https://wiki.rptools.info/api.php?action=feedcontributions&user=Melek&feedformat=atomRPTools Wiki - User contributions [en]2024-03-29T01:19:50ZUser contributionsMediaWiki 1.40.1https://wiki.rptools.info/index.php?title=lib:Elevation_Manual&diff=16564lib:Elevation Manual2023-03-24T04:40:59Z<p>Melek: </p>
<hr />
<div>[[File:lib elevation min.png|alt=Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.|thumb|Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.]]<br />
<h1>Welcome to Lib:Elevation!</h1><br />
<h2>Quick Links</h2><br />
<ul><br />
<li><strong>[https://github.com/melek/lib_elevation Download Lib:Elevation from GitHub]</strong></li><br />
<li>[https://forums.rptools.net/viewtopic.php?f=8&t=29234 View the RPTools Forum Post]</li><br />
<li>Ask questions and discuss in the [https://discord.gg/hbn2bfn MapTool Discord] in the #map-drawing-tools channel</li><br />
</ul><br />
<h2>Introduction</h2><br />
<p>This library adds an elevation feature to MapTool, allowing you to <strong>set Visual and Movement blocking layers based on elevation</strong> and <strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p><br />
<p>Here are some ideas on how to use this feature:</p><br />
<ul><br />
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations. </li><br />
<li>Remove vision entirely to simulate flying or scrying.</li><br />
<li>Change the background map at different elevations for a truly &#39;vertical&#39; feeling, such as flying islands or tall, fog-filled canyons.</li><br />
</ul><br />
<h2 id="terminology">Terminology</h2><br />
<p>There are a few concepts in Lib:Elevation that have special names that knowing up front can help you get to using the library quickly. </p><br />
<p>Some of the terms are similar to other MapTool terms like layer and token, so to (hopefully) reduce confusion, <br />
<strong>Elevations</strong> are sets</p><br />
<ul><br />
<li><strong>Token Elevation</strong>, or the elevation token property, is the vertical position of a token - how far up or down it is relative to other tokens. This is usually stored on the token as &#39;Elevaton&#39; (that is the MapTool default), and by itself is just a handy reference for players and GMs to know how high or low a token is on the map.</li><br />
<li><strong>Map Elevations</strong>, defined elevations, or simply elevations, are sets of data - a label, blocking layers, and linked tokens - which is shown at a particular elevation on the map. For example, a map of a maze might have &#39;Elevation 0&#39; labelled as &#39;Ground Level&#39; and block movement and sight the walls, while Elevation 20 might be labelled &#39;Flying&#39; and allow free vision and movement across the whole map. When I use the word &#39;Elevation&#39;, these special, defined elevations are usually what I mean, rather than the token property. Sometimes I may refer to elevations as &#39;layers&#39; or &#39;elevation layers&#39;, but I try to reserve that term specifically for the VBL/MBL associated with an elevation.</li><br />
<li><strong>Current Map Elevation</strong>, current elevation, or active elevation is the map elevation being displayed. Only one elevation is visible at a time for all players. Switching elevations means changing the current map elevation, which literally &#39;switches out&#39; which elevation you are playing on/editing. </li><br />
<li><strong>Faded tokens</strong> are tokens on a defined map elevation above or below the current elevation on the Token layer. These tokens will appear &#39;faded&#39; with lower opacity and placed behind tokens on the active elevation, and when they are defined will have the <code>isAbove</code> or <code>isBelow</code> state applied to it.</li><br />
<li><strong>Elevation Linked Tokens</strong> or <strong>Elevation Tokens</strong> refers to tokens which have their positions &#39;linked&#39; to a particular map elevation. These let you do thing slike switch the background map token, only show an NPC when they are at the same elevation as the player, hide door tokens so they don&#39;t appear at the wrong elevations. If the state is defined, these tokens will have a GM-only <code>isElevationToken</code> state applied to them to make them easier to spot for the GM.</li><br />
</ul><br />
<h2 id="campaign-setup">Campaign Setup</h2><br />
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p><br />
<ul><br />
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong> for quick access. The overlay UI has most of these options, but it is nice to have the buttons handy - especially in case the overlay has to be shut off for some reason. Exporting then importing these macro groups is a quick way to do this.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for &#39;*Elevation&#39;. This is a default MapTool property. If you&#39;d like to use a different property name for elevation in your campaign, you can change it in the <code>getElevationPropName</code> function.</li><br />
<li><strong>Add elevation token states in Campaign Properties</strong>, which will be used to show when a token is at an elevation above or below the current map elevation. Add two states: <code>isAbove</code> to mark tokens on a higher defined map elevation level, and <code>isBelow</code> for tokens below the current map elevation level. Here are recommended settings for these states:<ul><br />
<li>Choose the 2x2 Grid shapes at 50% opacity </li><br />
<li>Use &#39;Yield&#39; (down arrow) for <code>isBelow</code></li><br />
<li>User &#39;Triangle&#39; (up arrow) for <code>isAbove</code></li><br />
<li>Tokens will also appear faded when not on the current elevation.</li><br />
</ul><br />
</li><br />
<li><strong>Add a GM-only state to help manage Elevation Linked Tokens</strong> such as doors, background maps, etc.. Add one state: <code>isElevationToken</code> with the following state properties:<ul><br />
<li>Choose the &#39;Shaded&#39; type state set to a bright color and 25% opacity.</li><br />
<li>Check the &#39;GM Only&#39; option.</li><br />
<li>Check the &#39;Mouseover&#39; option.</li><br />
<li>You will learn more about why this state is helpful and what these linked &#39;Elevation Tokens&#39; are for.</li><br />
</ul><br />
</li><br />
</ul><br />
<h2 id="usage">Usage</h2><br />
<p>Lib:Elevation works by saving each elevation as a set of blocking layers (VBL and MBL) for the map, along with a list of any linked tokens which will be hidden when a different elevation is loaded. Changing between elevations swaps out which blocking layers are active and which elevation tokens are visible.</p><br />
<p>By default, new maps have no defined elevations and won&#39;t show the elevation list overlay for the GM. These maps are considered to be at elevation zero. You can add an elevation with the <code>Add Elev</code> button.</p><br />
<p>Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations. <strong>Changing elevations affects all connected players</strong>, unlike maps which the GM can freely preview privately without impacting which map a given player is on. If you want to check elevations on a map, it is recommended to keep the map hidden from players until you are ready for them to play on it.</p><br />
<p>When you switch between elevations, your changes to VBL/MBL and any elevation linked tokens will be saved. Then, VBL/MBL will be cleared, elevation tokens will be hidden, and the elevation you are switching to will be loaded onto the map.</p><br />
<p>Switching elevations is done manually, or when Initiative is active, when a token takes initiative. You can also use the <code>T↑↓</code> button to match the current elevation to the selected token&#39;s elevation property.</p><br />
<h3 id="elevation-management-buttons">Elevation Management Buttons</h3><br />
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown: </p><br />
<ul><br />
<li><code>Add Elev</code> will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like a background map token.</li><br />
<li><code>↑↑↑</code>, <code>↓↓↓</code>, and <code>↑↓</code> switches the map elevation up, down, or to a map elevation you choose.</li><br />
<li><code>T↑↓</code> button switches the map elevation to match the selected token&#39;s elevation property, rounded down to the nearest defined elevation. If a token&#39;s elevation is below the lowest defined elevation, it will default to the lowest available defined map elevation.</li><br />
<li><code>Link Tokens</code> links the selected token to an elevation you select. You can use <code>Unlink Tokns</code> to undo this, or <code>Select Tokens</code> to select all the current map elevation&#39;s linked tokens. These options are mostly for setting maps up, but you might unlink/link a token during play if moving NPCs between levels in a house, for instance.</li><br />
</ul><br />
<h3 id="token-management-buttons">Token Management Buttons</h3><br />
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect. </p><br />
<p>Please note that using these buttons usually also switches to the new elevation. </p><br />
<h2 id="limitations">Limitations</h2><br />
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p><br />
<ul><br />
<li>Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.</li><br />
<li>While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.</li><br />
</ul><br />
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p><br />
<h2 id="developer-notes">Developer notes</h2><br />
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to &#39;fill&#39; the vertical space until the next elevation.</p><br />
<p>Here are outlines the data structures and basic mechanism behind the library. </p><br />
<h3 id="library-properties">Library Properties</h3><br />
<p>The library itself contains no properties by default. There is a library options system which lets you set library-wide options, but that feature is not currently in use. Future versions may use these options as a fallback for undefined map-level options.</p><br />
<p><em>Note that versions 1.0a4 and lower stored all elevation data on the library token, using map IDs as keys. This was not import/export friendly and was replaced with library reference objects stored on automatically created map elevation data tokens.</em></p><br />
<h3 id="map-data-token-properties">Map Data Token properties</h3><br />
<p>On nearly any elevation operation, a &#39;Map Elevation Data&#39; token will be automatically created and populated with library reference data. All elevation related data on the map is stored on this token. <strong>If you delete the Map Elevation Data token, you will lose all your elevation data for the map.</strong></p><br />
<p>Using a token in this manner allows maps to be exported and imported to other campaigns using a sufficient version of Lib:Elevation.</p><br />
<table><br />
<br />
<tr><br />
<th>Property</th><br />
<th>Type</th><br />
<th>Purpose </th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>libRefData.elevation.version</td><br />
<td>String</td><br />
<td>The version of Lib:Elevation which created the data token.</td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.options</td><br />
<td>JSON Object</td><br />
<td>Option names are paired with their values. If they don&#39;t exist, they are presumed to be 0. </td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.current</td><br />
<td>String (Integer)</td><br />
<td>The current elevation. This value is set when saving an elevation or loading an elevation, which happens whenever the elevation is switched with a UI macro. Essentially, this is almost always the &#39;display&#39; elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.layers</td><br />
<td>JSON Object</td><br />
<td>Integer IDs representing an elevation are keys for JSON objects containing elevation data. This data structure is described below.</td><br />
</tr><br />
<br />
</table><br />
<h3 id="data-structures">Data Structures</h3><br />
<p>Note that Lib:Elevation uses Map Data Tokens stored on each map; this means that the library is loosely coupled with a campaign, and maps can be freely exported. Token IDs should stay constant on map import, so token names and exports/imports shouldn&#39;t compromise elevation data.</p><br />
<h4 id="-librefdata-elevation-layers-"><code>libRefData.elevation.layers</code></h4><br />
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called &#39;Map Elevation Objects&#39;. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p><br />
<table><br />
<br />
<tr><br />
<th>Key</th><br />
<th>Type</th><br />
<th>Purpose </th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>label</td><br />
<td>String</td><br />
<td>A display name for the elevation. Defined elevations don&#39;t require names.</td><br />
</tr><br />
<tr><br />
<td>vbl</td><br />
<td>JSON Array</td><br />
<td>VBL is a shape object array as returned by <code>getVBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>mbl</td><br />
<td>JSON Array</td><br />
<td>MBL is a shape object array as returned by <code>getMBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>tokens</td><br />
<td>JSON Object</td><br />
<td>Token ID keys containing <b>token appearance</b> objects. Token appearance is described below.</td><br />
</tr><br />
<br />
</table><br />
<h4 id="token-appearance-objects">Token appearance objects</h4><br />
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in <code>getTokenAppearance()</code> and <code>setTokenAppearance()</code>. When Strict Map settings, mainly Strict Token Appearance, dictate which are used. The token appearance JSON Object includes the following keys and the associated token data:</p><br />
<table><br />
<br />
<tr><br />
<th>Key</th><br />
<th>Data function</th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>ID</td><br />
<td>Same as Field ID</td><br />
</tr><br />
<tr><br />
<td>Layer</td><br />
<td><code>getLayer(ID)</code></td><br />
</tr><br />
<tr><br />
<td>X</td><br />
<td><code>getTokenX(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Y</td><br />
<td><code>getTokenY(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Z</td><br />
<td><code>getTokenDrawOrder(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Height</td><br />
<td><code>getTokenHeight(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Width</td><br />
<td><code>getTokenWidth(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Size</td><br />
<td><code>getSize(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Facing</td><br />
<td><code>getTokenFacing(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Opacity</td><br />
<td><code>getTokenOpacity(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Visible</td><br />
<td><code>getVisible(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Shape</td><br />
<td><code>getTokenShape(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Layout</td><br />
<td><code>getTokenLayoutProps(&#39;;&#39;, ID)</code></td><br />
</tr><br />
<br />
</table><br />
<h4 id="token-fade-data-lists">Token Fade Data Lists</h4><br />
<p>Tokens on other elevations are faded with the <code>elevation.setTokenElevationStates</code> function have their opacity reduced and are assigned either the <code>isAbove</code> or <code>isBelow</code> state. Additionally, according to the <code>fadedTokenSight</code> option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p><br />
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format: <code>opacity, sight_type, has_sight</code></p><br />
<p>This is stored by default on the token in the <code>libRefData.elevation.fadeData</code> property. This property can be changed in the <code>elevation.getTokenFadePropName</code> method.</p><br />
<h4 id="options">Options</h4><br />
<p>There is a simple options API using <code>elevation.getMapOption</code> and <code>elevation.setMapOption</code>. This is a simple JSON object on the map&#39;s data token with keys (option names) and the option value, where a missing key is treated as &#39;0&#39;. Here is a sample of the available options, and the full list can be found in a comment on the <code>optionsDialog</code> library macro:</p><br />
<table><br />
<br />
<tr><br />
<th>Option</th><br />
<th>Setting</th><br />
<th>Description</th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>fadedSightType</td><br />
<td>0</td><br />
<td>Faded tokens (tokens on other elevations) will not have their sight settings changed in any way.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>1</td><br />
<td>&#39;Has Sight&#39; will be unchecked for all faded tokens.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>STRING</td><br />
<td>A string matching a defined Sight Type will be applied to faded tokens.</td><br />
</tr><br />
<tr><br />
<td>heightFactor</td><br />
<td>N</td><br />
<td>This is the height multiplier the new elevation dialog uses to recommend a new elevation value. That dialog sets a fallback value of &#39;2&#39; (so for a 5 ft square, it will recommend new layers at 10 ft), but this value might also be used to determine how a future token height implementation might determine when to display a token below the current layer. </td><br />
</tr><br />
<tr><br />
<td>useFogHack</td><br />
<td>0</td><br />
<td>Fog of war is not affected by elevation changes.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>1</td><br />
<td>Fog of war is totally restored on elevation changes, followed by immediately exposing all player token sight ranges. Use with &#39;fadedSight = 1&#39; to give a more horror-like feel to multi-story buildings. If draw/eraseFoW functions are added, this may be retired.</td><br />
</tr><br />
<br />
</table><br />
<h4 id="sample-librefdata-elevation-layers-object">Sample <code>libRefData.elevation.layers</code> object</h4><br />
<p>A trivial example object may look like this:</p><br />
<br />
<pre>{<br />
"A14EF2FE619B42AF828CBBAC0192131A": {<br />
"0": {<br />
"label": "Ground level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
},<br />
"60": {<br />
"label": "Cliff top",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
}<br />
},<br />
"28CBBAC0192131AA14EF2FE619B42AF8": {<br />
"0": {<br />
"label": "Sea Level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
},<br />
"10": {<br />
"label": "Flying",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
}<br />
}<br />
}<br />
</pre><br />
<br />
[[Category:Draft]][[Category:How To]]</div>Melekhttps://wiki.rptools.info/index.php?title=lib:Elevation_Manual&diff=16547lib:Elevation Manual2023-03-22T16:58:42Z<p>Melek: Update image</p>
<hr />
<div>[[File:lib elevation min.png|alt=Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.|thumb|Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.]]<br />
<h1>Welcome to Lib:Elevation!</h1><br />
<h2>Quick Links</h2><br />
<ul><br />
<li><strong>[https://github.com/melek/lib_elevation Download Lib:Elevation from GitHub]</strong></li><br />
<li>[https://forums.rptools.net/viewtopic.php?f=8&t=29234 View the RPTools Forum Post]</li><br />
<li>Ask questions and discuss in the [https://discord.gg/hbn2bfn MapTool Discord] in the #map-drawing-tools channel</li><br />
</ul><br />
<h2>Introduction</h2><br />
<p>This library adds an elevation feature to MapTool, allowing you to <strong>set Visual and Movement blocking layers based on elevation</strong> and <strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p><br />
<p>Here are some ideas on how to use this feature:</p><br />
<ul><br />
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations. </li><br />
<li>Remove vision entirely to simulate flying or scrying.</li><br />
<li>Change the background map at different elevations for a truly &#39;vertical&#39; feeling, such as flying islands or tall, fog-filled canyons.</li><br />
</ul><br />
<h2 id="terminology">Terminology</h2><br />
<p>There are a few concepts in Lib:Elevation that have special names that knowing up front can help you get to using the library quickly. </p><br />
<p>Some of the terms are similar to other MapTool terms like layer and token, so to (hopefully) reduce confusion, <br />
<strong>Elevations</strong> are sets</p><br />
<ul><br />
<li><strong>Token Elevation</strong>, or the elevation token property, is the vertical position of a token - how far up or down it is relative to other tokens. This is usually stored on the token as &#39;Elevaton&#39; (that is the MapTool default), and by itself is just a handy reference for players and GMs to know how high or low a token is on the map.</li><br />
<li><strong>Map Elevations</strong>, defined elevations, or simply elevations, are sets of data - a label, blocking layers, and linked tokens - which is shown at a particular elevation on the map. For example, a map of a maze might have &#39;Elevation 0&#39; labelled as &#39;Ground Level&#39; and block movement and sight the walls, while Elevation 20 might be labelled &#39;Flying&#39; and allow free vision and movement across the whole map. When I use the word &#39;Elevation&#39;, these special, defined elevations are usually what I mean, rather than the token property. Sometimes I may refer to elevations as &#39;layers&#39; or &#39;elevation layers&#39;, but I try to reserve that term specifically for the VBL/MBL associated with an elevation.</li><br />
<li><strong>Current Map Elevation</strong>, current elevation, or active elevation is the map elevation being displayed. Only one elevation is visible at a time for all players. Switching elevations means changing the current map elevation, which literally &#39;switches out&#39; which elevation you are playing on/editing. </li><br />
<li><strong>Faded tokens</strong> are tokens on a defined map elevation above or below the current elevation on the Token layer. These tokens will appear &#39;faded&#39; with lower opacity and placed behind tokens on the active elevation, and when they are defined will have the <code>isAbove</code> or <code>isBelow</code> state applied to it.</li><br />
<li><strong>Elevation Linked Tokens</strong> or <strong>Elevation Tokens</strong> refers to tokens which have their positions &#39;linked&#39; to a particular map elevation. These let you do thing slike switch the background map token, only show an NPC when they are at the same elevation as the player, hide door tokens so they don&#39;t appear at the wrong elevations. If the state is defined, these tokens will have a GM-only <code>isElevationToken</code> state applied to them to make them easier to spot for the GM.</li><br />
</ul><br />
<h2 id="campaign-setup">Campaign Setup</h2><br />
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p><br />
<ul><br />
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong> for quick access. The overlay UI has most of these options, but it is nice to have the buttons handy - especially in case the overlay has to be shut off for some reason. Exporting then importing these macro groups is a quick way to do this.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for &#39;*Elevation&#39;. This is a default MapTool property. If you&#39;d like to use a different property name for elevation in your campaign, you can change it in the <code>getElevationPropName</code> function.</li><br />
<li><strong>Add elevation token states in Campaign Properties</strong>, which will be used to show when a token is at an elevation above or below the current map elevation. Add two states: <code>isAbove</code> to mark tokens on a higher defined map elevation level, and <code>isBelow</code> for tokens below the current map elevation level. Here are recommended settings for these states:<ul><br />
<li>Choose the 2x2 Grid shapes at 50% opacity </li><br />
<li>Use &#39;Yield&#39; (down arrow) for <code>isBelow</code></li><br />
<li>User &#39;Triangle&#39; (up arrow) for <code>isAbove</code></li><br />
<li>Tokens will also appear faded when not on the current elevation.</li><br />
</ul><br />
</li><br />
<li><strong>Add a GM-only state to help manage Elevation Linked Tokens</strong> such as doors, background maps, etc.. Add one state: <code>isElevationToken</code> with the following state properties:<ul><br />
<li>Choose the &#39;Shaded&#39; type state set to a bright color and 25% opacity.</li><br />
<li>Check the &#39;GM Only&#39; option.</li><br />
<li>Check the &#39;Mouseover&#39; option.</li><br />
<li>You will learn more about why this state is helpful and what these linked &#39;Elevation Tokens&#39; are for.</li><br />
</ul><br />
</li><br />
</ul><br />
<h2 id="usage">Usage</h2><br />
<p>Lib:Elevation works by saving each elevation as a set of blocking layers (VBL and MBL) for the map, along with a list of any linked tokens which will be hidden when a different elevation is loaded. Changing between elevations swaps out which blocking layers are active and which elevation tokens are visible.</p><br />
<p>By default, new maps have no defined elevations and won&#39;t show the elevation list overlay for the GM. These maps are considered to be at elevation zero. You can add an elevation with the <code>Add Elev</code> button.</p><br />
<p>Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations. <strong>Changing elevations affects all connected players</strong>, unlike maps which the GM can freely preview privately without impacting which map a given player is on. If you want to check elevations on a map, it is recommended to keep the map hidden from players until you are ready for them to play on it.</p><br />
<p>When you switch between elevations, your changes to VBL/MBL and any elevation linked tokens will be saved. Then, VBL/MBL will be cleared, elevation tokens will be hidden, and the elevation you are switching to will be loaded onto the map.</p><br />
<p>Switching elevations is done manually, or when Initiative is active, when a token takes initiative. You can also use the <code>T↑↓</code> button to match the current elevation to the selected token&#39;s elevation property.</p><br />
<h3 id="elevation-management-buttons">Elevation Management Buttons</h3><br />
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown: </p><br />
<ul><br />
<li><code>Add Elev</code> will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like a background map token.</li><br />
<li><code>↑↑↑</code>, <code>↓↓↓</code>, and <code>↑↓</code> switches the map elevation up, down, or to a map elevation you choose.</li><br />
<li><code>T↑↓</code> button switches the map elevation to match the selected token&#39;s elevation property, rounded down to the nearest defined elevation. If a token&#39;s elevation is below the lowest defined elevation, it will default to the lowest available defined map elevation.</li><br />
<li><code>Link Tokens</code> links the selected token to an elevation you select. You can use <code>Unlink Tokns</code> to undo this, or <code>Select Tokens</code> to select all the current map elevation&#39;s linked tokens. These options are mostly for setting maps up, but you might unlink/link a token during play if moving NPCs between levels in a house, for instance.</li><br />
</ul><br />
<h3 id="token-management-buttons">Token Management Buttons</h3><br />
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect. </p><br />
<p>Please note that using these buttons usually also switches to the new elevation. </p><br />
<h2 id="limitations">Limitations</h2><br />
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p><br />
<ul><br />
<li>Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.</li><br />
<li>While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.</li><br />
</ul><br />
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p><br />
<h2 id="developer-notes">Developer notes</h2><br />
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to &#39;fill&#39; the vertical space until the next elevation.</p><br />
<p>Here are outlines the data structures and basic mechanism behind the library. </p><br />
<h3 id="library-properties">Library Properties</h3><br />
<p>The library itself contains no properties by default. There is a library options system which lets you set library-wide options, but that feature is not currently in use. Future versions may use these options as a fallback for undefined map-level options.</p><br />
<p><em>Note that versions 1.0a4 and lower stored all elevation data on the library token, using map IDs as keys. This was not import/export friendly and was replaced with library reference objects stored on automatically created map elevation data tokens.</em></p><br />
<h3 id="map-data-token-properties">Map Data Token properties</h3><br />
<p>On nearly any elevation operation, a &#39;Map Elevation Data&#39; token will be automatically created and populated with library reference data. All elevation related data on the map is stored on this token. <strong>If you delete the Map Elevation Data token, you will lose all your elevation data for the map.</strong></p><br />
<p>Using a token in this manner allows maps to be exported and imported to other campaigns using a sufficient version of Lib:Elevation.</p><br />
<table><br />
<br />
<tr><br />
<th>Property</th><br />
<th>Type</th><br />
<th>Purpose </th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>libRefData.elevation.version</td><br />
<td>String</td><br />
<td>The version of Lib:Elevation which created the data token.</td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.options</td><br />
<td>JSON Object</td><br />
<td>Option names are paired with their values. If they don&#39;t exist, they are presumed to be 0. </td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.current</td><br />
<td>String (Integer)</td><br />
<td>The current elevation. This value is set when saving an elevation or loading an elevation, which happens whenever the elevation is switched with a UI macro. Essentially, this is almost always the &#39;display&#39; elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.layers</td><br />
<td>JSON Object</td><br />
<td>Integer IDs representing an elevation are keys for JSON objects containing elevation data. This data structure is described below.</td><br />
</tr><br />
<br />
</table><br />
<h3 id="data-structures">Data Structures</h3><br />
<p>Note that Lib:Elevation uses Map Data Tokens stored on each map; this means that the library is loosely coupled with a campaign, and maps can be freely exported. Token IDs should stay constant on map import, so token names and exports/imports shouldn&#39;t compromise elevation data.</p><br />
<h4 id="-librefdata-elevation-layers-"><code>libRefData.elevation.layers</code></h4><br />
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called &#39;Map Elevation Objects&#39;. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p><br />
<table><br />
<br />
<tr><br />
<th>Key</th><br />
<th>Type</th><br />
<th>Purpose </th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>label</td><br />
<td>String</td><br />
<td>A display name for the elevation. Defined elevations don&#39;t require names.</td><br />
</tr><br />
<tr><br />
<td>vbl</td><br />
<td>JSON Array</td><br />
<td>VBL is a shape object array as returned by <code>getVBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>mbl</td><br />
<td>JSON Array</td><br />
<td>MBL is a shape object array as returned by <code>getMBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>tokens</td><br />
<td>JSON Object</td><br />
<td>Token ID keys containing <b>token appearance</b> objects. Token appearance is described below.</td><br />
</tr><br />
<br />
</table><br />
<h4 id="token-appearance-objects">Token appearance objects</h4><br />
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in <code>getTokenAppearance()</code> and <code>setTokenAppearance()</code>. The token appearance JSON Object includes the following keys and the associated token data:</p><br />
<table><br />
<br />
<tr><br />
<th>Key</th><br />
<th>Data function</th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>ID</td><br />
<td>Same as Field ID</td><br />
</tr><br />
<tr><br />
<td>Layer</td><br />
<td><code>getLayer(ID)</code></td><br />
</tr><br />
<tr><br />
<td>X</td><br />
<td><code>getTokenX(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Y</td><br />
<td><code>getTokenY(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Z</td><br />
<td><code>getTokenDrawOrder(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Height</td><br />
<td><code>getTokenHeight(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Width</td><br />
<td><code>getTokenWidth(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Size</td><br />
<td><code>getSize(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Facing</td><br />
<td><code>getTokenFacing(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Opacity</td><br />
<td><code>getTokenOpacity(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Visible</td><br />
<td><code>getVisible(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Shape</td><br />
<td><code>getTokenShape(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Layout</td><br />
<td><code>getTokenLayoutProps(&#39;;&#39;, ID)</code></td><br />
</tr><br />
<br />
</table><br />
<h4 id="token-fade-data-lists">Token Fade Data Lists</h4><br />
<p>Tokens on other elevations are faded with the <code>elevation.setTokenElevationStates</code> function have their opacity reduced and are assigned either the <code>isAbove</code> or <code>isBelow</code> state. Additionally, according to the <code>fadedTokenSight</code> option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p><br />
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format: <code>opacity, sight_type, has_sight</code></p><br />
<p>This is stored by default on the token in the <code>libRefData.elevation.fadeData</code> property. This property can be changed in the <code>elevation.getTokenFadePropName</code> method.</p><br />
<h4 id="options">Options</h4><br />
<p>There is a simple options API using <code>elevation.getMapOption</code> and <code>elevation.setMapOption</code>. This is a simple JSON object on the map&#39;s data token with keys (option names) and the option value, where a missing key is treated as &#39;0&#39;. Here are the available options:</p><br />
<table><br />
<br />
<tr><br />
<th>Option</th><br />
<th>Setting</th><br />
<th>Description</th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>fadedSightType</td><br />
<td>0</td><br />
<td>Faded tokens (tokens on other elevations) will not have their sight settings changed in any way.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>1</td><br />
<td>&#39;Has Sight&#39; will be unchecked for all faded tokens.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>STRING</td><br />
<td>A string matching a defined Sight Type will be applied to faded tokens.</td><br />
</tr><br />
<tr><br />
<td>heightFactor</td><br />
<td>N</td><br />
<td>This is the height multiplier the new elevation dialog uses to recommend a new elevation value. That dialog sets a fallback value of &#39;2&#39; (so for a 5 ft square, it will recommend new layers at 10 ft), but this value might also be used to determine how a future token height implementation might determine when to display a token below the current layer. </td><br />
</tr><br />
<tr><br />
<td>useFogHack</td><br />
<td>0</td><br />
<td>Fog of war is not affected by elevation changes.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>1</td><br />
<td>Fog of war is totally restored on elevation changes, followed by immediately exposing all player token sight ranges. Use with &#39;fadedSight = 1&#39; to give a more horror-like feel to multi-story buildings. If draw/eraseFoW functions are added, this may be retired.</td><br />
</tr><br />
<br />
</table><br />
<h4 id="sample-librefdata-elevation-layers-object">Sample <code>libRefData.elevation.layers</code> object</h4><br />
<p>A trivial example object may look like this:</p><br />
<br />
<pre>{<br />
"A14EF2FE619B42AF828CBBAC0192131A": {<br />
"0": {<br />
"label": "Ground level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
},<br />
"60": {<br />
"label": "Cliff top",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
}<br />
},<br />
"28CBBAC0192131AA14EF2FE619B42AF8": {<br />
"0": {<br />
"label": "Sea Level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
},<br />
"10": {<br />
"label": "Flying",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
}<br />
}<br />
}<br />
</pre><br />
<br />
[[Category:Draft]][[Category:How To]]</div>Melekhttps://wiki.rptools.info/index.php?title=File:lib_elevation_min.png&diff=16546File:lib elevation min.png2023-03-22T16:56:19Z<p>Melek: User interface for Lib:Elevation, featuring an embedded visual and theme-sensitive colors.</p>
<hr />
<div>== Summary ==<br />
User interface for Lib:Elevation, featuring an embedded visual and theme-sensitive colors.</div>Melekhttps://wiki.rptools.info/index.php?title=listSort&diff=16537listSort2023-03-21T05:22:07Z<p>Melek: Fix formatting on return value in example.</p>
<hr />
<div>{{stub}}<br />
{{MacroFunction<br />
|name=listSort<br />
|description=<br />
Returns a sorted list.<br />
<br />
|usage=<br />
<syntaxhighlight lang="mtmacro" line><br />
[listSort(list, sortType)]<br />
[listSort(list, sortType, delim)]<br />
</syntaxhighlight><br />
<br />
'''Parameters'''<br />
{{param|list|The list that is sorted.}}<br />
{{param|sortType|The direction that this list is sorted. "A+" - alpha ascending, "A-" - alpha descending, "N-" - padded ending numbers descending alpha}}<br />
{{param|delim|The delimiter used in the separate the list, defaults to {{code|","}}.}}<br />
<br />
The sortType determines the type of sort to use.<br />
If sortType is "A", normal alphabetic sorting is used, and "Monster11" comes before "Monster3". (Default behavior)<br />
If sortType is "N", the first number in each entry is effectively padded to 4 digits, so that "Monster3" comes before "Monster11".<br />
The sortType can have a second character of "+" or "-" to specify an ascending or descending sort.<br />
<br />
<strong>Note about numeric lists</strong>: String list values are strings, not numbers. This function can sort lists of non-negative numbers correctly with or without prefixes such as "Monster1", "Monster2", etc. Negative numbers cannot be ordered in reverse order since the hyphen is viewed as a string prefix, not as a negation symbol. In other words, the string list "-5, 1, -3, 0" will be sorted to "-3, -5, 0, 1". <br />
<br />
If you want to order a list of numbers, use [[json.sort]] on a JSON Array. For more information about this limitation, check [https://github.com/RPTools/maptool/issues/3878 the related issue on GitHub].<br />
<br />
|example=<br />
<syntaxhighlight lang="mtmacro" line><br />
[h: UnsortedList = "Monster11,Monster3,Monster12,Monster66,Monster87,Monster71"]<br />
[h: SortedList = listSort(UnsortedList,'N')]<br />
<br />
Unsorted list: [r: UnsortedList]<br><br />
Sorted list: [r: SortedList]<br />
</syntaxhighlight><br />
<br />
Returns:<br />
<br />
<syntaxhighlight lang="mtmacro" line><br />
Unsorted list: Monster11,Monster3,Monster12,Monster66,Monster87,Monster71<br />
Sorted list: Monster3, Monster11, Monster12, Monster66, Monster71, Monster87<br />
</syntaxhighlight><br />
<br />
}}<br />
[[Category:String List Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=listSort&diff=16536listSort2023-03-21T05:18:36Z<p>Melek: Added a note about numeric lists per https://github.com/RPTools/maptool/issues/3878</p>
<hr />
<div>{{stub}}<br />
{{MacroFunction<br />
|name=listSort<br />
|description=<br />
Returns a sorted list.<br />
<br />
|usage=<br />
<syntaxhighlight lang="mtmacro" line><br />
[listSort(list, sortType)]<br />
[listSort(list, sortType, delim)]<br />
</syntaxhighlight><br />
<br />
'''Parameters'''<br />
{{param|list|The list that is sorted.}}<br />
{{param|sortType|The direction that this list is sorted. "A+" - alpha ascending, "A-" - alpha descending, "N-" - padded ending numbers descending alpha}}<br />
{{param|delim|The delimiter used in the separate the list, defaults to {{code|","}}.}}<br />
<br />
The sortType determines the type of sort to use.<br />
If sortType is "A", normal alphabetic sorting is used, and "Monster11" comes before "Monster3". (Default behavior)<br />
If sortType is "N", the first number in each entry is effectively padded to 4 digits, so that "Monster3" comes before "Monster11".<br />
The sortType can have a second character of "+" or "-" to specify an ascending or descending sort.<br />
<br />
<strong>Note about numeric lists</strong>: String list values are strings, not numbers. This function can sort lists of non-negative numbers correctly with or without prefixes such as "Monster1", "Monster2", etc. Negative numbers cannot be ordered in reverse order since the hyphen is viewed as a string prefix, not as a negation symbol. In other words, the string list "-5, 1, -3, 0" will be sorted to "-3, -5, 0, 1". <br />
<br />
If you want to order a list of numbers, use [[json.sort]] on a JSON Array. For more information about this limitation, check [https://github.com/RPTools/maptool/issues/3878 the related issue on GitHub].<br />
<br />
|example=<br />
<syntaxhighlight lang="mtmacro" line><br />
[h: UnsortedList = "Monster11,Monster3,Monster12,Monster66,Monster87,Monster71"]<br />
[h: SortedList = listSort(UnsortedList,'N')]<br />
<br />
Unsorted list: [r: UnsortedList]<br><br />
Sorted list: [r: SortedList]<br />
</syntaxhighlight><br />
<br />
Returns:<br />
Unsorted list: Monster11,Monster3,Monster12,Monster66,Monster87,Monster71<br />
Sorted list: Monster3, Monster11, Monster12, Monster66, Monster71, Monster87<br />
<br />
}}<br />
[[Category:String List Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=Introduction_to_Macro_Writing_With_Javascript&diff=11847Introduction to Macro Writing With Javascript2022-06-29T23:52:10Z<p>Melek: /* Introduction */</p>
<hr />
<div>{{Languages|Introduction to Macro Writing}}<br />
[[Category:MapTool]][[Category:Tutorial]]{{Beginner}}<br />
== Introduction ==<br />
Since MapTool 1.10 there is a new JavaScript environment that allows the use of JavaScript to write macros. This is a tutorial for anybody that hasn't used Javascript in MapTool before. This tutorial assumes no prior knowledge of Javascript, programming or macro writing in general. For reasons why you would want to write a macro see the start of [[Introduction to Macro Writing]]<br />
<br />
== MapTool Environments ==<br />
The first thing that any person wanting to write JavaScript for MapTool should know is that there are 2 different Javascript environments in MapTool. The first is for macros, related to the {{func|js.eval}} family of functions, the other Javascript environment lives inside the frames and overlays as part of HTML. To avoid confusion the first JavaScript environment is referred to as "GraalVM JavaScript" and the second "Frame JavaScript". This tutorial focuses on GraalVM Javascript so assume any reference to only Javascript is a reference to GraalVM Javascript.<br />
<br />
== Setting Up Macro Environment ==<br />
You can just write Javascript inside a string to be evaluated by {{func|js.eval}}. If you want to do anything slightly more complex than a single line this approach quickly becomes unwieldy, so setting up a area to develop complex macros is a good idea. For this tutorial, do this by following these steps;<br />
# create a [[Library Token]]<br />
# set allows URI acess to true<br />
# create a macro with Javascript<br />
# execute it.<br />
<br />
If you are unsure of how to do any of these steps here is a verbose description of the procedure;<br />
# pick a token and change its name to start with lib: like lib:javascript-tutorial<br />
# still inside the edit token window go on the "Lib:Token properties" tab and click the checkbox so that allows URI access has a checkmark besides it<br />
# to create a macro on the lib token first make sure you have a token related panel <br />
## to show a token panel on the top of the window on the menu bar click on window and then select either impersonate or selected (if you selected the impersonate panel make sure to impersonate the library token)<br />
## to add a new macro, right click on the panel and select "Add New Macro" from the context menu<br />
## to edit the macro, right click it and select "Edit.." from the context menu<br />
## in the second tab you can change its name from (new) <br />
# To execute the text inside a macro on a lib token create another macro and inside it call the {{func|js.evalURI}} function<br />
## to call the function write <syntaxhighlight lang="mtmacro" line>[r:js.evalURI("javascript-tutorial",lib URI)]</syntaxhighlight><br />
### a lib URI to a macro is a link of the form lib://libraryTokenName/macro/macroName so if you lib token is lib:javascript-tutorial and your macro is js then to refer to it the link is lib://javascript-tutorial/macro/js<br />
### the first argument is the namespace try to use a unique one or it may cause problems with other macros written in javascript<br />
<br />
As an alternative to using the built-in macro editor you can use a Javascript IDE or a text editor, they can be an immense help. If you are editing outside MapTool and then copy pasting your code, consider [[Creating A MapTool Addon]].<br />
<br />
== First Javascript Program ==<br />
This is the part where you start to learn Javascript, if you already know Javascript you can read the following articles to get started [[js:MapTool]] , [[js:MapTool.chat]] ,[[js:MapTool.tokens]] , [[js:MapTool.clientInfo]] and last but most important [[js:MTScript]].<br />
Javascript is a multi-paradigm programming language the exact meaning of this isn't important what is important is that we can treat it as a imperative programming language. An imperative program is just a sequence of commands.<br />
Insert the following in your macro holding javascript.<br />
<syntaxhighlight lang="javascript"><br />
"use strict";<br />
try {<br />
let message = "hello world";<br />
MapTool.chat.broadcast(message);<br />
} catch(e) {<br />
MapTool.chat.broadcast(""+e+"\n"+e.stack);<br />
}<br />
</syntaxhighlight><br />
if you inserted the text correctly, when executed hello world appeared in the chat, if you got something else check the text carefully, code is very fragile and a single misplaced { or } could break it.<br><br />
this snippet contains a lot of things which need to be explained, most of them will be explained now but the try and the catch will be explained next section<br><br />
<br />
<br />
=== Javascript Statements ===<br />
Firstly look at the end of each line besides the second and the and fifth one, notice that there is a semicolon. The semicolon denotes the end of a statement. In this instance is optional as each statement is in a separate line but it is good practise to include it. If you don't an automated program inserts it automatically and it may not get it right, which you certainly don't want. a statement is basically a command, if you rolled on MapTool before you probably used a command, this is the same thing, a statement does something.<br />
<br />
<br />
=== Javascript Strict Mode ===<br />
on the first line there is a statement which causes Javascript to enter strict mode, on strict mode Javascript turns things which are probably mistakes into errors which if you are inside a try catch block will give what is wrong and where, the full list of what happens can be found [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode here] but just to talk about a example say you mistyped something Javascript normally won't complain and continue using a value called undefined, creating subtle bugs, compare that to getting "on line x column y you asked for a value which doesn't exist."<br />
<br />
<br />
=== Javascript variables ===<br />
On the third line we have a statement containing <code>let message = "hello world";</code> what this does is create a variable. A variable stores a changeable value so instead of using "hello world" we can use message, you can declare a variable with <i>var, let or const</i>. A variable name must start with a letter or underline and may contain numbers, letters and underline, a variable name can't be any the Javascript keywords like let, const, var and more. <br />
In the last paragraph it was mentioned that a variable can hold a value, this value can be one of the basic types in Javascript they are <br />
* <b>string:</b> a string is a fragment of text enclosed in either quotes or double quotes, a string enclosed with backticks is called a [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals template literal]] which is special.<br />
* <b>number:</b> a number is a number they can be either integer like -1, 3 or it can be fractional number like 0.2, 0.1 3.5 they are called floating point numbers do note that because of their representation in the computer using floats does have some imprecision 0.1 + 0.2 isn't equal to 0.3 but rather 0.30000000000000004. this also happens for really big integers as they are also floating point numbers<br />
* <b>objects:</b> a object is a group of properties with associated values, they are created with curly braces enclosing the properties and pairs of propertyName:propertyValue like this <code> {property1:value1,property2:2}</code>, only strings, a special type called Symbol and numbers can be properties but '''anything''' can be a value in an object,this includes other objects and functions. To access a object properties you use ["property"] or .property after the object, there is a lot more to know about objects but for now this is enough. <br />
* <b>arrays:</b> a array is a collection of values, the literal form of a array is braces with values like this <code>[value1,value2,etc]</code> there are special functions to working with arrays like objects there is a lot more to them.<br />
* <b>functions:</b> they will be talked about more later but note that a function can be assigned to a variable and later called by that name.<br />
<br />
<br />
=== Javascript Functions ===<br />
On the fourth line there is <code>MapTool.chat.broadcast(message);</code> which is a function call. A function is basically a group of statements which can optionally receive arguments. when you call a function you supply the arguments and it performs the statements it contains. In this case we are calling the broadcast function of the chat object which is contained in the MapTool object. This function calls java code to output a string to chat, nb: if you give as argument something other than a string like a number or a object you will get an error. To declare a function use <br />
<syntaxhighlight lang="javascript"><br />
function functionName (argument1,argument2,etc){<br />
insert your statements here;<br />
}<br />
</syntaxhighlight><br />
<br />
== Javascript Control Structures ==<br />
You may have noticed that with the tools we have currently it isn't possible to build anything complex. For instance: What if we want check if a roll is higher than the targets DC and if so roll an attack? What if we want to deal damage to all characters in the map? Even worse, what if we make an error like dividing by 0? Control structures solve this problem, see the following example of implementing a fireball spell for d&d<br />
<syntaxhighlight lang="javascript"><br />
"use strict";<br />
function roll(dice,sides){<br />
let string = MTScript.execMacro(`[r:roll(${dice},${sides})]`);<br />
return Number(string);<br />
}<br />
var checkNumber = (value => Number.isNaN(value)||value == undefined);<br />
<br />
function makeSave(token,spellLevel,spellDC){<br />
const dex = Number(token.getProperty("dexterity"));<br />
let message = token.getName()+":"<br />
let dexModifier = (dex-10)/2;<br />
if(checkNumber(dexModifier)){<br />
dexModifier = 0;<br />
}<br />
const result = dexModifier + roll(1,20);<br />
let previousLife = Number(token.getProperty("HP"));<br />
if(checkNumber(previousLife)){<br />
previousLife = 0;<br />
}<br />
let newLife;<br />
const damageRoll = (roll(8,6)+roll(spellLevel-4,6))<br />
if(result >=spellDC){<br />
message = message +"succeded on its dex save with "+result;<br />
newLife = Math.ceil(previousLife-damageRoll/2);<br />
}<br />
else{<br />
message = message + "failed on its dex save with "+result;<br />
newLife = previousLife -damageRoll;<br />
}<br />
token.setProperty("HP",""+newLife);<br />
MapTool.chat.broadcast(message + " and is now at "+newLife+"HP");<br />
return token;<br />
}<br />
<br />
function getInput(names){<br />
let commandStart = "[h:input(";<br />
let commandEnd = `[h:value = "[]"]`;<br />
const argNum = names.length -1;<br />
for(let i = 0; i<argNum;i++){<br />
commandStart = commandStart +`"${names[i]}||${names[i]}|TEXT|",`<br />
commandEnd = commandEnd + `\n[h:value = json.append(value,${names[i]})]` <br />
}<br />
commandStart = commandStart +`"${names[argNum]}||${names[argNum]}|TEXT|")]`;<br />
commandEnd = commandEnd + `\n[r:json.append(value,${names[argNum]})]`;<br />
return JSON.parse(MTScript.execMacro(commandStart+commandEnd));<br />
}<br />
<br />
try{<br />
const tokens = MapTool.tokens.getMapTokens();<br />
const [spellLevel,spellDC] = getInput(["spellLevel","spellDC"]);<br />
<br />
for(const token of tokens){<br />
makeSave(token,spellLevel,spellDC);<br />
}<br />
}<br />
catch(e){<br />
MapTool.chat.broadcast(""+e+"\n"+e.stack);<br />
}<br />
</syntaxhighlight><br />
=== Javascript try and catch ===<br />
Like the previous example this code uses a try catch block. In a try block if any part of the code throws a exception then the catch block is executed. The variable inside parenthesis near the catch keyword represents the error. In MapTool and most browsers Error objects contain a [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#instance_properties stack]] property that indicates from where it was thrown. When programming in Javascript try to always have at least a try catch block so you get useful errors. If you don't then you will get a generic there is something wrong in this code.<br />
<br />
<br />
=== Javascript If ===<br />
In the makeSave function we have various <b>if</b>s keywords, when the result inside the parenthesis of the if is truthy it executes the code otherwise it executes the else if present. A truthy result, is either true, a number other than 0, a non empty string or any object including a empty object. A falsy result is the empty string, 0, null and undefined. related to the if keyword there are comparison operators == checks for equality but converts types 0 == "0" evaluates to true. to truly check for equality use the === operator the opposite is the not equal operator != like the basic equality operator it converts types so 0 != "0" is false to check for inequality without conversion use !== there also are comparison operators for numbers like greater than >, greater or equal than >= and others. <br />
<br />
<br />
=== Javascript For ===<br />
On the getInput function there is a use of a <b>for</b> keyword, in the basic for block you define a variable, declare an exit condition, and finally declare a statement to be executed at the end of the loop, it will execute the code block inside the for loop until the end condition is reached. Besides that there is a <b>for of</b> and a <b>for in</b> block. The difference is that the for of loops over the elements of an iterable meaning array like objects, and the for in loops over enumerable properties meaning visible properties of a object. <br />
<br />
<br />
=== Complete Explanation Of Code Example === <br />
This code block:<br />
* defines some functions, then <br />
* in a try block gets all tokens on the map from [[js:MapTool.tokens |MapTool.token.getMapTokens]],<br />
* information of the cast fireball from the get input function<br />
* it then loops over all tokens with the information of the fireball spell.<br />
<br />
==== Roll and Check Number Function ====<br />
The roll function calls some MapTool Script to roll dice, via the [[js:MTScript |MTScript.execMacro]] function. The checkNumber function checks if the entered number is either undefined or the special number NaN, it uses the "or" || operator there also is the "and" && logical operator. The check number function is a example of a arrow function, an alternative syntax for defining functions, as the checkNumber function is only a single statement it does not require curly braces due to the arrow notation.<br />
<br />
==== MakeSave Function ====<br />
The makeSave function implements the logic of a fireball spell, it shows an example of building a message by parts to later use in a call to MapTool.chat.broadcast.<br />
<br />
==== GetInput Function ====<br />
The getInput function builds a complex macro expression to call the input function at the end, it uses a for loop to do so, this get input function could be reused for any number of inputs, it also is an example of using the JSON builtin object to transform a textual json object into a javascript object.<br />
<br />
== Javascript Macro Writing Tips ==<br />
=== Always Use Try Catch Blocks ===<br />
if you don't you will get cryptic error messages that give no information <br />
=== Calling A Previously Defined Function In A Namespace===<br />
When you define a global variable it lives in the Javascript namespace until the campaign is reloaded. you can just add <code>MTScript.registerMacro(macroName, function)</code> to define a UDF named js.macroName that calls the function, note however that as of 1.11.5 [https://github.com/RPTools/maptool/issues/3231 you can't access json objects received from Maptool]<br />
<br />
== See also ==<br />
* [[ Introduction To DOM Manipulation ]]<br />
* [[ Introduction To Fetch And Asynchronous Javascript ]]<br />
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript MDN Javascript Tutorial ]<br />
* [https://www.w3schools.com/js/default.asp W3school Javascript Tutorial]</div>Melekhttps://wiki.rptools.info/index.php?title=macroLinkText&diff=11672macroLinkText2021-11-29T18:47:54Z<p>Melek: Fix link.</p>
<hr />
<div>{{MacroFunction<br />
|name=macroLinkText<br />
|version=1.3b48<br />
|description=<br />
Creates the text that would appear in a HTML tag for a link which will run the specified macro when clicked on. This is useful for callbacks in {{roll|dialog}} or {{roll|frame}}. If you just want to send a click-able link to someone use {{func|macroLink}}.<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
macroLinkText(macroName)<br />
</source><br />
<source lang="mtmacro" line><br />
macroLinkText(macroName, output)<br />
</source><br />
<source lang="mtmacro" line><br />
macroLinkText(macroName, output, args)<br />
</source><br />
<source lang="mtmacro" line><br />
macroLinkText(macroName, output, args, target)<br />
</source><br />
'''Parameters'''<br />
{{param|macroName|The name of the macro to run when the link is clicked. The {{code|macroName}} is in the standard macro reference format (e.g. {{code|Macro@Lib:Token}})}}<br />
{{param|output|Who the output of the macro should go to, values are (defaults to {{code|none}}):}}<br />
** {{code|self}} - Display only to person who clicked on the link.<br />
** {{code|gm}} - Display to GM.<br />
** {{code|all}} - Everyone (acts like a {{code|/say}})<br />
** {{code|none}} - Discard any output.<br />
** {{code|gm-self}} - Display to GM and the person executing the link.<br />
** {{code|list}} - Displays to a list of players. When the {{code|output}} parameter is {{code|"list"}} then the macro link expects the {{code|args}} parameter to be a [[JSON Object]], that contains a field called {{code|mlOutputList}} which is a [[JSON Array]] containing the players to send the output to.<br />
{{param|args|Any arguments to be passed to the macro when it is called.}}<br />
{{param|target|Which tokens to run the macro on. Target can be one or more of the following separated by commas (defaults to {{code|impersonated}}):}}<br />
** {{code|impersonated}} - The impersonated [[Token]].<br />
** {{code|selected}} - The selected [[Token]]/s.<br />
** [[Token ID]] - The {{code|id}} of a [[Token]].<br />
<br />
|examples=<br />
To create the text that would go inside a form element as the {{code|action}} attribute, and that will call a macro named {{code|Test}} on the [[Library Token]] named {{code|Lib:Test}}:<br />
<source lang="mtmacro" line><br />
[r: macroLinkText("Test@Lib:Test","", "gm")]<br />
</source><br />
Returns: {{code|macro://Test@Lib:Test/gm/impersonated?}}<br />
<br />
To create the text that would go inside a form element as the {{code|action}} attribute and call the {{code|AddWeapon}} on the [[Library Token]] named {{code|Lib:PC}} which will act upon the [[Current Token]]:<br />
<source lang="mtmacro" line><br />
[r:macroLinkText('AddWeapon@Lib:PC', 'none', '', currentToken())]<br />
</source><br />
Returns: {{code|macro://AddWeapon@Lib:PC/none/#ID#?}} where {{code|#ID#}} is the {{code|id}} of the [[Current Token]].<br />
<br />
Sending to multiple players and the GM in 1.3b55<br />
<source lang="mtmacro" line><br />
[h: outputTo = '["Fred", "Barney", "gm"]']<br />
[h: args = json.set("{}", "mlOutputList", outputTo)]<br />
[r: macroLinkText("Test@Lib:Test", "list", args)]<br />
</source><br />
<br />
Correctly modifying the colour of the link, works both in the chat box and in forms:<br />
<source lang="mtmacro" line><br />
[r: strformat('<a style="color:red" href="%s">Click Me</a>', macroLinkText("Test@Lib:Test"))] <br />
</source><br />
<br />
Opening an overlay with arguments to the GM panel macro {{code|loadGMOverlay}} for all connected GMs using {{func|execLink}}. <br />
<br />
* This is a very useful pattern to load an overlay for all players or GMs with a library token using {{code|onCampaignLoad}}. <br />
* In this example, the hypothetical overlay function can take text and background color arguments in a [[String_Property_List|String Property List]].<br />
<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("loadGMOverlay@GM", "none", "text=white;background=black")] <br />
[h: execLink(link, 0, "gm")] <br />
</source><br />
<br />
<br />
|also=<br />
{{func|macroLink}}<br />
{{func|execLink}}<br />
<br />
|changes=<br />
{{change|1.3b55|Added {{code|gm-self}} and {{code|list}} output options.}}<br />
{{change|1.3b56|Links created using this function will no longer show a tooltip when displayed in a dialog or frame.}}<br />
<br />
}}<br />
[[Category:Miscellaneous Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=execLink&diff=11671execLink2021-11-29T18:47:25Z<p>Melek: Add an example mirroring new example on macroLinkText</p>
<hr />
<div>{{MacroFunction<br />
|name=execLink<br />
|version=1.3b55<br />
|trusted=true<br />
|description=<br />
Executes a macro link that was created with {{func|macroLinkText}}, output generated by the link is sent to players using the standard {{func|macroLinkText}} logic. {{func|execLink}} allows you to defer the running of the link until after the currently running macro has ended in which case the output will be displayed after any output generated by the current macro. If you defer a series of links, they will be queued in order and executed after the currently running macro. There is no software limit to the amount of links you can queue, but your hardware will impose its own limitations. If the execution of the link is not defered then any output generated will appear ''before'' any output generated by the current macro. <br />
<br />
You can use this function to update values in a token copied with {{func|copyToken}} using the defered option. You can also use this function to send output selectivly to a list of players from the current macro, or to generate output that is not suppressed when the {{func|abort}} function is called.<br />
<br />
|usage=<br />
<br />
<source lang="mtmacro" line><br />
execLink(link)<br />
execLink(link, defer)<br />
execLink(link, defer, targets)<br />
execLink(link, defer, targets, delim)<br />
</source><br />
'''Parameters'''<br />
{{param|link|The link to "execute".}}<br />
{{param|defer|Executes the link after the current macro has completed if non zero, defaults to zero.}}<br />
{{param|targets|are the user names (so not token names) but the names of the users that are logged in. The options "gm", "gm-self", "self", "not-self", "not-gm", "not-gm-self", "none", and "all" are also valid parameters to give. E.g.: "tim, tom, tarra". Defaults to self (so if no parameter is given the link is executed locally only). Here is a summary of the valid values:<br />
::: '''''Player name''''': The named player.<br />
::: '''self''': Self only (default, link is only executed locally).<br />
::: '''gm''': GM only.<br />
::: '''gm-self''': Both the GM and self.<br />
::: '''all''': All connected players and GMs.<br />
::: '''not-self''': Anyone but self.<br />
::: '''not-gm''': All non-GMs.<br />
::: '''not-gm-self''': All players apart from the GM and self.<br />
::: '''none''': No players. No GMs.}}<br />
{{param|delim|The delimiter used to separate the values in the String List that is given, defaults to {{code|","}}. If {{code|"json"}} is specified, a JSON array is expected instead of a String List.}}<br />
<br />
<br />
|examples=<br />
Execute a macro link immediately (any output will appear before the current macros output)<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("Test@Lib:Test", "self")]<br />
[h: execLink(link)]<br />
</source><br />
<br />
Execute a macro link after the execution of the current macro (any output will appear before the current macros output)<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("Test@Lib:Test", "self")]<br />
[h: execLink(link, 1)]<br />
</source><br />
<br />
Copy a token and update its values.<br />
<source lang="mtmacro" line><br />
[h: newToken = copyToken("Hero")]<br />
[h: link = macroLinkText("update@Lib:GM", "none", "", newToken)]<br />
[h: execLink(link)]<br />
</source><br />
<br />
Execute a macro link on all clients<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("Test@Lib:Test", "none")]<br />
[h: execLink(link, 0, "all")]<br />
</source><br />
<br />
Opening an overlay with arguments to the GM panel macro {{code|loadGMOverlay}} for all connected GMs. <br />
<br />
* This is a very useful pattern to load an overlay with a library token using {{code|onCampaignLoad}}. <br />
* In this example, the hypothetical overlay function can take text and background color arguments in a [[String_Property_List|String Property List]].<br />
<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("loadGMOverlay@GM", "none", "text=white;background=black")] <br />
[h: execLink(link, 0, "gm")] <br />
</source><br />
<br />
|changes=<br />
{{change|1.5.5|Added the {{code|targets}} and {{code|delim}} parameters.}}<br />
{{change|1.5.7|Added "not-self", "not-gm" and "not-gm-self" as valid targets.}}<br />
<br />
|also=<br />
{{func|macroLinkText}} {{func|macroLink}} {{func|copyToken}}<br />
<br />
}}<br />
===Notes===<br />
Deferred functions/links which are queued within a deferred macro do not run directly after the queuing macro, but instead is added to the end of the stack of all the deferred functions and links. This means you cannot 'nest' deferrals or insert deferrals in the middle of the stack of deferred macros. For discussion of this functionality and possible workarounds you can [https://github.com/RPTools/maptool/issues/2633 read more on GitHub].<br />
[[Category:Miscellaneous Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=macroLinkText&diff=11670macroLinkText2021-11-29T18:45:50Z<p>Melek: Add example and 'see also' for use with execLink.</p>
<hr />
<div>{{MacroFunction<br />
|name=macroLinkText<br />
|version=1.3b48<br />
|description=<br />
Creates the text that would appear in a HTML tag for a link which will run the specified macro when clicked on. This is useful for callbacks in {{roll|dialog}} or {{roll|frame}}. If you just want to send a click-able link to someone use {{func|macroLink}}.<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
macroLinkText(macroName)<br />
</source><br />
<source lang="mtmacro" line><br />
macroLinkText(macroName, output)<br />
</source><br />
<source lang="mtmacro" line><br />
macroLinkText(macroName, output, args)<br />
</source><br />
<source lang="mtmacro" line><br />
macroLinkText(macroName, output, args, target)<br />
</source><br />
'''Parameters'''<br />
{{param|macroName|The name of the macro to run when the link is clicked. The {{code|macroName}} is in the standard macro reference format (e.g. {{code|Macro@Lib:Token}})}}<br />
{{param|output|Who the output of the macro should go to, values are (defaults to {{code|none}}):}}<br />
** {{code|self}} - Display only to person who clicked on the link.<br />
** {{code|gm}} - Display to GM.<br />
** {{code|all}} - Everyone (acts like a {{code|/say}})<br />
** {{code|none}} - Discard any output.<br />
** {{code|gm-self}} - Display to GM and the person executing the link.<br />
** {{code|list}} - Displays to a list of players. When the {{code|output}} parameter is {{code|"list"}} then the macro link expects the {{code|args}} parameter to be a [[JSON Object]], that contains a field called {{code|mlOutputList}} which is a [[JSON Array]] containing the players to send the output to.<br />
{{param|args|Any arguments to be passed to the macro when it is called.}}<br />
{{param|target|Which tokens to run the macro on. Target can be one or more of the following separated by commas (defaults to {{code|impersonated}}):}}<br />
** {{code|impersonated}} - The impersonated [[Token]].<br />
** {{code|selected}} - The selected [[Token]]/s.<br />
** [[Token ID]] - The {{code|id}} of a [[Token]].<br />
<br />
|examples=<br />
To create the text that would go inside a form element as the {{code|action}} attribute, and that will call a macro named {{code|Test}} on the [[Library Token]] named {{code|Lib:Test}}:<br />
<source lang="mtmacro" line><br />
[r: macroLinkText("Test@Lib:Test","", "gm")]<br />
</source><br />
Returns: {{code|macro://Test@Lib:Test/gm/impersonated?}}<br />
<br />
To create the text that would go inside a form element as the {{code|action}} attribute and call the {{code|AddWeapon}} on the [[Library Token]] named {{code|Lib:PC}} which will act upon the [[Current Token]]:<br />
<source lang="mtmacro" line><br />
[r:macroLinkText('AddWeapon@Lib:PC', 'none', '', currentToken())]<br />
</source><br />
Returns: {{code|macro://AddWeapon@Lib:PC/none/#ID#?}} where {{code|#ID#}} is the {{code|id}} of the [[Current Token]].<br />
<br />
Sending to multiple players and the GM in 1.3b55<br />
<source lang="mtmacro" line><br />
[h: outputTo = '["Fred", "Barney", "gm"]']<br />
[h: args = json.set("{}", "mlOutputList", outputTo)]<br />
[r: macroLinkText("Test@Lib:Test", "list", args)]<br />
</source><br />
<br />
Correctly modifying the colour of the link, works both in the chat box and in forms:<br />
<source lang="mtmacro" line><br />
[r: strformat('<a style="color:red" href="%s">Click Me</a>', macroLinkText("Test@Lib:Test"))] <br />
</source><br />
<br />
Opening an overlay with arguments to the GM panel macro {{code|loadGMOverlay}} for all connected GMs using {{func|execLink}}. <br />
<br />
* This is a very useful pattern to load an overlay for all players or GMs with a library token using {{code|onCampaignLoad}}. <br />
* In this example, the hypothetical overlay function can take text and background color arguments in a [[String_Property_List String Property List]].<br />
<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("loadGMOverlay@GM", "none", "text=white;background=black")] <br />
[h: execLink(link, 0, "gm")] <br />
</source><br />
<br />
<br />
|also=<br />
{{func|macroLink}}<br />
{{func|execLink}}<br />
<br />
|changes=<br />
{{change|1.3b55|Added {{code|gm-self}} and {{code|list}} output options.}}<br />
{{change|1.3b56|Links created using this function will no longer show a tooltip when displayed in a dialog or frame.}}<br />
<br />
}}<br />
[[Category:Miscellaneous Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=MapTool_Preferences&diff=11601MapTool Preferences2021-10-08T20:17:33Z<p>Melek: /* Macro Permissions */ Typo</p>
<hr />
<div>{{note|'''Note:''' Screenshots in this article are shown with the default settings, which might not necessarily be the ''recommended'' settings for your use.}}{{Beginner}}<br />
__TOC__<br />
==Interactions Tab==<br />
[[Image:prefs_tab_interactions.png|left|thumb|300px|Interactions Tab on the Preferences Dialog]]<br />
<div style="clear: both"></div><br />
===Maps===<br />
[[Image:Prefs_Interactions_Tab_-_Maps.png|frame|right|Maps Section]] <br />
* '''New maps have Fog of War'''<br />
: Determines if new maps should have [[Fog of War]] enabled when created. If you use [[Fog of War]], it might seem obvious to have this {{Checked}}; however, when creating multiple maps for a new campaign, it is often useful to to disable this feature to assist with rapid map creation since even as a GM you will be unable to clearly view a map covered in [[Fog of War]]. After completing a map, it is a simple process to re-enable [[Fog of War]].<br />
* '''New maps visible to players'''<br />
: Determines if new maps should be set as Player Visible when created. Although there are exceptions, typically having this <span style="font-size: 24px; line-height: 1px; color: red; font-weight: bold; vertical-align: sub;">&#10003;</span>unchecked is the optimal setting; that way you won't unintentionally leave a map visible to players.<br />
* '''New Map Grid Type'''<br />
** '''Square''' [[Image:gridSquare.png|sub]]<br />
** '''Horizontal Hex''' [[Image:gridHorizontalHex.png|sub]]<br />
** '''Vertical Hex''' [[Image:gridVerticalHex.png|sub]]<br />
** '''Isometric''' [[Image:gridIsometric.png|sub]]<br />
: Determines the default grid type of new maps when created. You are free to create maps without a grid type, and also a grid type different than the one specified here, but you can not set the Default Grid Type to none.<br />
* '''New Map Grid Size'''<br />
: Represents the default amount of pixels you want MapTool to use drawing each grid cell at full resolution. The default setting of {{code|100}} pixels is adequate for most computers, but more capable computers can handle {{code|100}} pixels or even {{code|200}} pixels computers. There is no requirement that you use specific sizes, but {{code|50}} pixels and {{code|100}} pixels are commonly used. This setting will also determine how large an image appears when placed on a map layer when 'Start Freesize' is not checked for that layer.<br />
* '''New Map Units Per Cell'''<br />
: Sets the amount of units that each grid cell represents. The ambiguous "unit" is used in this case because you decide what "unit" means. If you want each grid cell to represent 5 feet, this would be set to {{code|5}}. If you want each grid cell to represent 4 kilometers, this would be set to {{code|4}}. This is often referred to as ''Distance Per Cell''. As of v1.5.1 MapTool supports a floating point number for this value.<br />
* '''New Map Vision Distance'''<br />
: The maximum distance that [[PC Token]]s can expose [[Fog of War]] after [[Light]]s, [[Sight]]s, and [[Vision Blocking Layer]]s are taken into account. It is important to note that this setting is measured in ''Distance Per Cell''.<br />
* '''New Map Light'''<br />
: The light setting for new maps. Choose from ''Off'', ''Day'' and ''Night''. (As of MT v1.5.11)<br />
* '''Movement metric'''<br />
** '''ONE_TWO_ONE''' specifies that every second diagonal movement will calculate as twice the ''Distance Per Cell''.<br />
** '''ONE_ONE_ONE''' specifies that diagonal movement will calculate the same as non-diagonal movement. <br />
** '''MANHATTAN''' specifies that every diagonal movement will calculate as twice the ''Distance Per Cell''.<br />
** '''NO DIAGONALS''' specifies that [[Token]]s can only move non-diagonally.<br />
: Determines how movement should be calculated when a [[Token]] moves diagonally on maps using a Square or Isometric grid. This affects the total distance displayed beneath a [[Token]] when it is moving, or when its previous path is displayed; it is calculated based on ''Distance Per Cell''. Maps with Hex grid types ignore this setting and instead calculate movement in any direction using the ''Distance Per Cell''.<br />
<br />
===Tokens===<br />
[[Image:Prefs_Interactions_Tab_Tokens.png|frame|right|Tokens Section]] <br />
* '''Start Snap to Grid'''<br />
: Determines if [[Token]]s will default to having '''Snap to Grid''' {{Checked}}. Having this setting {{Checked}} is optimal for maps that use a grid, but even on such maps there are cases when you might want to temporarily disable this setting(e.g. when placing a lot of "prop" [[Token]]s on the Object layer while drawing a map). <br />
* '''New tokens visible to players'''<br />
: Determines if new [[Token]]s have the '''Visible''' option {{Checked}} upon creation. The optimal setting for this really depends on your play style; if you have a lot of random encounters and build them during play, you may find it useful to have this setting disabled. <br />
* '''Warn when tokens are deleted'''<br />
: When {{Checked}} MapTool asks for confirmation whenever deleting a [[Token]].<br />
* '''Duplicate Token Numbering'''<br />
** '''Increment'''<br />
** '''Random'''<br />
: Will automatically generate numbers for [[Token]]s with duplicate names upon creation to distinguish them. '''Increment''' will leave the first token unnumbered, but will number each duplicate after that starting with the number {{code|1}} (e.g. Troll, Troll 1, Troll 2). '''Random''' will create a random two-digit or greater number for the token, even if there are no duplicates on the map yet. '''Random''' might be considered the optimal setting, as it gives your players no indication of how many copies of that [[Token]] can be expected to exist.<br />
* '''Show Numbering on'''<br />
** '''Name'''<br />
** '''GM Name'''<br />
** '''Both'''<br />
: Specifies where the number that derived from '''Duplicate Token Numbering''' is applied. '''Name''' appends the number after the name (derived from '''New Token Naming'''). '''GM Name''' places the number within the ''GM Name'' field of the [[Token]] options. '''Both''' appends the number after the name, and places it within the ''GM Name'' field of the [[Token]] options. <br />
: <span style="color:red;">'''Note'''</span>: It is generally recommended that you set this preference to '''Name''' or '''Both''', and not '''GM Name'''. Any [[Macro Introduction|Macros]] which refer to tokens by name rather than by token ID will break/behave unpredictably when a map has multiple tokens with the same name.<br />
* '''New Token Naming'''<br />
** '''Use Filename'''<br />
** '''Use "Creature"'''<br />
: Determines what the name will be when creating a new [[Token]], or what the ''Name'' field will be pre-filled with in a new [[Token]] dialog. '''Use Filename''' specifies that the name will be derived from the name of the file that was added to your Resource Library (e.g. if you add the file ''uglytroll.jpg'' to your Resource Library, tokens created from that image will begin with the name ''uglytroll''). '''Use "Creature"''' defaults all new [[Token]]s to being named "Creature" (without quotes). <br />
* '''Start Freesize'''<br />
: If you are using a map with a grid, [[Token]]s typically default to the size of one grid cell upon creation. Having this setting {{Checked}} allows you to have them default to the image's ''Native Size''. ''Native Size'' tokens moved to another layer become ''Freesize'', which can be resized by dragging a handle in their lower right corner.<br />
* '''Show Dialog on New Token'''<br />
: When this setting is {{Checked}}, a ''New Token'' dialog will open when you drag an image onto the map, allowing you to set some options prior to creation. If you disable this setting, all new tokens will be created with the default settings derived from previous settings in this section.<br />
* '''Stat Sheet Portrait Size''' ''(Set to 0 to disable portaits)''<br />
: Sets the width (in pixels) of the portrait that is displayed in the lower left corner of the map when mousing over certain [[Token]]s; the image is resized proportionately. A portrait is displayed under a few different circumstances; if the [[Token]] has properties that are set to display on the stat sheet, and those properties have values, the portrait will display the token image. If the [[Token]] has a portrait image set, it will display with or without a stat sheet. Why might you want to set this to {{code|0}}? Besides the obvious reason of not displaying the portrait, you might want to use a stat sheet, but not want a portrait displayed with it; or perhaps you don't want to use a stat sheet or a portrait, but would like to have the portrait image 'slot' usable for other purposes, like inside a Dialog or Frame.<br />
* '''Show Portrait on mouseover'''<br />
: When {{Checked}}, displays the token's Portrait image in the lower left corner when the cursor is hovered over the token.<br />
* '''Show stat sheet on mouseover'''<br />
: When {{Checked}}, displays the token's stat sheet in the lower left corner (to the right of the portrait) when the cursor is hovered over the token.<br />
* '''Stat sheet requires Shift key'''<br />
: Requires the Shift key be held down when the cursor is hovered over the token in order to display the stat sheet when {{Checked}}. Has no effect if ''Show stat sheet on mouseover'' is unchecked. MapTool only checks if the Shift key is depressed when the cursor first passes over a token and then either displays or suppresses the stat sheet, meaning you cannot use this setting to 'toggle' the statsheet on and off with the shift key without also moving the cursor.<br />
* '''Force Token Facing Arrow'''<br />
: Displays a yellow facing arrow on all tokens with a facing value when {{Checked}}, even on top-down tokens which normally omit them.<br />
* '''Snap Token while dragging'''<br />
: Tokens will snap to the grid as they are dragged when {{Checked}}. When unchecked, the token's path and destination are still highlighted.<br />
* '''Hide Mouse Pointer while dragging'''<br />
: MapTool hides the cursor arrow while dragging tokens within the map view when {{Checked}}.<br />
<br />
===Chat===<br />
Chat autosave settings now reside in the 'Application' tab of the Preferences window. <br />
[[Image:prefs_interactions_chat.png|frame|right|Chat Section]] <br />
* '''Show Avatar per line'''<br />
: The image for the impersonated token is shown next to any chat output it creates, when this is {{Checked}}. This is a client-side setting and does not effect any other clients connected to the same game.<br />
* '''Insert Smilies'''<br />
: Replaces common smiley(emoticon) character sequences with graphical smilies when this is {{Checked}}. If you use a lot of macros, it is recommended that you turn this off, as it could cause some complications if any of your macro code is interpreted as a smiley.<br />
* '''Use ToolTips for Inline Rolls'''<br />
: Sets the default display ([[:Category:Display Roll Option|Display Roll Option]]) for rolls in the chat panel. Will use {{roll|tooltip}} if this is {{Checked}}, otherwise it will default to {{roll|expanded}}.<br />
* '''Suppress ToolTips for MacroLinks'''<br />
: MacroLinks normally show tooltips that state information about the link target as an anti-cheating device. When {{Checked}}, these tooltips are disabled.<br />
* '''Typing Notification Duration Seconds'''<br />
: The number of seconds before typing notifications in the top left of the Map View disappear after a player's last keystroke.<br />
* '''Typing Notification Color'''<br />
: Color of the text for typing notifications.<br />
* '''Show Chat Notification Background'''<br />
: When {{Checked}} shows a graphic behind typing notifications. Can be helpful to provide consistently contrasting background for the notifications.<br />
* '''Trusted Prefix Background'''<br />
: Sets a custom background for macro output that comes from a [[Trusted Macro]].<br />
* '''Trusted Prefix Foreground'''<br />
: Sets a custom foreground (text color) for macro output that comes from a [[Trusted Macro]].<br />
<br />
===Macro Editor===<br />
[[Image:Prefs_Interactions_Tab_Macro_Editor.png|frame|right|Macro Editor Section]]<br />
* '''Style Theme'''<br />
: Select from a variety of themes for macro editor windows.<br />
<div style="clear: both"></div><br />
<br />
===Objects===<br />
[[Image:Prefs_Interactions_Tab_Objects.png|frame|right|Objects Section]] <br />
* '''Start Snap to Grid'''<br />
: Tokens created on map's Object layer will automatically be set to '''Snap to Grid''' if this is {{Checked}}. <br />
* '''Start Freesize'''<br />
: Tokens created on a map's Object layer will automatically be set to '''Freesize''' if this is {{Checked}}.<br />
<br />
===Backgrounds===<br />
[[Image:Prefs_Interactions_Tab_Backgrounds.png|frame|right|Backgrounds Section]] <br />
* '''Start Snap to Grid'''<br />
: Images dropped on a map's Background layer will automatically be set to '''Snap to Grid''', if this is {{Checked}}. <br />
* '''Start Freesize'''<br />
: Images dropped on a map's Background layer will automatically be set to '''Freesize''', if this is {{Checked}}.<br />
<br />
===Facing===<br />
[[Image:Prefs_Interactions_Tab_Facing.png|frame|right|Facing Section]] <br />
* '''On Edges'''<br />
: A token's facing will snap to the edges when {{Checked}}. Edges are the lines that make up a grid cell.<br />
* '''On Vertices'''<br />
: A token's facing will snap to the vertices when {{Checked}}. Vertices are the points that connect the lines that make up a grid cell.<br />
<br />
==Accessibility Tab==<br />
[[Image:prefs_tab_accessibility.png|thumb|right|300px|Accessibility Tab on the Preferences Dialog]]<br />
* '''Chat Font Size'''<br />
: The default size of the font in the chat panel; measured in points.<br />
* '''ToolTip Initial Delay'''<br />
: The time it takes for a tooltip to display when hovering the mouse over an element that possesses a tooltip; measured in miliseconds.<br />
* '''ToolTip Dismiss Delay'''<br />
: The time it takes for a tooltip to disappear when hovering the mouse over an element that possesses a tooltip; measured in miliseconds.<br />
<br />
<div style="clear: both"></div><br />
<br />
==Application Tab==<br />
[[Image:prefs_tab_application.png|left|thumb|300px|Application Tab on the Preferences Dialog]]<br />
<div style="clear: both"></div><br />
===Save===<br />
[[Image:prefs_application_save.png|frame|right|Save Section]] <br />
* '''Campaign autosave every [ ] min'''<br />
: Saves an autosave copy of your campaign in the interval specified in <code>%{appHome}/autosave</code>. This will not overwrite your campaign file, but rather create a file which is updated every time it automatically saves. Autosave is only a temporary file, useful in case MapTool crashes. When MapTool is properly closed, the Autosave file is deleted. Note the interval is the time between the last save completing and the start of the next one.<br />
: As a troubleshooting aid, the AutoSaveManager will switch from measuring the autosave interval in minutes to seconds when the [[log.setLevel|log level]] for that package is set to “DEBUG”.<br />
* '''Save reminder on close'''<br />
: Displays a dialog when attempting to close the program with unsaved changes to your campaign when {{Checked}}.<br />
* '''Time between chat log autosaves'''<br />
: The amount of time in minutes between the autosaving of the chat log.<br />
* '''Autosave chat log filename'''<br />
: The filename that will be used when automatically saving your chat log.<br />
* '''File Sync Directory'''<br />
: Specify a path to a local cloud-synced directory to determine relative path external files such as Hero Lab portfolios.<br />
* '''1.3b50 Compatability Mode''' <br />
: <code>This setting has been removed. You can use File > Export Campaign As... to save campaigns for MapTool versions as far back as 1.4.0.</code><br />
: Due to some changes in how certain data is stored in the campaign file in versions after 1.3b50, they might not be compatible with version 1.3b50 and earlier. If this is {{Checked}} your campaign will be saved in the older format, allowing it to be opened in older versions, but losing some of the new features.<br />
<br />
===Map Visuals===<br />
[[Image:Prefs_Application_Tab_Map_Visuals.png|frame|right|Map Visuals Section]] <br />
* '''Halo line width'''<br />
: Controls the width of the [[Halo]] border when it is displayed on a [[Token]].<br />
* '''Use halo color for vision'''<br />
: When this setting is {{Checked}}, hovering over a token with [[Vision]] overlays the token's visible area with the token's [[Halo]] color. This overlay is a translucent layer controlled by the '''Halo opacity''' setting. <br />
* '''Halo opacity'''<br />
: Controls the opacity of the optional overlay enabled by the '''Use halo color for vision''' setting. This does not control the actual [[Halo|Halo's]] outline opacity, which is always completely opaque. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Aura opacity'''<br />
: Controls the opacity of color overlays provided by [[Aura|Auras]] enabled on tokens. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Light opacity'''<br />
: Controls the opacity of color overlays provided by [[Introduction_to_Lights_and_Sights#Light_Sources|Light Sources]] enabled on tokens. This also affects 'personal' lights defined in a token's [[Vision]] setting. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Fog opacity'''<br />
: Controls the opacity of the black layer of 'Soft Fog' that is left in previously explored areas when [[Fog of War]] is enabled. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Auto-expose fog on token movement (GM Only)'''<br />
: Will automatically expose [[Fog of War]] after moving a [[Token]] if {{Checked}}. This setting is intended to help test Fog of War and VBL when not hosting a game. When running a server, this setting is ignored in favor of the settings in the 'Start Server' dialog.<br />
<br />
===Performance===<br />
[[Image:Prefs_Application_Tab_Performance.png|frame|right|Performance Section]]<br />
* '''Fill selection box'''<br />
: When {{Checked}}, the selection box which appears when dragging to select tokens in the Map View will contain a translucent blue fill. Less powerful devices running MapTool may see a small performance gain from unchecking this setting.<br />
* '''Frame Rate Cap''' <code>New in MapTool 1.5.7</code><br />
: Sets the maximum frame rate for the map renderer. Less powerful devices running MapTool may see a performance gain by lowering this setting.<br />
<br />
===Initiative Defaults===<br />
[[Image:Prefs_Application_Tab_Initiative_Defaults.png|frame|right|Initiative Section]]<br />
* '''Hide NPCs from players on new maps'''<br />
: When {{Checked}}, automatically enables 'Hide NPCs' in the [[Initiative Panel]] on new maps. This setting doesn't show connected players [[NPC Tokens]] on the Initiative Panel.<br />
* '''Give Owners Permission in new campaigns'''<br />
: This automatically enables the 'Owner Permissions' setting in the [[Initiative Panel]] on new maps when {{Checked}}. The setting mainly lets players with token ownership add their tokens to or remove their tokens from the initiative list and advance the initiative when it is their token's turn.<br />
* '''Lock Player Movement in new campaigns'''<br />
: When {{Checked}}, new maps will have 'Lock Player Movement' automatically enabled in the [[Initiative Panel]]. This setting prevents players who do not own the token with initiative from moving any tokens.<br />
* '''Show Initiative Gain Message'''<br />
: When initiative advances to a [[PC Token]] token and this is {{Checked}}, a simple 'Token Name has received initiative' message is displayed for all players in chat. This is ignored for [[NPC Token|NPC Tokens]].<br />
<br />
===Client===<br />
[[Image:Prefs_Application_Tab_Client2.png|frame|right|Client Section]]<br />
* '''Fit GM View'''<br />
: When {{Checked}} and the GM uses 'Center Players on Current View', the Map View will zoom out as necessary to accommodate the entire GM view. If unchecked, the zoom level will be set to match the GM's Map View, which will occlude part of the map if your Map View areas are different sizes.<br />
<br />
* '''Default Username'''<br />
: Use to set the Default Username that appears in the MapTool title bar when a personal server is running. Defaults to ''Anonymous User''. (Added MapTool v1.9.0.)<br />
<br />
===Macro Panels===<br />
[[Image:Prefs_Application_Tab_Macro_Panels.png|frame|right|Macro Panels Section]] <br />
* '''Default: Allow Players to Edit Macros'''<br />
: In order for a macro to be considered a [[Trusted Macro]], players must not be able to edit it. This setting determines if a new macro should default to allowing players to edit if {{Checked}}. Disabling this setting can be very useful if you intend to create a lot of macros that you intend to be trusted.<br />
<br />
===UPnP===<br />
[[Image:Prefs_Application_Tab_UPnP.png|frame|right|UPnP Section]]<br />
* '''Discovery Timeout'''<br />
: The timeout period in milliseconds MapTool will wait when searching for UPnP gateways before giving up.<br />
<br />
===Macro Permissions===<br />
[[Image:Prefs_Application_Tab_Macro_Permissions.png|frame|right|Macro Permissions Section]]<br />
* '''Enable External Macro Access'''<br />
: When {{Checked}}, [[Introduction to Macro Writing|Macros]] may call functions that access your drive and http services. Some examples (not a complete list) of functions which will be enabled are [[RESTful Functions Overview|REST Functions]], [[exportData]], and [[getEnvironmentVariable]].<br />
: <br><strong>Note about security:</strong> This option is off by default and exposes you to some risk when enabled. For instance, a malicious macro could communicate with an external server and store data on your local computer. Only enable this option if all the macros and libraries in your campaign files were written by you or directly from authors you trust.<br />
<div style="clear: both"></div><br />
<br />
==Sounds Tab==<br />
[[Image:prefs_tab_sounds.png|thumb|right|300px|Sounds Tab on the Preferences Dialog]]<br />
* '''Play system sounds'''<br />
: When {{Checked}}, MapTool will play a sound when new content is sent to the chat panel.<br />
* '''Play streams'''<br />
: When {{Checked}}, streams started with [[playStream]] will be allowed to play.<br />
* '''Only when window not focused'''<br />
: When {{Checked}}, the sound that MapTool plays when new content is sent to the chat panel will only play if MapTool is not the application that has focus.<br />
* '''Turn on Syrinscape Integration'''<br />
: When clicking <code>syrinscape-fantasy:</code> links in MapTool, the Syrinscape Fantasy Player will be allowed to automatically open when this setting is {{Checked}}. This has no effect on [[Syrinscape Integration]] using the REST API and Online Player.<br />
<br />
==Startup Tab==<br />
[[Image:Prefs_Startup_Tab.png|thumb|300px|frame|left|Startup Tab of Preferences Dialog]]<br />
<div style="clear: both"></div><br />
<br />
===JVM Memory Settings===<br />
[[Image:Prefs_Startup_Tab_JVM_Settings.png|frame|right|JVM Memory Section]]<br />
These preferences are somewhat advanced. To better understand how MapTool uses memory settings, read about [[Stack Size]]. If you are having Stack Overflow errors and need to modify these settings for more reliable performance, read about [[Avoiding Stack Overflow]]. If you need help resetting MapTool memory settings, check out [https://www.rptools.net/2019/04/resetting-maptool/ Resetting MapTool JVM Settings] on the RPTools blog.<br />
<br />
<div class="template_clarify" style="border: solid red 2px; background-color: lightgrey; padding: 5px"><br />
The packaging tool provided with Java 14+ has eliminated our ability to have MapTool configure its memory settings for you. For the time being, these options are greyed out and the user must edit the configuration file directly using a normal text editor. This text is taken from a Discord post by Phergus and replicated [https://forums.rptools.net/viewtopic.php?f=1&t=29087&p=278171#p277802| on our forum]. This is not likely to change until Java 17 is released at the earliest, and possibly later if the Java developers don't correct it by then.<br />
<br />
'''Startup Config for MT 1.8.x'''<br/><br />
Locate and edit the {{code|maptool.cfg}} file under the application folder in your MapTool install directory. In most cases, you shouldn't need to change ANY of them, excepting {{code|user.language}} for those in different locales.<br />
<br />
Under {{code|[JavaOptions]}} you can add/set the following (example values are shown):<br />
: {{code|-Xmx4G}} - set max heap to 4G<br />
: {{code|-Xms1G}} - set min heap to 1G<br />
: {{code|-Xss10M}} - set stack size to 10M<br />
: {{code|-Dsun.java2d.d3d{{=}}false}} - disabled Direct3D<br />
: {{code|-Dsun.java2d.opengl{{=}}true}} - enable OpenGL <br />
: {{code|-Djavafx.macosx.embedded{{=}}false}} - initialize AWT before JFX (MacOS only)<br />
: {{code|-Duser.language{{=}}en}} - set MT local to English<br />
: {{code|-Dawt.useSystemAAFontSettings{{=}}on}} - turn on text antialiasing (for Linux)<br />
'''Startup Config for MT 1.9.x'''<br/><br />
The format changed slightly for MT 1.9.x. Each line should now start with {{code|java-options{{=}}}} and then the options listed for MT 1.8.x.<br />
</div><br />
These three settings are memory sizes in bytes. The letter at the end can be K, M, or G signifying Kilobytes, Megabytes, or Gigabytes. Changes to these settings take effect upon restarting MapTool.<br />
<br />
* '''Maximum heap size (-Xmx)'''<br />
: The maximum amount of total memory (RAM) MapTool can use at once, usually entered in Gigabytes (G). For heavy frameworks with many assets, you may have to raise this value. 4G is a generous default value for nearly all users with at least 8GB of RAM.<br />
* '''Initial & minimum heap size (-Xms)'''<br />
: The minimum amount of memory (RAM) which MapTool will always reserve for use, usually entered in Gigabytes (G). Oracle recommends this setting be the same as the Maximum heap size. Doing so may provide performance gains by reducing garbage collection operations. This value should not be higher than the Maximum heap size.<br />
* '''Thread stack size (-Xss)'''<br />
: The memory each particular Java thread has reserved for its use, usually entered in Megabytes (M). Raising this value may allow more complex macros to be run, but it should generally be kept as low as possible. 4M is a generous default value that allows most macros to work just fine. To help understand this value, a simple campaign using short macros or no macros may be able to run successfully with a value as low as 256K, while a campaign containing extremely large macros may need 5M or 6M to avoid stack overflow.<br />
<br />
===Advanced Options===<br />
[[Image:Prefs_Startup_Tab_Advanced_Options.png|frame|right|Advanced Options Section]]<br />
These options are used for development and troubleshooting. Changes to these settings take effect upon restarting MapTool.<br />
<br />
* '''Enable assertions'''<br />
: Developers often test MapTool with this option {{Checked}} to enable additional Java checks so they can find additional warnings or errors. This setting is not recommended for normal users as it lowers performance.<br />
* '''Disable Direct3d Pipeline'''<br />
: When {{Checked}}, MapTool will not use Direct3D. This is mainly used by developers, but if you are having visual issues you can try using this setting to see if your problem is resolved. If so, it may indicate you need new drivers from your video card manufacturer.<br />
* '''Enable OpenGL Pipeline'''<br />
: This option may help resolve visual issues when {{Checked}} by enabling OpenGL rendering. You do not need to check 'Disable Direct3d Pipeline' in order to use this setting.<br />
* '''Initialize AWT before JavaFX'''<br />
: Developers can use this.<br />
<br />
===Language Override===<br />
[[Image:Prefs_Startup_Tab_Language_Override.png|frame|right|Language Override Section]]<br />
* '''Language'''<br />
: Select the user interface language for MapTool. Changes to this setting take effect upon restarting MapTool.<br />
<br />
===Additional Options===<br />
[[Image:Prefs_Startup_Tab_Additional_Options.png|frame|right|Additional Options Section]]<br />
* '''Data Directory'''<br />
: The local directory where MapTool saves asset cache data, autosaves, backups, configuration files, and more. Changes to this setting take effect upon restarting MapTool.<br />
<br />
[[Category:MapTool]]</div>Melekhttps://wiki.rptools.info/index.php?title=MapTool_Preferences&diff=11600MapTool Preferences2021-10-08T16:05:52Z<p>Melek: /* Macro Permissions */ Add a bit of a warning to Enable External Macro Access option.</p>
<hr />
<div>{{note|'''Note:''' Screenshots in this article are shown with the default settings, which might not necessarily be the ''recommended'' settings for your use.}}{{Beginner}}<br />
__TOC__<br />
==Interactions Tab==<br />
[[Image:prefs_tab_interactions.png|left|thumb|300px|Interactions Tab on the Preferences Dialog]]<br />
<div style="clear: both"></div><br />
===Maps===<br />
[[Image:Prefs_Interactions_Tab_-_Maps.png|frame|right|Maps Section]] <br />
* '''New maps have Fog of War'''<br />
: Determines if new maps should have [[Fog of War]] enabled when created. If you use [[Fog of War]], it might seem obvious to have this {{Checked}}; however, when creating multiple maps for a new campaign, it is often useful to to disable this feature to assist with rapid map creation since even as a GM you will be unable to clearly view a map covered in [[Fog of War]]. After completing a map, it is a simple process to re-enable [[Fog of War]].<br />
* '''New maps visible to players'''<br />
: Determines if new maps should be set as Player Visible when created. Although there are exceptions, typically having this <span style="font-size: 24px; line-height: 1px; color: red; font-weight: bold; vertical-align: sub;">&#10003;</span>unchecked is the optimal setting; that way you won't unintentionally leave a map visible to players.<br />
* '''New Map Grid Type'''<br />
** '''Square''' [[Image:gridSquare.png|sub]]<br />
** '''Horizontal Hex''' [[Image:gridHorizontalHex.png|sub]]<br />
** '''Vertical Hex''' [[Image:gridVerticalHex.png|sub]]<br />
** '''Isometric''' [[Image:gridIsometric.png|sub]]<br />
: Determines the default grid type of new maps when created. You are free to create maps without a grid type, and also a grid type different than the one specified here, but you can not set the Default Grid Type to none.<br />
* '''New Map Grid Size'''<br />
: Represents the default amount of pixels you want MapTool to use drawing each grid cell at full resolution. The default setting of {{code|100}} pixels is adequate for most computers, but more capable computers can handle {{code|100}} pixels or even {{code|200}} pixels computers. There is no requirement that you use specific sizes, but {{code|50}} pixels and {{code|100}} pixels are commonly used. This setting will also determine how large an image appears when placed on a map layer when 'Start Freesize' is not checked for that layer.<br />
* '''New Map Units Per Cell'''<br />
: Sets the amount of units that each grid cell represents. The ambiguous "unit" is used in this case because you decide what "unit" means. If you want each grid cell to represent 5 feet, this would be set to {{code|5}}. If you want each grid cell to represent 4 kilometers, this would be set to {{code|4}}. This is often referred to as ''Distance Per Cell''. As of v1.5.1 MapTool supports a floating point number for this value.<br />
* '''New Map Vision Distance'''<br />
: The maximum distance that [[PC Token]]s can expose [[Fog of War]] after [[Light]]s, [[Sight]]s, and [[Vision Blocking Layer]]s are taken into account. It is important to note that this setting is measured in ''Distance Per Cell''.<br />
* '''New Map Light'''<br />
: The light setting for new maps. Choose from ''Off'', ''Day'' and ''Night''. (As of MT v1.5.11)<br />
* '''Movement metric'''<br />
** '''ONE_TWO_ONE''' specifies that every second diagonal movement will calculate as twice the ''Distance Per Cell''.<br />
** '''ONE_ONE_ONE''' specifies that diagonal movement will calculate the same as non-diagonal movement. <br />
** '''MANHATTAN''' specifies that every diagonal movement will calculate as twice the ''Distance Per Cell''.<br />
** '''NO DIAGONALS''' specifies that [[Token]]s can only move non-diagonally.<br />
: Determines how movement should be calculated when a [[Token]] moves diagonally on maps using a Square or Isometric grid. This affects the total distance displayed beneath a [[Token]] when it is moving, or when its previous path is displayed; it is calculated based on ''Distance Per Cell''. Maps with Hex grid types ignore this setting and instead calculate movement in any direction using the ''Distance Per Cell''.<br />
<br />
===Tokens===<br />
[[Image:Prefs_Interactions_Tab_Tokens.png|frame|right|Tokens Section]] <br />
* '''Start Snap to Grid'''<br />
: Determines if [[Token]]s will default to having '''Snap to Grid''' {{Checked}}. Having this setting {{Checked}} is optimal for maps that use a grid, but even on such maps there are cases when you might want to temporarily disable this setting(e.g. when placing a lot of "prop" [[Token]]s on the Object layer while drawing a map). <br />
* '''New tokens visible to players'''<br />
: Determines if new [[Token]]s have the '''Visible''' option {{Checked}} upon creation. The optimal setting for this really depends on your play style; if you have a lot of random encounters and build them during play, you may find it useful to have this setting disabled. <br />
* '''Warn when tokens are deleted'''<br />
: When {{Checked}} MapTool asks for confirmation whenever deleting a [[Token]].<br />
* '''Duplicate Token Numbering'''<br />
** '''Increment'''<br />
** '''Random'''<br />
: Will automatically generate numbers for [[Token]]s with duplicate names upon creation to distinguish them. '''Increment''' will leave the first token unnumbered, but will number each duplicate after that starting with the number {{code|1}} (e.g. Troll, Troll 1, Troll 2). '''Random''' will create a random two-digit or greater number for the token, even if there are no duplicates on the map yet. '''Random''' might be considered the optimal setting, as it gives your players no indication of how many copies of that [[Token]] can be expected to exist.<br />
* '''Show Numbering on'''<br />
** '''Name'''<br />
** '''GM Name'''<br />
** '''Both'''<br />
: Specifies where the number that derived from '''Duplicate Token Numbering''' is applied. '''Name''' appends the number after the name (derived from '''New Token Naming'''). '''GM Name''' places the number within the ''GM Name'' field of the [[Token]] options. '''Both''' appends the number after the name, and places it within the ''GM Name'' field of the [[Token]] options. <br />
: <span style="color:red;">'''Note'''</span>: It is generally recommended that you set this preference to '''Name''' or '''Both''', and not '''GM Name'''. Any [[Macro Introduction|Macros]] which refer to tokens by name rather than by token ID will break/behave unpredictably when a map has multiple tokens with the same name.<br />
* '''New Token Naming'''<br />
** '''Use Filename'''<br />
** '''Use "Creature"'''<br />
: Determines what the name will be when creating a new [[Token]], or what the ''Name'' field will be pre-filled with in a new [[Token]] dialog. '''Use Filename''' specifies that the name will be derived from the name of the file that was added to your Resource Library (e.g. if you add the file ''uglytroll.jpg'' to your Resource Library, tokens created from that image will begin with the name ''uglytroll''). '''Use "Creature"''' defaults all new [[Token]]s to being named "Creature" (without quotes). <br />
* '''Start Freesize'''<br />
: If you are using a map with a grid, [[Token]]s typically default to the size of one grid cell upon creation. Having this setting {{Checked}} allows you to have them default to the image's ''Native Size''. ''Native Size'' tokens moved to another layer become ''Freesize'', which can be resized by dragging a handle in their lower right corner.<br />
* '''Show Dialog on New Token'''<br />
: When this setting is {{Checked}}, a ''New Token'' dialog will open when you drag an image onto the map, allowing you to set some options prior to creation. If you disable this setting, all new tokens will be created with the default settings derived from previous settings in this section.<br />
* '''Stat Sheet Portrait Size''' ''(Set to 0 to disable portaits)''<br />
: Sets the width (in pixels) of the portrait that is displayed in the lower left corner of the map when mousing over certain [[Token]]s; the image is resized proportionately. A portrait is displayed under a few different circumstances; if the [[Token]] has properties that are set to display on the stat sheet, and those properties have values, the portrait will display the token image. If the [[Token]] has a portrait image set, it will display with or without a stat sheet. Why might you want to set this to {{code|0}}? Besides the obvious reason of not displaying the portrait, you might want to use a stat sheet, but not want a portrait displayed with it; or perhaps you don't want to use a stat sheet or a portrait, but would like to have the portrait image 'slot' usable for other purposes, like inside a Dialog or Frame.<br />
* '''Show Portrait on mouseover'''<br />
: When {{Checked}}, displays the token's Portrait image in the lower left corner when the cursor is hovered over the token.<br />
* '''Show stat sheet on mouseover'''<br />
: When {{Checked}}, displays the token's stat sheet in the lower left corner (to the right of the portrait) when the cursor is hovered over the token.<br />
* '''Stat sheet requires Shift key'''<br />
: Requires the Shift key be held down when the cursor is hovered over the token in order to display the stat sheet when {{Checked}}. Has no effect if ''Show stat sheet on mouseover'' is unchecked. MapTool only checks if the Shift key is depressed when the cursor first passes over a token and then either displays or suppresses the stat sheet, meaning you cannot use this setting to 'toggle' the statsheet on and off with the shift key without also moving the cursor.<br />
* '''Force Token Facing Arrow'''<br />
: Displays a yellow facing arrow on all tokens with a facing value when {{Checked}}, even on top-down tokens which normally omit them.<br />
* '''Snap Token while dragging'''<br />
: Tokens will snap to the grid as they are dragged when {{Checked}}. When unchecked, the token's path and destination are still highlighted.<br />
* '''Hide Mouse Pointer while dragging'''<br />
: MapTool hides the cursor arrow while dragging tokens within the map view when {{Checked}}.<br />
<br />
===Chat===<br />
Chat autosave settings now reside in the 'Application' tab of the Preferences window. <br />
[[Image:prefs_interactions_chat.png|frame|right|Chat Section]] <br />
* '''Show Avatar per line'''<br />
: The image for the impersonated token is shown next to any chat output it creates, when this is {{Checked}}. This is a client-side setting and does not effect any other clients connected to the same game.<br />
* '''Insert Smilies'''<br />
: Replaces common smiley(emoticon) character sequences with graphical smilies when this is {{Checked}}. If you use a lot of macros, it is recommended that you turn this off, as it could cause some complications if any of your macro code is interpreted as a smiley.<br />
* '''Use ToolTips for Inline Rolls'''<br />
: Sets the default display ([[:Category:Display Roll Option|Display Roll Option]]) for rolls in the chat panel. Will use {{roll|tooltip}} if this is {{Checked}}, otherwise it will default to {{roll|expanded}}.<br />
* '''Suppress ToolTips for MacroLinks'''<br />
: MacroLinks normally show tooltips that state information about the link target as an anti-cheating device. When {{Checked}}, these tooltips are disabled.<br />
* '''Typing Notification Duration Seconds'''<br />
: The number of seconds before typing notifications in the top left of the Map View disappear after a player's last keystroke.<br />
* '''Typing Notification Color'''<br />
: Color of the text for typing notifications.<br />
* '''Show Chat Notification Background'''<br />
: When {{Checked}} shows a graphic behind typing notifications. Can be helpful to provide consistently contrasting background for the notifications.<br />
* '''Trusted Prefix Background'''<br />
: Sets a custom background for macro output that comes from a [[Trusted Macro]].<br />
* '''Trusted Prefix Foreground'''<br />
: Sets a custom foreground (text color) for macro output that comes from a [[Trusted Macro]].<br />
<br />
===Macro Editor===<br />
[[Image:Prefs_Interactions_Tab_Macro_Editor.png|frame|right|Macro Editor Section]]<br />
* '''Style Theme'''<br />
: Select from a variety of themes for macro editor windows.<br />
<div style="clear: both"></div><br />
<br />
===Objects===<br />
[[Image:Prefs_Interactions_Tab_Objects.png|frame|right|Objects Section]] <br />
* '''Start Snap to Grid'''<br />
: Tokens created on map's Object layer will automatically be set to '''Snap to Grid''' if this is {{Checked}}. <br />
* '''Start Freesize'''<br />
: Tokens created on a map's Object layer will automatically be set to '''Freesize''' if this is {{Checked}}.<br />
<br />
===Backgrounds===<br />
[[Image:Prefs_Interactions_Tab_Backgrounds.png|frame|right|Backgrounds Section]] <br />
* '''Start Snap to Grid'''<br />
: Images dropped on a map's Background layer will automatically be set to '''Snap to Grid''', if this is {{Checked}}. <br />
* '''Start Freesize'''<br />
: Images dropped on a map's Background layer will automatically be set to '''Freesize''', if this is {{Checked}}.<br />
<br />
===Facing===<br />
[[Image:Prefs_Interactions_Tab_Facing.png|frame|right|Facing Section]] <br />
* '''On Edges'''<br />
: A token's facing will snap to the edges when {{Checked}}. Edges are the lines that make up a grid cell.<br />
* '''On Vertices'''<br />
: A token's facing will snap to the vertices when {{Checked}}. Vertices are the points that connect the lines that make up a grid cell.<br />
<br />
==Accessibility Tab==<br />
[[Image:prefs_tab_accessibility.png|thumb|right|300px|Accessibility Tab on the Preferences Dialog]]<br />
* '''Chat Font Size'''<br />
: The default size of the font in the chat panel; measured in points.<br />
* '''ToolTip Initial Delay'''<br />
: The time it takes for a tooltip to display when hovering the mouse over an element that possesses a tooltip; measured in miliseconds.<br />
* '''ToolTip Dismiss Delay'''<br />
: The time it takes for a tooltip to disappear when hovering the mouse over an element that possesses a tooltip; measured in miliseconds.<br />
<br />
<div style="clear: both"></div><br />
<br />
==Application Tab==<br />
[[Image:prefs_tab_application.png|left|thumb|300px|Application Tab on the Preferences Dialog]]<br />
<div style="clear: both"></div><br />
===Save===<br />
[[Image:prefs_application_save.png|frame|right|Save Section]] <br />
* '''Campaign autosave every [ ] min'''<br />
: Saves an autosave copy of your campaign in the interval specified in <code>%{appHome}/autosave</code>. This will not overwrite your campaign file, but rather create a file which is updated every time it automatically saves. Autosave is only a temporary file, useful in case MapTool crashes. When MapTool is properly closed, the Autosave file is deleted. Note the interval is the time between the last save completing and the start of the next one.<br />
: As a troubleshooting aid, the AutoSaveManager will switch from measuring the autosave interval in minutes to seconds when the [[log.setLevel|log level]] for that package is set to “DEBUG”.<br />
* '''Save reminder on close'''<br />
: Displays a dialog when attempting to close the program with unsaved changes to your campaign when {{Checked}}.<br />
* '''Time between chat log autosaves'''<br />
: The amount of time in minutes between the autosaving of the chat log.<br />
* '''Autosave chat log filename'''<br />
: The filename that will be used when automatically saving your chat log.<br />
* '''File Sync Directory'''<br />
: Specify a path to a local cloud-synced directory to determine relative path external files such as Hero Lab portfolios.<br />
* '''1.3b50 Compatability Mode''' <br />
: <code>This setting has been removed. You can use File > Export Campaign As... to save campaigns for MapTool versions as far back as 1.4.0.</code><br />
: Due to some changes in how certain data is stored in the campaign file in versions after 1.3b50, they might not be compatible with version 1.3b50 and earlier. If this is {{Checked}} your campaign will be saved in the older format, allowing it to be opened in older versions, but losing some of the new features.<br />
<br />
===Map Visuals===<br />
[[Image:Prefs_Application_Tab_Map_Visuals.png|frame|right|Map Visuals Section]] <br />
* '''Halo line width'''<br />
: Controls the width of the [[Halo]] border when it is displayed on a [[Token]].<br />
* '''Use halo color for vision'''<br />
: When this setting is {{Checked}}, hovering over a token with [[Vision]] overlays the token's visible area with the token's [[Halo]] color. This overlay is a translucent layer controlled by the '''Halo opacity''' setting. <br />
* '''Halo opacity'''<br />
: Controls the opacity of the optional overlay enabled by the '''Use halo color for vision''' setting. This does not control the actual [[Halo|Halo's]] outline opacity, which is always completely opaque. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Aura opacity'''<br />
: Controls the opacity of color overlays provided by [[Aura|Auras]] enabled on tokens. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Light opacity'''<br />
: Controls the opacity of color overlays provided by [[Introduction_to_Lights_and_Sights#Light_Sources|Light Sources]] enabled on tokens. This also affects 'personal' lights defined in a token's [[Vision]] setting. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Fog opacity'''<br />
: Controls the opacity of the black layer of 'Soft Fog' that is left in previously explored areas when [[Fog of War]] is enabled. This value can be a number from 0 (transparent) to 255 (opaque).<br />
* '''Auto-expose fog on token movement (GM Only)'''<br />
: Will automatically expose [[Fog of War]] after moving a [[Token]] if {{Checked}}. This setting is intended to help test Fog of War and VBL when not hosting a game. When running a server, this setting is ignored in favor of the settings in the 'Start Server' dialog.<br />
<br />
===Performance===<br />
[[Image:Prefs_Application_Tab_Performance.png|frame|right|Performance Section]]<br />
* '''Fill selection box'''<br />
: When {{Checked}}, the selection box which appears when dragging to select tokens in the Map View will contain a translucent blue fill. Less powerful devices running MapTool may see a small performance gain from unchecking this setting.<br />
* '''Frame Rate Cap''' <code>New in MapTool 1.5.7</code><br />
: Sets the maximum frame rate for the map renderer. Less powerful devices running MapTool may see a performance gain by lowering this setting.<br />
<br />
===Initiative Defaults===<br />
[[Image:Prefs_Application_Tab_Initiative_Defaults.png|frame|right|Initiative Section]]<br />
* '''Hide NPCs from players on new maps'''<br />
: When {{Checked}}, automatically enables 'Hide NPCs' in the [[Initiative Panel]] on new maps. This setting doesn't show connected players [[NPC Tokens]] on the Initiative Panel.<br />
* '''Give Owners Permission in new campaigns'''<br />
: This automatically enables the 'Owner Permissions' setting in the [[Initiative Panel]] on new maps when {{Checked}}. The setting mainly lets players with token ownership add their tokens to or remove their tokens from the initiative list and advance the initiative when it is their token's turn.<br />
* '''Lock Player Movement in new campaigns'''<br />
: When {{Checked}}, new maps will have 'Lock Player Movement' automatically enabled in the [[Initiative Panel]]. This setting prevents players who do not own the token with initiative from moving any tokens.<br />
* '''Show Initiative Gain Message'''<br />
: When initiative advances to a [[PC Token]] token and this is {{Checked}}, a simple 'Token Name has received initiative' message is displayed for all players in chat. This is ignored for [[NPC Token|NPC Tokens]].<br />
<br />
===Client===<br />
[[Image:Prefs_Application_Tab_Client2.png|frame|right|Client Section]]<br />
* '''Fit GM View'''<br />
: When {{Checked}} and the GM uses 'Center Players on Current View', the Map View will zoom out as necessary to accommodate the entire GM view. If unchecked, the zoom level will be set to match the GM's Map View, which will occlude part of the map if your Map View areas are different sizes.<br />
<br />
* '''Default Username'''<br />
: Use to set the Default Username that appears in the MapTool title bar when a personal server is running. Defaults to ''Anonymous User''. (Added MapTool v1.9.0.)<br />
<br />
===Macro Panels===<br />
[[Image:Prefs_Application_Tab_Macro_Panels.png|frame|right|Macro Panels Section]] <br />
* '''Default: Allow Players to Edit Macros'''<br />
: In order for a macro to be considered a [[Trusted Macro]], players must not be able to edit it. This setting determines if a new macro should default to allowing players to edit if {{Checked}}. Disabling this setting can be very useful if you intend to create a lot of macros that you intend to be trusted.<br />
<br />
===UPnP===<br />
[[Image:Prefs_Application_Tab_UPnP.png|frame|right|UPnP Section]]<br />
* '''Discovery Timeout'''<br />
: The timeout period in milliseconds MapTool will wait when searching for UPnP gateways before giving up.<br />
<br />
===Macro Permissions===<br />
[[Image:Prefs_Application_Tab_Macro_Permissions.png|frame|right|Macro Permissions Section]]<br />
* '''Enable External Macro Access'''<br />
: When {{Checked}}, [[Introduction to Macro Writing|Macros]] may call functions that access your drive and http services. Some examples (not a complete list) of functions which will be enabled are [[RESTful Functions Overview|REST Functions]], [[exportData]], and [[getEnvironmentVariable]].<br />
: <br><strong>Note about security:</strong> This option is off by default and exposes you to some risk when enabled. For instance, a malicious macro could communicate with an external server and store data on your local computer. Only enable this option if all the macros and libraries in your campaign files were written by your or directly from authors you trust.<br />
<div style="clear: both"></div><br />
<br />
==Sounds Tab==<br />
[[Image:prefs_tab_sounds.png|thumb|right|300px|Sounds Tab on the Preferences Dialog]]<br />
* '''Play system sounds'''<br />
: When {{Checked}}, MapTool will play a sound when new content is sent to the chat panel.<br />
* '''Play streams'''<br />
: When {{Checked}}, streams started with [[playStream]] will be allowed to play.<br />
* '''Only when window not focused'''<br />
: When {{Checked}}, the sound that MapTool plays when new content is sent to the chat panel will only play if MapTool is not the application that has focus.<br />
* '''Turn on Syrinscape Integration'''<br />
: When clicking <code>syrinscape-fantasy:</code> links in MapTool, the Syrinscape Fantasy Player will be allowed to automatically open when this setting is {{Checked}}. This has no effect on [[Syrinscape Integration]] using the REST API and Online Player.<br />
<br />
==Startup Tab==<br />
[[Image:Prefs_Startup_Tab.png|thumb|300px|frame|left|Startup Tab of Preferences Dialog]]<br />
<div style="clear: both"></div><br />
<br />
===JVM Memory Settings===<br />
[[Image:Prefs_Startup_Tab_JVM_Settings.png|frame|right|JVM Memory Section]]<br />
These preferences are somewhat advanced. To better understand how MapTool uses memory settings, read about [[Stack Size]]. If you are having Stack Overflow errors and need to modify these settings for more reliable performance, read about [[Avoiding Stack Overflow]]. If you need help resetting MapTool memory settings, check out [https://www.rptools.net/2019/04/resetting-maptool/ Resetting MapTool JVM Settings] on the RPTools blog.<br />
<br />
<div class="template_clarify" style="border: solid red 2px; background-color: lightgrey; padding: 5px"><br />
The packaging tool provided with Java 14+ has eliminated our ability to have MapTool configure its memory settings for you. For the time being, these options are greyed out and the user must edit the configuration file directly using a normal text editor. This text is taken from a Discord post by Phergus and replicated [https://forums.rptools.net/viewtopic.php?f=1&t=29087&p=278171#p277802| on our forum]. This is not likely to change until Java 17 is released at the earliest, and possibly later if the Java developers don't correct it by then.<br />
<br />
'''Startup Config for MT 1.8.x'''<br/><br />
Locate and edit the {{code|maptool.cfg}} file under the application folder in your MapTool install directory. In most cases, you shouldn't need to change ANY of them, excepting {{code|user.language}} for those in different locales.<br />
<br />
Under {{code|[JavaOptions]}} you can add/set the following (example values are shown):<br />
: {{code|-Xmx4G}} - set max heap to 4G<br />
: {{code|-Xms1G}} - set min heap to 1G<br />
: {{code|-Xss10M}} - set stack size to 10M<br />
: {{code|-Dsun.java2d.d3d{{=}}false}} - disabled Direct3D<br />
: {{code|-Dsun.java2d.opengl{{=}}true}} - enable OpenGL <br />
: {{code|-Djavafx.macosx.embedded{{=}}false}} - initialize AWT before JFX (MacOS only)<br />
: {{code|-Duser.language{{=}}en}} - set MT local to English<br />
: {{code|-Dawt.useSystemAAFontSettings{{=}}on}} - turn on text antialiasing (for Linux)<br />
'''Startup Config for MT 1.9.x'''<br/><br />
The format changed slightly for MT 1.9.x. Each line should now start with {{code|java-options{{=}}}} and then the options listed for MT 1.8.x.<br />
</div><br />
These three settings are memory sizes in bytes. The letter at the end can be K, M, or G signifying Kilobytes, Megabytes, or Gigabytes. Changes to these settings take effect upon restarting MapTool.<br />
<br />
* '''Maximum heap size (-Xmx)'''<br />
: The maximum amount of total memory (RAM) MapTool can use at once, usually entered in Gigabytes (G). For heavy frameworks with many assets, you may have to raise this value. 4G is a generous default value for nearly all users with at least 8GB of RAM.<br />
* '''Initial & minimum heap size (-Xms)'''<br />
: The minimum amount of memory (RAM) which MapTool will always reserve for use, usually entered in Gigabytes (G). Oracle recommends this setting be the same as the Maximum heap size. Doing so may provide performance gains by reducing garbage collection operations. This value should not be higher than the Maximum heap size.<br />
* '''Thread stack size (-Xss)'''<br />
: The memory each particular Java thread has reserved for its use, usually entered in Megabytes (M). Raising this value may allow more complex macros to be run, but it should generally be kept as low as possible. 4M is a generous default value that allows most macros to work just fine. To help understand this value, a simple campaign using short macros or no macros may be able to run successfully with a value as low as 256K, while a campaign containing extremely large macros may need 5M or 6M to avoid stack overflow.<br />
<br />
===Advanced Options===<br />
[[Image:Prefs_Startup_Tab_Advanced_Options.png|frame|right|Advanced Options Section]]<br />
These options are used for development and troubleshooting. Changes to these settings take effect upon restarting MapTool.<br />
<br />
* '''Enable assertions'''<br />
: Developers often test MapTool with this option {{Checked}} to enable additional Java checks so they can find additional warnings or errors. This setting is not recommended for normal users as it lowers performance.<br />
* '''Disable Direct3d Pipeline'''<br />
: When {{Checked}}, MapTool will not use Direct3D. This is mainly used by developers, but if you are having visual issues you can try using this setting to see if your problem is resolved. If so, it may indicate you need new drivers from your video card manufacturer.<br />
* '''Enable OpenGL Pipeline'''<br />
: This option may help resolve visual issues when {{Checked}} by enabling OpenGL rendering. You do not need to check 'Disable Direct3d Pipeline' in order to use this setting.<br />
* '''Initialize AWT before JavaFX'''<br />
: Developers can use this.<br />
<br />
===Language Override===<br />
[[Image:Prefs_Startup_Tab_Language_Override.png|frame|right|Language Override Section]]<br />
* '''Language'''<br />
: Select the user interface language for MapTool. Changes to this setting take effect upon restarting MapTool.<br />
<br />
===Additional Options===<br />
[[Image:Prefs_Startup_Tab_Additional_Options.png|frame|right|Additional Options Section]]<br />
* '''Data Directory'''<br />
: The local directory where MapTool saves asset cache data, autosaves, backups, configuration files, and more. Changes to this setting take effect upon restarting MapTool.<br />
<br />
[[Category:MapTool]]</div>Melekhttps://wiki.rptools.info/index.php?title=getSightType&diff=11545getSightType2021-09-10T22:11:43Z<p>Melek: Correcting usage</p>
<hr />
<div>{{MacroFunction<br />
|name=getSightType<br />
|version=1.3b48<br />
|description=<br />
Returns the type of [[Token:sight|sight]] that the [[Current Token]] has. When no sight type is set, returns an empty string.<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
getSightType()<br />
getSightType(id)<br />
getSightType(id, mapname)<br />
</source><br />
<br />
'''Parameters'''<br />
{{param|id|The {{code|id}} of the token to have the [[State]] set. Defaults to the [[Current Token]]. {{TrustedParameter}} }}<br />
{{param|mapname|The name of the map to find the token. Defaults to the current map.}}<br />
<br />
|changes=<br />
{{change|1.7.0|Now returns an empty string when no sight type is set.}}<br />
{{change|1.5.4|Added {{code|id}} and {{code|mapname}} parameter options.}}<br />
<br />
}}<br />
[[Category:Sight Function]]<br />
[[Category:Token Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=execLink&diff=11540execLink2021-08-28T12:22:27Z<p>Melek: Add notes on deferrals.</p>
<hr />
<div>{{MacroFunction<br />
|name=execLink<br />
|version=1.3b55<br />
|trusted=true<br />
|description=<br />
Executes a macro link that was created with {{func|macroLinkText}}, output generated by the link is sent to players using the standard {{func|macroLinkText}} logic. {{func|execLink}} allows you to defer the running of the link until after the currently running macro has ended in which case the output will be displayed after any output generated by the current macro. If you defer a series of links, they will be queued in order and executed after the currently running macro. There is no software limit to the amount of links you can queue, but your hardware will impose its own limitations. If the execution of the link is not defered then any output generated will appear ''before'' any output generated by the current macro. <br />
<br />
You can use this function to update values in a token copied with {{func|copyToken}} using the defered option. You can also use this function to send output selectivly to a list of players from the current macro, or to generate output that is not suppressed when the {{func|abort}} function is called.<br />
<br />
|usage=<br />
<br />
<source lang="mtmacro" line><br />
execLink(link)<br />
execLink(link, defer)<br />
execLink(link, defer, targets)<br />
execLink(link, defer, targets, delim)<br />
</source><br />
'''Parameters'''<br />
{{param|link|The link to "execute".}}<br />
{{param|defer|Executes the link after the current macro has completed if non zero, defaults to zero.}}<br />
{{param|targets|are the user names (so not token names) but the names of the users that are logged in. The options "gm", "gm-self", "self", "not-self", "not-gm", "not-gm-self", "none", and "all" are also valid parameters to give. E.g.: "tim, tom, tarra". Defaults to self (so if no parameter is given the link is executed locally only). Here is a summary of the valid values:<br />
::: '''''Player name''''': The named player.<br />
::: '''self''': Self only (default, link is only executed locally).<br />
::: '''gm''': GM only.<br />
::: '''gm-self''': Both the GM and self.<br />
::: '''all''': All connected players and GMs.<br />
::: '''not-self''': Anyone but self.<br />
::: '''not-gm''': All non-GMs.<br />
::: '''not-gm-self''': All players apart from the GM and self.<br />
::: '''none''': No players. No GMs.}}<br />
{{param|delim|The delimiter used to separate the values in the String List that is given, defaults to {{code|","}}. If {{code|"json"}} is specified, a JSON array is expected instead of a String List.}}<br />
<br />
<br />
|examples=<br />
Execute a macro link immediately (any output will appear before the current macros output)<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("Test@Lib:Test", "self")]<br />
[h: execLink(link)]<br />
</source><br />
<br />
Execute a macro link after the execution of the current macro (any output will appear before the current macros output)<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("Test@Lib:Test", "self")]<br />
[h: execLink(link, 1)]<br />
</source><br />
<br />
Copy a token and update its values.<br />
<source lang="mtmacro" line><br />
[h: newToken = copyToken("Hero")]<br />
[h: link = macroLinkText("update@Lib:GM", "none", "", newToken)]<br />
[h: execLink(link)]<br />
</source><br />
<br />
Execute a macro link on all clients<br />
<source lang="mtmacro" line><br />
[h: link = macroLinkText("Test@Lib:Test", "none")]<br />
[h: execLink(link, 0, "all")]<br />
</source><br />
<br />
|changes=<br />
{{change|1.5.5|Added the {{code|targets}} and {{code|delim}} parameters.}}<br />
{{change|1.5.7|Added "not-self", "not-gm" and "not-gm-self" as valid targets.}}<br />
<br />
|also=<br />
{{func|macroLinkText}} {{func|macroLink}} {{func|copyToken}}<br />
<br />
}}<br />
===Notes===<br />
Deferred functions/links which are queued within a deferred macro do not run directly after the queuing macro, but instead is added to the end of the stack of all the deferred functions and links. This means you cannot 'nest' deferrals or insert deferrals in the middle of the stack of deferred macros. For discussion of this functionality and possible workarounds you can [https://github.com/RPTools/maptool/issues/2633 read more on GitHub].<br />
[[Category:Miscellaneous Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=execFunction&diff=11539execFunction2021-08-28T12:21:17Z<p>Melek: Add note about deferral behavior.</p>
<hr />
<div>{{MacroFunction<br />
|name=execFunction<br />
|version=1.5.7<br />
|trusted=true<br />
|description=<br />
Executes a built-in macro function or user-defined function (UDF) on one or more clients. No output from the executed function will be presented on the targets. {{func|execFunction}} allows you to defer the running of the function until after the currently running macro has ended. If you defer a series of {{func|execFunction}} calls, they will be queued in order and executed after the currently running macro.<br />
|usage=<br />
<br />
<source lang="mtmacro" line><br />
execFunction(functionName, arguments)<br />
execFunction(functionName, arguments, defer)<br />
execFunction(functionName, arguments, defer, targets)<br />
execFunction(functionName, arguments, defer, targets, delim)<br />
</source><br />
'''Parameters'''<br />
{{param|functionName|The function to "execute".}}<br />
{{param|arguments|A JSON array of arguments for the function.}}<br />
{{param|defer|Executes the function after the current macro has completed if non zero, defaults to zero.}}<br />
{{param|targets|are the user names (so not token names) but the names of the users that are logged in. The options "gm", "gm-self", "self", "not-self", "not-gm", "not-gm-self", "none", and "all" are also valid parameters to give. E.g.: "tim, tom, tarra". Defaults to self (so if no parameter is given the function is executed locally only).}}<br />
{{param|delim|The delimiter used to separate the values in the String List that is given, defaults to {{code|","}}. If {{code|"json"}} is specified, a JSON array is expected instead of a String List.}}<br />
<br />
|example=<br />
To run a song on every client, the GM can use<br />
<br />
<source lang="mtmacro" line><br />
[h: song = "https://ia800300.us.archive.org/29/items/Muzyka-CC/Aleksand_Sjakin_-_Flight_in_space.mp3"]<br />
[h: execFunction("playStream", json.append("[]", song, 1, 0.8), 0, "all")]<br />
</source><br />
<br />
|also=<br />
{{func|macroLinkText}} {{func|macroLink}}<br />
<br />
}}<br />
===Notes===<br />
Deferred functions/links which are queued within a deferred macro do not run directly after the queuing macro, but instead is added to the end of the stack of all the deferred functions and links. This means you cannot 'nest' deferrals or insert deferrals in the middle of the stack of deferred macros. For discussion of this functionality and possible workarounds you can [https://github.com/RPTools/maptool/issues/2633 read more on GitHub].<br />
[[Category:Miscellaneous Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=moveTokenFromMap&diff=11532moveTokenFromMap2021-08-20T00:38:44Z<p>Melek: Add to Map Function category</p>
<hr />
<div>{{stub|Examples of usage, and clearer description.}}<br />
{{MacroFunction<br />
|name=moveTokenFrom<br />
|trusted=true<br />
|version=1.3b54<br />
|description=<br />
Moves tokens from a specified map to the current map.<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
moveTokenFromMap(id, map)<br />
moveTokenFromMap(id, map, x)<br />
moveTokenFromMap(id, map, x, y)<br />
moveTokenFromMap(id, map, x, y, z)<br />
</source><br />
'''Parameters'''<br />
{{param|id|The token {{code|id}} or a [[JSON Array]] of token {{code|id}}s of the token/s to move.}}<br />
{{param|map|A string containing the name of the map that the token is moved from.}}<br />
{{param|x|The {{code|X}} coordinate of the current map that the token should be moved to. Defaults to 0.}}<br />
{{param|y|The {{code|Y}} coordinate of the current map that the token should be moved to. Defaults to 0.}}<br />
{{param|z|The z-order that the token should have after being moved. Defaults to the largest of the map.}}<br />
<br />
|also=<br />
{{func|moveTokenToMap}}<br />
<br />
}}<br />
[[Category:Token Function]][[Category:Map Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=moveToken&diff=11531moveToken2021-08-20T00:38:19Z<p>Melek: Add 'See Also' bullets from moveTokenTo/FromMap</p>
<hr />
<div>{{MacroFunction<br />
|name=moveToken<br />
|version=1.3b51<br />
|description=<br />
Move a token to a new location.<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
moveToken(x, y)<br />
moveToken(x, y, units)<br />
moveToken(x, y, units, id)<br />
</source><br />
'''Parameters'''<br />
* {{code|x}} - The X coordinate to move the token to.<br />
* {{code|y}} - The Y coordinate to move the token to.<br />
* {{code|units}} - If set to {{false}}, the coordinates are a location on the grid in '''cells'''. Defaults to {{true}}, where the coordinates are in ''Distance Per Cell'' '''pixels'''.<br />
* {{code|id}} - The id [[Macros:Variables:string|string]] of the token to move, defaults to the [[Current Token]].{{TrustedParameter}}<br />
&nbsp;<br />
<!-- The 'nbsp' is needed to close the DIV --><br />
|examples=<br />
Moves the [[Current Token]] down {{code|5}} '''units''', and left {{code|10}} '''units'''.<br />
<source lang="mtmacro" line><br />
[h: CurrentX = getTokenX()]<br />
[h: CurrentY = getTokenY()]<br />
[h: NewX = CurrentX + 5]<br />
[h: NewY = CurrentY - 10]<br />
[h: moveToken(NewX, NewY)]<br />
</source><br />
<br />
Moves the [[Current Token]] down {{code|5}} '''cells''', and left {{code|10}} '''cells'''.<br />
<source lang="mtmacro" line><br />
[h: CurrentX = getTokenX(0)]<br />
[h: CurrentY = getTokenY(0)]<br />
[h: NewX = CurrentX + 5]<br />
[h: NewY = CurrentY - 10]<br />
[h: moveToken(NewX, NewY, 0)]<br />
</source><br />
<br />
|also=<br />
{{func|getTokenX}}, <br />
{{func|getTokenY}},<br />
{{func|moveTokenToMap}},<br />
{{func|moveTokenFromMap}}<br />
<br />
}}<br />
[[Category:Token Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=moveTokenToMap&diff=11530moveTokenToMap2021-08-20T00:37:29Z<p>Melek: Add to Map Function category</p>
<hr />
<div>{{stub|Examples of usage, and clearer description.}}<br />
{{MacroFunction<br />
|name=moveTokenToMap<br />
|trusted=true<br />
|version=1.3b54<br />
|description=<br />
Moves tokens from the current map to a specified map.<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
moveTokenToMap(id, map)<br />
moveTokenToMap(id, map, x)<br />
moveTokenToMap(id, map, x, y)<br />
moveTokenToMap(id, map, x, y, z)<br />
</source><br />
'''Parameters'''<br />
{{param|id|The token {{code|id}} or a [[JSON Array]] of token {{code|id}}s of the token/s to move.}}<br />
{{param|map|A string containing the name of the map that the token is moved to.}}<br />
{{param|x|The {{code|X}} coordinate of the map that the token should be moved to. Default to 0.}}<br />
{{param|y|The {{code|Y}} coordinate of the map that the token should be moved to. Default to 0.}}<br />
{{param|z|The z-order that the token should have after being moved. Defaults to the largest of the map.}}<br />
<br />
|also=<br />
{{func|moveTokenFromMap}}<br />
<br />
}}<br />
[[Category:Token Function]][[Category:Map Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=getTokenMap&diff=11529getTokenMap2021-08-20T00:26:54Z<p>Melek: Add to 'Map' category.</p>
<hr />
<div>{{MacroFunction<br />
|name=getTokenMap<br />
|version=1.5.11<br />
|description=<br />
Gets the list of map(s) where a token resides. The list is returned either as a string list, or as a [[JSON Array]].<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
getTokenMap(name/ID)<br />
getTokenMap(name/ID, delim)<br />
</source><br />
'''Parameters'''<br />
'''Parameters'''<br />
{{param|name/ID|Either the name of the token or the ID.}}<br />
{{param|delim|The delimiter used in the string list returned, defaults to {{code|","}}. If set to {{code|json}}, then a JSON array is returned.}}<br />
<br />
|example=<br />
Suppose a token named "Dragon" is on two maps, "Grasslands" and "Arid". The command<br />
<source lang="mtmacro" line><br />
[r: getTokenMap("Dragon", "json")]<br />
</source><br />
returns the JSON Array:<br />
<source lang="mtmacro" line><br />
["Grasslands","Arid"]<br />
</source><br />
}}<br />
[[Category:Token Function]]<br />
[[Category:Map Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=MapToolOS&diff=11526MapToolOS2021-08-16T16:58:42Z<p>Melek: /* MapToolOS */ Added Discord template link and updated <code> blocks to use <pre></p>
<hr />
<div>=MapToolOS=<br />
Ready to use Linux images preconfigured to run MapTool.<br />
<br />
These are community maintained images, designed to get up and running with maptool quickly, and uniformly. For support, come ask in {{Discord}}.<br />
<br />
==Installation==<br />
Download the disk image file for the image you want to run. It can be extracted via 7zip or similar unarchiving tool. If you are going to run it via a Virtual Machine (VM), just point your VM software at the extracted disk image, and select the correct boot type (UEFI vs legacy). To run from a USB drive, a tool like balenaEtcher can write the image to a drive. Minimum drive sizes, CPU type, and other requirements are listed in each image's section. <br />
<br />
'''Flashing an image file to a USB drive (or other drive) will erase and reformat the drive!'''<br />
<br />
==GenTool==<br />
[https://scratch.lp-programming.com/maptool.img.xz GenTool.img.xz]<br />
<br />
Based on Gentoo Linux, this boots to a KDE/plasma or XFCE desktop, with a fairly comprehensive list of installed utilities (the core KDE meta packages). <br />
<br />
===Requirements===<br />
* 4GB or larger drive (16GB recommended)<br />
* 1 GB RAM (2GB strongly recommended)<br />
* x86_64 CPU with AVX2 (Intel Haswell or newer, or AMD Excavator or newer)<br />
* UEFI based boot<br />
<br />
If it fails to boot to GRUB, verify your bios is set to boot either to UEFI or UEFI+legacy.<br />
<br />
===Notes===<br />
* New binary package updates roughly weekly<br />
* Username: maptool<br />
* P: maptool@maptool<br />
* Root: root@maptool<br />
<br />
If you want to use the whole area of a larger-than-4gb flash drive, there are two steps. <br />
First, use parted to change the second partition to use the whole drive. (You will need to determine which drive is your root drive, which you can do by running <code>mount | grep btrfs</code>. Look for the entry mounted on <code>/</code>. If that reads <code>/dev/sda2</code> than your root device is <code>/dev/sda</code><br />
<br />
<pre><br />
su -c "parted /dev/$root"<br />
resizepart 2 100%<br />
q<br />
</pre><br />
<br />
Then reboot. The second step requires resizing the live btrfs filesystem. <br />
<br />
<pre><br />
btrfs filesyste resize max /<br />
</pre> <br />
<br />
This does not require a reboot.<br />
<br />
<br />
Updating the installed image will require a larger disk (8GB minimum), and rolling back some space saving USE flags. The basic sequence to update packages is as follow.<br />
<br />
<pre><br />
eix-sync && emerge --update -avbkg1 --deep --newuse --with-bdeps=y --usepkgonly --autounmask @world<br />
</pre><br />
<br />
It will offer to make some mask or USE changes. Hit yes, then run<br />
<br />
<pre><br />
dispatch-conf<br />
</pre><br />
<br />
to review the changes. Y will accept the changes, then re-run the first command.<br />
<br />
==GenTool - Minimal==<br />
[https://scratch.lp-programming.com/maptool-stripped.img.xz GenTool-min.img.xz]<br />
<br />
[https://scratch.lp-programming.com/maptool-overlay.img.xz GenTool-overlay.img.xz]<br />
<br />
Based on GenTool, with fewer packages, and with some core files removed. Same requirements as GenTool, except it will fit on a 2GB drive, and is half the download size. Due to the removed files, updating this image is not supported, and some normal Linux features may behave oddly (or be missing). It is possible to convert it to a normal image, by downloading the second file, mounting it under linux, and copying the files to the root partition (<code>cp -ra $mount_point/* /</code>).</div>Melekhttps://wiki.rptools.info/index.php?title=Template:Discord&diff=11525Template:Discord2021-08-16T16:56:49Z<p>Melek: /* Source */ Correct MW formatting</p>
<hr />
<div><noinclude><br />
=Template Usage=<br />
This template is a simple link to the MapTool discord. A template is preferred because a Discord link may change.<br />
<br />
==Examples==<br />
The default usage uses 'Discord' as the link text:<br />
<pre>{{Discord}}</pre><br />
<br />
Adding further text after the template name replaces the link text:<br />
<pre>{{Discord|the MapTool Discord channel}}</pre><br />
<br />
=Source=<br />
Edit this section to view template source.<br />
</noinclude><includeonly>[https://discord.gg/hbn2bfn {{{1|Discord}}}]</includeonly><noinclude>[[Category:Templates]]</noinclude></div>Melekhttps://wiki.rptools.info/index.php?title=Template:Discord&diff=11524Template:Discord2021-08-16T16:56:25Z<p>Melek: /* Source */ Update link from HTML to MW</p>
<hr />
<div><noinclude><br />
=Template Usage=<br />
This template is a simple link to the MapTool discord. A template is preferred because a Discord link may change.<br />
<br />
==Examples==<br />
The default usage uses 'Discord' as the link text:<br />
<pre>{{Discord}}</pre><br />
<br />
Adding further text after the template name replaces the link text:<br />
<pre>{{Discord|the MapTool Discord channel}}</pre><br />
<br />
=Source=<br />
Edit this section to view template source.<br />
</noinclude><includeonly>[[https://discord.gg/hbn2bfn {{{1|Discord}}}]]</includeonly><noinclude>[[Category:Templates]]</noinclude></div>Melekhttps://wiki.rptools.info/index.php?title=Template:Discord&diff=11523Template:Discord2021-08-16T16:55:00Z<p>Melek: /* Template Usage */ Update example</p>
<hr />
<div><noinclude><br />
=Template Usage=<br />
This template is a simple link to the MapTool discord. A template is preferred because a Discord link may change.<br />
<br />
==Examples==<br />
The default usage uses 'Discord' as the link text:<br />
<pre>{{Discord}}</pre><br />
<br />
Adding further text after the template name replaces the link text:<br />
<pre>{{Discord|the MapTool Discord channel}}</pre><br />
<br />
=Source=<br />
Edit this section to view template source.<br />
</noinclude><includeonly><a href="https://discord.gg/hbn2bfn" target="_blank">{{{1|Discord}}}</a></includeonly><noinclude>[[Category:Templates]]</noinclude></div>Melekhttps://wiki.rptools.info/index.php?title=Template:Discord&diff=11522Template:Discord2021-08-16T16:54:41Z<p>Melek: /* Source */ Change the default usage to output 'Discord' to make grammar simpler.</p>
<hr />
<div><noinclude><br />
=Template Usage=<br />
This template is a simple link to the MapTool discord. A template is preferred because a Discord link may change.<br />
<br />
==Examples==<br />
The default usage uses 'MapTool Discord' as the link text:<br />
<pre>{{Discord}}</pre><br />
<br />
Adding further text after the template name replaces the link text:<br />
<pre>{{Discord|the Discord channel}}</pre><br />
<br />
=Source=<br />
Edit this section to view template source.<br />
</noinclude><includeonly><a href="https://discord.gg/hbn2bfn" target="_blank">{{{1|Discord}}}</a></includeonly><noinclude>[[Category:Templates]]</noinclude></div>Melekhttps://wiki.rptools.info/index.php?title=Template:Discord&diff=11521Template:Discord2021-08-16T16:53:08Z<p>Melek: Add Discord template to make updating Discord links easier in the future</p>
<hr />
<div><noinclude><br />
=Template Usage=<br />
This template is a simple link to the MapTool discord. A template is preferred because a Discord link may change.<br />
<br />
==Examples==<br />
The default usage uses 'MapTool Discord' as the link text:<br />
<pre>{{Discord}}</pre><br />
<br />
Adding further text after the template name replaces the link text:<br />
<pre>{{Discord|the Discord channel}}</pre><br />
<br />
=Source=<br />
Edit this section to view template source.<br />
</noinclude><includeonly><a href="https://discord.gg/hbn2bfn" target="_blank">{{{1|MapTool Discord}}}</a></includeonly><noinclude>[[Category:Templates]]</noinclude></div>Melekhttps://wiki.rptools.info/index.php?title=lib:Elevation_Manual&diff=11494lib:Elevation Manual2021-08-06T14:48:56Z<p>Melek: Major documentation update for 1.0a5</p>
<hr />
<div>[[File:lib_elevation.png|thumb|Lib:Elevation tries to fit into the MapTool UI to add accessible elevation tools for map-making.]]<br />
<h1>Welcome to Lib:Elevation!</h1><br />
<h2>Quick Links</h2><br />
<ul><br />
<li><strong>[https://github.com/melek/lib_elevation Download Lib:Elevation from GitHub]</strong></li><br />
<li>[https://forums.rptools.net/viewtopic.php?f=8&t=29234 View the RPTools Forum Post]</li><br />
<li>Ask questions and discuss in the [https://discord.gg/hbn2bfn MapTool Discord] in the #map-drawing-tools channel</li><br />
</ul><br />
<h2>Introduction</h2><br />
<p>This library adds an elevation feature to MapTool, allowing you to <strong>set Visual and Movement blocking layers based on elevation</strong> and <strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p><br />
<p>Here are some ideas on how to use this feature:</p><br />
<ul><br />
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations. </li><br />
<li>Remove vision entirely to simulate flying or scrying.</li><br />
<li>Change the background map at different elevations for a truly &#39;vertical&#39; feeling, such as flying islands or tall, fog-filled canyons.</li><br />
</ul><br />
<h2 id="terminology">Terminology</h2><br />
<p>There are a few concepts in Lib:Elevation that have special names that knowing up front can help you get to using the library quickly. </p><br />
<p>Some of the terms are similar to other MapTool terms like layer and token, so to (hopefully) reduce confusion, <br />
<strong>Elevations</strong> are sets</p><br />
<ul><br />
<li><strong>Token Elevation</strong>, or the elevation token property, is the vertical position of a token - how far up or down it is relative to other tokens. This is usually stored on the token as &#39;Elevaton&#39; (that is the MapTool default), and by itself is just a handy reference for players and GMs to know how high or low a token is on the map.</li><br />
<li><strong>Map Elevations</strong>, defined elevations, or simply elevations, are sets of data - a label, blocking layers, and linked tokens - which is shown at a particular elevation on the map. For example, a map of a maze might have &#39;Elevation 0&#39; labelled as &#39;Ground Level&#39; and block movement and sight the walls, while Elevation 20 might be labelled &#39;Flying&#39; and allow free vision and movement across the whole map. When I use the word &#39;Elevation&#39;, these special, defined elevations are usually what I mean, rather than the token property. Sometimes I may refer to elevations as &#39;layers&#39; or &#39;elevation layers&#39;, but I try to reserve that term specifically for the VBL/MBL associated with an elevation.</li><br />
<li><strong>Current Map Elevation</strong>, current elevation, or active elevation is the map elevation being displayed. Only one elevation is visible at a time for all players. Switching elevations means changing the current map elevation, which literally &#39;switches out&#39; which elevation you are playing on/editing. </li><br />
<li><strong>Faded tokens</strong> are tokens on a defined map elevation above or below the current elevation on the Token layer. These tokens will appear &#39;faded&#39; with lower opacity and placed behind tokens on the active elevation, and when they are defined will have the <code>isAbove</code> or <code>isBelow</code> state applied to it.</li><br />
<li><strong>Elevation Linked Tokens</strong> or <strong>Elevation Tokens</strong> refers to tokens which have their positions &#39;linked&#39; to a particular map elevation. These let you do thing slike switch the background map token, only show an NPC when they are at the same elevation as the player, hide door tokens so they don&#39;t appear at the wrong elevations. If the state is defined, these tokens will have a GM-only <code>isElevationToken</code> state applied to them to make them easier to spot for the GM.</li><br />
</ul><br />
<h2 id="campaign-setup">Campaign Setup</h2><br />
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p><br />
<ul><br />
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong> for quick access. The overlay UI has most of these options, but it is nice to have the buttons handy - especially in case the overlay has to be shut off for some reason. Exporting then importing these macro groups is a quick way to do this.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for &#39;*Elevation&#39;. This is a default MapTool property. If you&#39;d like to use a different property name for elevation in your campaign, you can change it in the <code>getElevationPropName</code> function.</li><br />
<li><strong>Add elevation token states in Campaign Properties</strong>, which will be used to show when a token is at an elevation above or below the current map elevation. Add two states: <code>isAbove</code> to mark tokens on a higher defined map elevation level, and <code>isBelow</code> for tokens below the current map elevation level. Here are recommended settings for these states:<ul><br />
<li>Choose the 2x2 Grid shapes at 50% opacity </li><br />
<li>Use &#39;Yield&#39; (down arrow) for <code>isBelow</code></li><br />
<li>User &#39;Triangle&#39; (up arrow) for <code>isAbove</code></li><br />
<li>Tokens will also appear faded when not on the current elevation.</li><br />
</ul><br />
</li><br />
<li><strong>Add a GM-only state to help manage Elevation Linked Tokens</strong> such as doors, background maps, etc.. Add one state: <code>isElevationToken</code> with the following state properties:<ul><br />
<li>Choose the &#39;Shaded&#39; type state set to a bright color and 25% opacity.</li><br />
<li>Check the &#39;GM Only&#39; option.</li><br />
<li>Check the &#39;Mouseover&#39; option.</li><br />
<li>You will learn more about why this state is helpful and what these linked &#39;Elevation Tokens&#39; are for.</li><br />
</ul><br />
</li><br />
</ul><br />
<h2 id="usage">Usage</h2><br />
<p>Lib:Elevation works by saving each elevation as a set of blocking layers (VBL and MBL) for the map, along with a list of any linked tokens which will be hidden when a different elevation is loaded. Changing between elevations swaps out which blocking layers are active and which elevation tokens are visible.</p><br />
<p>By default, new maps have no defined elevations and won&#39;t show the elevation list overlay for the GM. These maps are considered to be at elevation zero. You can add an elevation with the <code>Add Elev</code> button.</p><br />
<p>Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations. <strong>Changing elevations affects all connected players</strong>, unlike maps which the GM can freely preview privately without impacting which map a given player is on. If you want to check elevations on a map, it is recommended to keep the map hidden from players until you are ready for them to play on it.</p><br />
<p>When you switch between elevations, your changes to VBL/MBL and any elevation linked tokens will be saved. Then, VBL/MBL will be cleared, elevation tokens will be hidden, and the elevation you are switching to will be loaded onto the map.</p><br />
<p>Switching elevations is done manually, or when Initiative is active, when a token takes initiative. You can also use the <code>T↑↓</code> button to match the current elevation to the selected token&#39;s elevation property.</p><br />
<h3 id="elevation-management-buttons">Elevation Management Buttons</h3><br />
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown: </p><br />
<ul><br />
<li><code>Add Elev</code> will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like a background map token.</li><br />
<li><code>↑↑↑</code>, <code>↓↓↓</code>, and <code>↑↓</code> switches the map elevation up, down, or to a map elevation you choose.</li><br />
<li><code>T↑↓</code> button switches the map elevation to match the selected token&#39;s elevation property, rounded down to the nearest defined elevation. If a token&#39;s elevation is below the lowest defined elevation, it will default to the lowest available defined map elevation.</li><br />
<li><code>Link Tokens</code> links the selected token to an elevation you select. You can use <code>Unlink Tokns</code> to undo this, or <code>Select Tokens</code> to select all the current map elevation&#39;s linked tokens. These options are mostly for setting maps up, but you might unlink/link a token during play if moving NPCs between levels in a house, for instance.</li><br />
</ul><br />
<h3 id="token-management-buttons">Token Management Buttons</h3><br />
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect. </p><br />
<p>Please note that using these buttons usually also switches to the new elevation. </p><br />
<h2 id="limitations">Limitations</h2><br />
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p><br />
<ul><br />
<li>Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.</li><br />
<li>While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.</li><br />
</ul><br />
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p><br />
<h2 id="developer-notes">Developer notes</h2><br />
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to &#39;fill&#39; the vertical space until the next elevation.</p><br />
<p>Here are outlines the data structures and basic mechanism behind the library. </p><br />
<h3 id="library-properties">Library Properties</h3><br />
<p>The library itself contains no properties by default. There is a library options system which lets you set library-wide options, but that feature is not currently in use. Future versions may use these options as a fallback for undefined map-level options.</p><br />
<p><em>Note that versions 1.0a4 and lower stored all elevation data on the library token, using map IDs as keys. This was not import/export friendly and was replaced with library reference objects stored on automatically created map elevation data tokens.</em></p><br />
<h3 id="map-data-token-properties">Map Data Token properties</h3><br />
<p>On nearly any elevation operation, a &#39;Map Elevation Data&#39; token will be automatically created and populated with library reference data. All elevation related data on the map is stored on this token. <strong>If you delete the Map Elevation Data token, you will lose all your elevation data for the map.</strong></p><br />
<p>Using a token in this manner allows maps to be exported and imported to other campaigns using a sufficient version of Lib:Elevation.</p><br />
<table><br />
<br />
<tr><br />
<th>Property</th><br />
<th>Type</th><br />
<th>Purpose </th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>libRefData.elevation.version</td><br />
<td>String</td><br />
<td>The version of Lib:Elevation which created the data token.</td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.options</td><br />
<td>JSON Object</td><br />
<td>Option names are paired with their values. If they don&#39;t exist, they are presumed to be 0. </td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.current</td><br />
<td>String (Integer)</td><br />
<td>The current elevation. This value is set when saving an elevation or loading an elevation, which happens whenever the elevation is switched with a UI macro. Essentially, this is almost always the &#39;display&#39; elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td><br />
</tr><br />
<tr><br />
<td>libRefData.elevation.layers</td><br />
<td>JSON Object</td><br />
<td>Integer IDs representing an elevation are keys for JSON objects containing elevation data. This data structure is described below.</td><br />
</tr><br />
<br />
</table><br />
<h3 id="data-structures">Data Structures</h3><br />
<p>Note that Lib:Elevation uses Map Data Tokens stored on each map; this means that the library is loosely coupled with a campaign, and maps can be freely exported. Token IDs should stay constant on map import, so token names and exports/imports shouldn&#39;t compromise elevation data.</p><br />
<h4 id="-librefdata-elevation-layers-"><code>libRefData.elevation.layers</code></h4><br />
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called &#39;Map Elevation Objects&#39;. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p><br />
<table><br />
<br />
<tr><br />
<th>Key</th><br />
<th>Type</th><br />
<th>Purpose </th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>label</td><br />
<td>String</td><br />
<td>A display name for the elevation. Defined elevations don&#39;t require names.</td><br />
</tr><br />
<tr><br />
<td>vbl</td><br />
<td>JSON Array</td><br />
<td>VBL is a shape object array as returned by <code>getVBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>mbl</td><br />
<td>JSON Array</td><br />
<td>MBL is a shape object array as returned by <code>getMBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>tokens</td><br />
<td>JSON Object</td><br />
<td>Token ID keys containing <b>token appearance</b> objects. Token appearance is described below.</td><br />
</tr><br />
<br />
</table><br />
<h4 id="token-appearance-objects">Token appearance objects</h4><br />
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in <code>getTokenAppearance()</code> and <code>setTokenAppearance()</code>. The token appearance JSON Object includes the following keys and the associated token data:</p><br />
<table><br />
<br />
<tr><br />
<th>Key</th><br />
<th>Data function</th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>ID</td><br />
<td>Same as Field ID</td><br />
</tr><br />
<tr><br />
<td>Layer</td><br />
<td><code>getLayer(ID)</code></td><br />
</tr><br />
<tr><br />
<td>X</td><br />
<td><code>getTokenX(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Y</td><br />
<td><code>getTokenY(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Z</td><br />
<td><code>getTokenDrawOrder(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Height</td><br />
<td><code>getTokenHeight(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Width</td><br />
<td><code>getTokenWidth(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Size</td><br />
<td><code>getSize(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Facing</td><br />
<td><code>getTokenFacing(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Opacity</td><br />
<td><code>getTokenOpacity(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Visible</td><br />
<td><code>getVisible(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Shape</td><br />
<td><code>getTokenShape(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Layout</td><br />
<td><code>getTokenLayoutProps(&#39;;&#39;, ID)</code></td><br />
</tr><br />
<br />
</table><br />
<h4 id="token-fade-data-lists">Token Fade Data Lists</h4><br />
<p>Tokens on other elevations are faded with the <code>elevation.setTokenElevationStates</code> function have their opacity reduced and are assigned either the <code>isAbove</code> or <code>isBelow</code> state. Additionally, according to the <code>fadedTokenSight</code> option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p><br />
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format: <code>opacity, sight_type, has_sight</code></p><br />
<p>This is stored by default on the token in the <code>libRefData.elevation.fadeData</code> property. This property can be changed in the <code>elevation.getTokenFadePropName</code> method.</p><br />
<h4 id="options">Options</h4><br />
<p>There is a simple options API using <code>elevation.getMapOption</code> and <code>elevation.setMapOption</code>. This is a simple JSON object on the map&#39;s data token with keys (option names) and the option value, where a missing key is treated as &#39;0&#39;. Here are the available options:</p><br />
<table><br />
<br />
<tr><br />
<th>Option</th><br />
<th>Setting</th><br />
<th>Description</th><br />
</tr><br />
<br />
<br />
<tr><br />
<td>fadedSightType</td><br />
<td>0</td><br />
<td>Faded tokens (tokens on other elevations) will not have their sight settings changed in any way.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>1</td><br />
<td>&#39;Has Sight&#39; will be unchecked for all faded tokens.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>STRING</td><br />
<td>A string matching a defined Sight Type will be applied to faded tokens.</td><br />
</tr><br />
<tr><br />
<td>heightFactor</td><br />
<td>N</td><br />
<td>This is the height multiplier the new elevation dialog uses to recommend a new elevation value. That dialog sets a fallback value of &#39;2&#39; (so for a 5 ft square, it will recommend new layers at 10 ft), but this value might also be used to determine how a future token height implementation might determine when to display a token below the current layer. </td><br />
</tr><br />
<tr><br />
<td>useFogHack</td><br />
<td>0</td><br />
<td>Fog of war is not affected by elevation changes.</td><br />
</tr><br />
<tr><br />
<td></td><br />
<td>1</td><br />
<td>Fog of war is totally restored on elevation changes, followed by immediately exposing all player token sight ranges. Use with &#39;fadedSight = 1&#39; to give a more horror-like feel to multi-story buildings. If draw/eraseFoW functions are added, this may be retired.</td><br />
</tr><br />
<br />
</table><br />
<h4 id="sample-librefdata-elevation-layers-object">Sample <code>libRefData.elevation.layers</code> object</h4><br />
<p>A trivial example object may look like this:</p><br />
<br />
<pre>{<br />
"A14EF2FE619B42AF828CBBAC0192131A": {<br />
"0": {<br />
"label": "Ground level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
},<br />
"60": {<br />
"label": "Cliff top",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
}<br />
},<br />
"28CBBAC0192131AA14EF2FE619B42AF8": {<br />
"0": {<br />
"label": "Sea Level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
},<br />
"10": {<br />
"label": "Flying",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
}<br />
}<br />
}<br />
</pre><br />
<br />
[[Category:Draft]][[Category:How To]]</div>Melekhttps://wiki.rptools.info/index.php?title=Cookbook_Ingredients_-_Code_Snippets&diff=11492Cookbook Ingredients - Code Snippets2021-08-05T04:30:21Z<p>Melek: Melek moved page Cookbook Ingredients Setion (Code Snippets) to Cookbook Ingredients - Code Snippets without leaving a redirect: Remove parentheses from title and mispelling.</p>
<hr />
<div>== JSON ==<br />
<br />
=== Find Name of Key Containing an Array Containing a Key/Value Pair ===<br />
<br />
Given a JSON object like this one that contains arrays of states returned from getInfo("campaign"):<br />
<br />
<pre>{<br />
"other stuff":{},<br />
"states":{<br />
"no group":<br />
[<br />
{"name":"Dead"... },<br />
{"name":"Hidden"... }<br />
]<br />
"my named group":<br />
[<br />
{"name":"Blind"... },<br />
{"name":"Deaf"... }<br />
]<br />
},<br />
"more stuff":{}<br />
}</pre><br />
<br />
To find the name of the key containing the array that has the desired key/value pair, e.g. for the state "Blind" return "my named group".<br />
<br />
<pre>[h: jsonObject = getInfo("campaign")]<br />
[h: findKey = "name"]<br />
[h: findValue = "Blind"]<br />
[h: findWithin = "states"]<br />
[r: keyName = listGet(json.get(json.path.read(json.get(jsonObject, findWithin), strformat("\$..[?(@.%{findKey} == '%s')]", findValue), "AS_PATH_LIST"), 0), 1, "'")]<br />
alternatives<br />
[r: keyName = getGroup(strfind(jsonObject, '(?<=\\"'+findWithin+'\\":).*\\"([^\\"]+)\\"(?=:\\[)(?=.*\\"name\\":\\"'+findValue+'\\")'), 1, 1)]<br />
[r: keyName = replace(jsonObject, '.*(?<=\\"'+findWithin+'\\":).*\\"([^\\"]+)\\"(?=:\\[)(?=.*\\"'+findKey+'\\":\\"'+findValue+'\\").*',"\$1", 1)]<br />
[r: keyName = replace(json.get(jsonObject, findWithin),'.*?([^\\"]*)\\"\\:\\[[^\\[]*\\"'+findValue+'\\".*',"\$1", 1)]</pre><br />
<br />
=== Find Name of Key Containing an Object Containing a Key/Value Pair ===<br />
<br />
Given a JSON object like this one that contains JSON objects<br />
<br />
<pre>[h: jsonObj = '{<br />
"a": {<br />
"Return": "No"<br />
},<br />
"b": {<br />
"Return": "Yes"<br />
},<br />
"c": {<br />
"Return": "No"<br />
}<br />
}']</pre><br />
<br />
To find the key name of the first object containing an occurance of "Return": "Yes"<br />
<br />
<pre>[r: listGet(json.get(json.path.read(jsonObj, ".[?(@.Return == 'Yes')]", "AS_PATH_LIST"), 0), 1, "'")]</pre><br />
<br />
To get an array of all key names of objects containing an occurance of "Return": "Yes"<br />
<br />
<pre>[r: replace(json.path.read(jsonObj, ".[?(@.Return == 'Yes')]", "AS_PATH_LIST"), "\\\$\\[\\'|\\'\\]", "")]</pre><br />
<br />
[[Category:Cookbook]][[Category:Snippets]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Snippets&diff=11491Category:Snippets2021-08-05T04:28:53Z<p>Melek: Created page with "Category:Cookbook"</p>
<hr />
<div>[[Category:Cookbook]]</div>Melekhttps://wiki.rptools.info/index.php?title=Cookbook_Ingredients_-_Code_Snippets&diff=11490Cookbook Ingredients - Code Snippets2021-08-05T04:28:39Z<p>Melek: Posted on behalf of Reverend on Discord: https://discord.com/channels/296230822262865920/296659024818995200/872304827743481907</p>
<hr />
<div>== JSON ==<br />
<br />
=== Find Name of Key Containing an Array Containing a Key/Value Pair ===<br />
<br />
Given a JSON object like this one that contains arrays of states returned from getInfo("campaign"):<br />
<br />
<pre>{<br />
"other stuff":{},<br />
"states":{<br />
"no group":<br />
[<br />
{"name":"Dead"... },<br />
{"name":"Hidden"... }<br />
]<br />
"my named group":<br />
[<br />
{"name":"Blind"... },<br />
{"name":"Deaf"... }<br />
]<br />
},<br />
"more stuff":{}<br />
}</pre><br />
<br />
To find the name of the key containing the array that has the desired key/value pair, e.g. for the state "Blind" return "my named group".<br />
<br />
<pre>[h: jsonObject = getInfo("campaign")]<br />
[h: findKey = "name"]<br />
[h: findValue = "Blind"]<br />
[h: findWithin = "states"]<br />
[r: keyName = listGet(json.get(json.path.read(json.get(jsonObject, findWithin), strformat("\$..[?(@.%{findKey} == '%s')]", findValue), "AS_PATH_LIST"), 0), 1, "'")]<br />
alternatives<br />
[r: keyName = getGroup(strfind(jsonObject, '(?<=\\"'+findWithin+'\\":).*\\"([^\\"]+)\\"(?=:\\[)(?=.*\\"name\\":\\"'+findValue+'\\")'), 1, 1)]<br />
[r: keyName = replace(jsonObject, '.*(?<=\\"'+findWithin+'\\":).*\\"([^\\"]+)\\"(?=:\\[)(?=.*\\"'+findKey+'\\":\\"'+findValue+'\\").*',"\$1", 1)]<br />
[r: keyName = replace(json.get(jsonObject, findWithin),'.*?([^\\"]*)\\"\\:\\[[^\\[]*\\"'+findValue+'\\".*',"\$1", 1)]</pre><br />
<br />
=== Find Name of Key Containing an Object Containing a Key/Value Pair ===<br />
<br />
Given a JSON object like this one that contains JSON objects<br />
<br />
<pre>[h: jsonObj = '{<br />
"a": {<br />
"Return": "No"<br />
},<br />
"b": {<br />
"Return": "Yes"<br />
},<br />
"c": {<br />
"Return": "No"<br />
}<br />
}']</pre><br />
<br />
To find the key name of the first object containing an occurance of "Return": "Yes"<br />
<br />
<pre>[r: listGet(json.get(json.path.read(jsonObj, ".[?(@.Return == 'Yes')]", "AS_PATH_LIST"), 0), 1, "'")]</pre><br />
<br />
To get an array of all key names of objects containing an occurance of "Return": "Yes"<br />
<br />
<pre>[r: replace(json.path.read(jsonObj, ".[?(@.Return == 'Yes')]", "AS_PATH_LIST"), "\\\$\\[\\'|\\'\\]", "")]</pre><br />
<br />
[[Category:Cookbook]][[Category:Snippets]]</div>Melekhttps://wiki.rptools.info/index.php?title=lib:Elevation_Manual&diff=11442lib:Elevation Manual2021-07-18T06:18:57Z<p>Melek: Add links</p>
<hr />
<div>[[File:lib_elevation.png|thumb|Lib:Elevation tries to fit into the MapTool UI to add accessible elevation tools for map-making.]]<br />
<h1>Welcome to Lib:Elevation!</h1><br />
<ul><br />
<li><strong>[https://github.com/melek/lib_elevation Download Lib:Elevation from GitHub]</strong></li><br />
<li>[https://forums.rptools.net/viewtopic.php?f=8&t=29234 View the RPTools Forum Post]</li><br />
<li>Ask questions and discuss in the [https://discord.gg/hbn2bfn MapTool Discord] in the #map-drawing-tools channel</li><br />
</ul><br />
<p>This library adds an elevation feature to MapTool, allowing you to&nbsp;<strong>set Visual and Movement blocking layers based on elevation</strong>&nbsp;and&nbsp;<strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p><br />
<h2>Campaign Setup</h2><br />
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p><br />
<ul><br />
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong>&nbsp;for quick access. The overlay UI may have some of these options, but it is nice to have the buttons handy.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show special states for token-layer tokens at different elevations</strong>, add two states:&nbsp;<code>isAbove</code>&nbsp;to mark tokens on a higher defined map elevation level, and&nbsp;<code>isBelow</code>&nbsp;for tokens below the current map elevation level. I use partly transparent, 'Yield' (down arrow) and 'Triangle' images in the 2x2 grid. Tokens will also appear faded when not on the current elevation.</li><br />
<li><strong>To highlight/mark elevation tokens for GMs</strong>&nbsp;(doors, background maps, etc. set to a particular elevation), add an 'isElevationToken' state to your game and check the 'GM' and 'Mouseover' options. I use the 'Shaded' type state set to teal and 25% opacity. You can also change the property name in&nbsp;<code>getLinkedStateName</code>.</li><br />
</ul><br />
<h2>Usage</h2><br />
<p>By default, new maps have no elevations explicitly defined and won't show the elevation list overlay for the GM. Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations.&nbsp;<strong>Changing elevations changes them for all connected players</strong>, unlike layers which the GM can freely choose between without impacting how players see the map.</p><br />
<p>Each elevation saves a set of blocking layers (VBL and MBL) for the map, and can have tokens linked to it (<em>elevation tokens</em>) which will be hidden when a different elevation is chosen (unless that elevation also uses that elevation token). Changing between elevation layers swaps out which blocking layers are active and which elevation tokens are visible.</p><br />
<p>On a new map without any elevations defined, the implicit default elevation is zero - but adding a different elevation will set that as the only elevation.</p><br />
<h3>Elevation Management Buttons</h3><br />
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown:</p><br />
<ul><br />
<li><code>Add Elev</code>&nbsp;will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like the map stamp.</li><br />
<li><code>&#8593;&#8593;&#8593;</code>,&nbsp;<code>&#8595;&#8595;&#8595;</code>, and&nbsp;<code>&#8593;&#8595;</code>&nbsp;switches the map elevation up, down, or to a map elevation you choose.</li><br />
<li><code>T&#8593;&#8595;</code>&nbsp;button switches the map elevation to the selected token.</li><br />
<li><code>Link Tokens</code>&nbsp;links the selected token to an elevation you select. You can use&nbsp;<code>Unlink Tokns</code>&nbsp;to undo this, or&nbsp;<code>Select Tokens</code>&nbsp;to select all the current map elevation's linked tokens.</li><br />
</ul><br />
<h3>Token Management Buttons</h3><br />
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect.</p><br />
<p>Please note that using these buttons usually also switches to the new elevation.</p><br />
<h2>About Elevation</h2><br />
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to 'fill' the vertical space until the next elevation.</p><br />
<p>Here are some ideas on how to use this feature:</p><br />
<ul><br />
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations.</li><br />
<li>Remove vision entirely to simulate flying or scrying.</li><br />
<li>Change the background map at different elevations for a truly 'vertical' feeling, such as flying islands or tall, fog-filled canyons.</li><br />
</ul><br />
<h2>Limitations</h2><br />
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p><br />
<ul><br />
<li>Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.</li><br />
<li>While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.</li><br />
</ul><br />
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p><br />
<h2>Developer notes</h2><br />
<p>Here are outlines the data structures and basic mechanism behind the library.</p><br />
<h3>Library Properties</h3><br />
<table><br />
<tr><br />
<th>Property</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>libData.elevation.elevations</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for the current elevation. The current elevation is set when saving a map or loading a map, which happens whenever the map is switched with a UI macro. Essentially, this is almost always the 'display' elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td><br />
</tr><br />
<tr><br />
<td>libData.elevation.maps</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for JSON objects containing elevation data. This data structure is described below.</td><br />
</tr><br />
</table><br />
<h3>Data Structures</h3><br />
<p>Note that Lib:Elevation uses Map and Token IDs stored on the library; this means that the library is pretty tightly coupled with a campaign. Any change to the IDs expected by the data structure will lead to undefined behavior. Importing/Exporting maps with elevation data is not currently supported.</p><br />
<h4><code>libData.elevation.maps</code></h4><br />
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called 'Map Elevation Objects'. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>label</td><br />
<td>String</td><br />
<td>A display name for the elevation. Defined elevations don't require names.</td><br />
</tr><br />
<tr><br />
<td>vbl</td><br />
<td>JSON Array</td><br />
<td>VBL is a shape object array as returned by&nbsp;<code>getVBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>mbl</td><br />
<td>JSON Array</td><br />
<td>MBL is a shape object array as returned by&nbsp;<code>getMBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>tokens</td><br />
<td>JSON Object</td><br />
<td>Token ID keys containing&nbsp;<strong>token appearance</strong>&nbsp;objects. Token appearance is described below.</td><br />
</tr><br />
</table><br />
<h4>Token appearance objects</h4><br />
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in&nbsp;<code>getTokenAppearance()</code>&nbsp;and&nbsp;<code>setTokenAppearance()</code>. The token appearance JSON Object includes the following keys and the associated token data:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Data function</th><br />
</tr><br />
<tr><br />
<td>ID</td><br />
<td>Same as Field ID</td><br />
</tr><br />
<tr><br />
<td>Layer</td><br />
<td><code>getLayer(ID)</code></td><br />
</tr><br />
<tr><br />
<td>X</td><br />
<td><code>getTokenX(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Y</td><br />
<td><code>getTokenY(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Z</td><br />
<td><code>getTokenDrawOrder(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Height</td><br />
<td><code>getTokenHeight(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Width</td><br />
<td><code>getTokenWidth(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Size</td><br />
<td><code>getSize(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Facing</td><br />
<td><code>getTokenFacing(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Opacity</td><br />
<td><code>getTokenOpacity(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Visible</td><br />
<td><code>getVisible(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Shape</td><br />
<td><code>getTokenShape(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Layout</td><br />
<td><code>getTokenLayoutProps(';', ID)</code></td><br />
</tr><br />
</table><br />
<h4>Token Fade Data Lists</h4><br />
<p>Tokens on other elevations are faded with the&nbsp;<code>elevation.setTokenElevationStates</code>&nbsp;function have their opacity reduced and are assigned either the&nbsp;<code>isAbove</code>&nbsp;or&nbsp;<code>isBelow</code>&nbsp;state. Additionally, according to the&nbsp;<code>fadedTokenSight</code>&nbsp;option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p><br />
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format:&nbsp;<code>opacity, sight_type, has_sight</code></p><br />
<p>This is stored by default on the token in the&nbsp;<code>libRefData.elevation.fadeData</code>&nbsp;property. This property can be changed in the&nbsp;<code>elevation.getTokenFadePropName</code>&nbsp;method.</p><br />
<h4>Options</h4><br />
<p>There is a simple options API using&nbsp;<code>elevation.getOption</code>&nbsp;and&nbsp;<code>elevation.setOption</code>. This is a simple JSON object with keys (option names) and the option value, where a missing key is treated as '0'. Here are the available options:</p><br />
<ul><br />
<li><code>fadedSightType</code>&nbsp;Determines how faded tokens have their sight settings changed when faded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Do not change sight settings when faded.</li><br />
<li><code>1</code>&nbsp;- Uncheck 'Has Sight' when faded. Prior settings are restored when unfaded.</li><br />
<li><code>sight_type</code>&nbsp;- Assigns the sight type. Does not alter the 'Has Sight' checkbox. Prior settings are retored when token is unfaded.</li><br />
</ul><br />
</li><br />
<li><code>useFogHack</code>&nbsp;restores fog of war each time an elevation is loaded/reloaded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Disable fog hack.</li><br />
<li><code>1</code>&nbsp;- Enable fog hack.</li><br />
</ul><br />
</li><br />
</ul><br />
<h4>Sample&nbsp;<code>libData.elevation.maps</code>&nbsp;object</h4><br />
<p>A trivial example object may look like this:</p><br />
<pre>{<br />
"A14EF2FE619B42AF828CBBAC0192131A": {<br />
"0": {<br />
"label": "Ground level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
},<br />
"60": {<br />
"label": "Cliff top",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
}<br />
},<br />
"28CBBAC0192131AA14EF2FE619B42AF8": {<br />
"0": {<br />
"label": "Sea Level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
},<br />
"10": {<br />
"label": "Flying",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
}<br />
}<br />
}<br />
</pre><br />
<br />
[[Category:Draft]][[Category:How To]]</div>Melekhttps://wiki.rptools.info/index.php?title=lib:Elevation_Manual&diff=11441lib:Elevation Manual2021-07-18T06:08:42Z<p>Melek: Correct "Drafts" category to "Draft"</p>
<hr />
<div>[[File:lib_elevation.png|thumb|Lib:Elevation tries to fit into the MapTool UI to add accessible elevation tools for map-making.]]<br />
<h1>Welcome to Lib:Elevation!</h1><br />
<p><strong>Download Lib:Elevation [https://github.com/melek/lib_elevation on GitHub]</strong></p><br />
<p>This library adds an elevation feature to MapTool, allowing you to&nbsp;<strong>set Visual and Movement blocking layers based on elevation</strong>&nbsp;and&nbsp;<strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p><br />
<h2>Campaign Setup</h2><br />
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p><br />
<ul><br />
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong>&nbsp;for quick access. The overlay UI may have some of these options, but it is nice to have the buttons handy.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show special states for token-layer tokens at different elevations</strong>, add two states:&nbsp;<code>isAbove</code>&nbsp;to mark tokens on a higher defined map elevation level, and&nbsp;<code>isBelow</code>&nbsp;for tokens below the current map elevation level. I use partly transparent, 'Yield' (down arrow) and 'Triangle' images in the 2x2 grid. Tokens will also appear faded when not on the current elevation.</li><br />
<li><strong>To highlight/mark elevation tokens for GMs</strong>&nbsp;(doors, background maps, etc. set to a particular elevation), add an 'isElevationToken' state to your game and check the 'GM' and 'Mouseover' options. I use the 'Shaded' type state set to teal and 25% opacity. You can also change the property name in&nbsp;<code>getLinkedStateName</code>.</li><br />
</ul><br />
<h2>Usage</h2><br />
<p>By default, new maps have no elevations explicitly defined and won't show the elevation list overlay for the GM. Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations.&nbsp;<strong>Changing elevations changes them for all connected players</strong>, unlike layers which the GM can freely choose between without impacting how players see the map.</p><br />
<p>Each elevation saves a set of blocking layers (VBL and MBL) for the map, and can have tokens linked to it (<em>elevation tokens</em>) which will be hidden when a different elevation is chosen (unless that elevation also uses that elevation token). Changing between elevation layers swaps out which blocking layers are active and which elevation tokens are visible.</p><br />
<p>On a new map without any elevations defined, the implicit default elevation is zero - but adding a different elevation will set that as the only elevation.</p><br />
<h3>Elevation Management Buttons</h3><br />
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown:</p><br />
<ul><br />
<li><code>Add Elev</code>&nbsp;will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like the map stamp.</li><br />
<li><code>&#8593;&#8593;&#8593;</code>,&nbsp;<code>&#8595;&#8595;&#8595;</code>, and&nbsp;<code>&#8593;&#8595;</code>&nbsp;switches the map elevation up, down, or to a map elevation you choose.</li><br />
<li><code>T&#8593;&#8595;</code>&nbsp;button switches the map elevation to the selected token.</li><br />
<li><code>Link Tokens</code>&nbsp;links the selected token to an elevation you select. You can use&nbsp;<code>Unlink Tokns</code>&nbsp;to undo this, or&nbsp;<code>Select Tokens</code>&nbsp;to select all the current map elevation's linked tokens.</li><br />
</ul><br />
<h3>Token Management Buttons</h3><br />
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect.</p><br />
<p>Please note that using these buttons usually also switches to the new elevation.</p><br />
<h2>About Elevation</h2><br />
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to 'fill' the vertical space until the next elevation.</p><br />
<p>Here are some ideas on how to use this feature:</p><br />
<ul><br />
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations.</li><br />
<li>Remove vision entirely to simulate flying or scrying.</li><br />
<li>Change the background map at different elevations for a truly 'vertical' feeling, such as flying islands or tall, fog-filled canyons.</li><br />
</ul><br />
<h2>Limitations</h2><br />
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p><br />
<ul><br />
<li>Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.</li><br />
<li>While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.</li><br />
</ul><br />
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p><br />
<h2>Developer notes</h2><br />
<p>Here are outlines the data structures and basic mechanism behind the library.</p><br />
<h3>Library Properties</h3><br />
<table><br />
<tr><br />
<th>Property</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>libData.elevation.elevations</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for the current elevation. The current elevation is set when saving a map or loading a map, which happens whenever the map is switched with a UI macro. Essentially, this is almost always the 'display' elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td><br />
</tr><br />
<tr><br />
<td>libData.elevation.maps</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for JSON objects containing elevation data. This data structure is described below.</td><br />
</tr><br />
</table><br />
<h3>Data Structures</h3><br />
<p>Note that Lib:Elevation uses Map and Token IDs stored on the library; this means that the library is pretty tightly coupled with a campaign. Any change to the IDs expected by the data structure will lead to undefined behavior. Importing/Exporting maps with elevation data is not currently supported.</p><br />
<h4><code>libData.elevation.maps</code></h4><br />
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called 'Map Elevation Objects'. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>label</td><br />
<td>String</td><br />
<td>A display name for the elevation. Defined elevations don't require names.</td><br />
</tr><br />
<tr><br />
<td>vbl</td><br />
<td>JSON Array</td><br />
<td>VBL is a shape object array as returned by&nbsp;<code>getVBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>mbl</td><br />
<td>JSON Array</td><br />
<td>MBL is a shape object array as returned by&nbsp;<code>getMBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>tokens</td><br />
<td>JSON Object</td><br />
<td>Token ID keys containing&nbsp;<strong>token appearance</strong>&nbsp;objects. Token appearance is described below.</td><br />
</tr><br />
</table><br />
<h4>Token appearance objects</h4><br />
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in&nbsp;<code>getTokenAppearance()</code>&nbsp;and&nbsp;<code>setTokenAppearance()</code>. The token appearance JSON Object includes the following keys and the associated token data:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Data function</th><br />
</tr><br />
<tr><br />
<td>ID</td><br />
<td>Same as Field ID</td><br />
</tr><br />
<tr><br />
<td>Layer</td><br />
<td><code>getLayer(ID)</code></td><br />
</tr><br />
<tr><br />
<td>X</td><br />
<td><code>getTokenX(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Y</td><br />
<td><code>getTokenY(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Z</td><br />
<td><code>getTokenDrawOrder(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Height</td><br />
<td><code>getTokenHeight(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Width</td><br />
<td><code>getTokenWidth(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Size</td><br />
<td><code>getSize(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Facing</td><br />
<td><code>getTokenFacing(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Opacity</td><br />
<td><code>getTokenOpacity(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Visible</td><br />
<td><code>getVisible(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Shape</td><br />
<td><code>getTokenShape(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Layout</td><br />
<td><code>getTokenLayoutProps(';', ID)</code></td><br />
</tr><br />
</table><br />
<h4>Token Fade Data Lists</h4><br />
<p>Tokens on other elevations are faded with the&nbsp;<code>elevation.setTokenElevationStates</code>&nbsp;function have their opacity reduced and are assigned either the&nbsp;<code>isAbove</code>&nbsp;or&nbsp;<code>isBelow</code>&nbsp;state. Additionally, according to the&nbsp;<code>fadedTokenSight</code>&nbsp;option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p><br />
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format:&nbsp;<code>opacity, sight_type, has_sight</code></p><br />
<p>This is stored by default on the token in the&nbsp;<code>libRefData.elevation.fadeData</code>&nbsp;property. This property can be changed in the&nbsp;<code>elevation.getTokenFadePropName</code>&nbsp;method.</p><br />
<h4>Options</h4><br />
<p>There is a simple options API using&nbsp;<code>elevation.getOption</code>&nbsp;and&nbsp;<code>elevation.setOption</code>. This is a simple JSON object with keys (option names) and the option value, where a missing key is treated as '0'. Here are the available options:</p><br />
<ul><br />
<li><code>fadedSightType</code>&nbsp;Determines how faded tokens have their sight settings changed when faded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Do not change sight settings when faded.</li><br />
<li><code>1</code>&nbsp;- Uncheck 'Has Sight' when faded. Prior settings are restored when unfaded.</li><br />
<li><code>sight_type</code>&nbsp;- Assigns the sight type. Does not alter the 'Has Sight' checkbox. Prior settings are retored when token is unfaded.</li><br />
</ul><br />
</li><br />
<li><code>useFogHack</code>&nbsp;restores fog of war each time an elevation is loaded/reloaded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Disable fog hack.</li><br />
<li><code>1</code>&nbsp;- Enable fog hack.</li><br />
</ul><br />
</li><br />
</ul><br />
<h4>Sample&nbsp;<code>libData.elevation.maps</code>&nbsp;object</h4><br />
<p>A trivial example object may look like this:</p><br />
<pre>{<br />
"A14EF2FE619B42AF828CBBAC0192131A": {<br />
"0": {<br />
"label": "Ground level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
},<br />
"60": {<br />
"label": "Cliff top",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
}<br />
},<br />
"28CBBAC0192131AA14EF2FE619B42AF8": {<br />
"0": {<br />
"label": "Sea Level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
},<br />
"10": {<br />
"label": "Flying",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
}<br />
}<br />
}<br />
</pre><br />
<br />
[[Category:Draft]][[Category:How To]]</div>Melekhttps://wiki.rptools.info/index.php?title=lib:Elevation_Manual&diff=11440lib:Elevation Manual2021-07-18T04:54:26Z<p>Melek: Add screenshot.</p>
<hr />
<div>[[File:lib_elevation.png|thumb|Lib:Elevation tries to fit into the MapTool UI to add accessible elevation tools for map-making.]]<br />
<h1>Welcome to Lib:Elevation!</h1><br />
<p><strong>Download Lib:Elevation [https://github.com/melek/lib_elevation on GitHub]</strong></p><br />
<p>This library adds an elevation feature to MapTool, allowing you to&nbsp;<strong>set Visual and Movement blocking layers based on elevation</strong>&nbsp;and&nbsp;<strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p><br />
<h2>Campaign Setup</h2><br />
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p><br />
<ul><br />
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong>&nbsp;for quick access. The overlay UI may have some of these options, but it is nice to have the buttons handy.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show special states for token-layer tokens at different elevations</strong>, add two states:&nbsp;<code>isAbove</code>&nbsp;to mark tokens on a higher defined map elevation level, and&nbsp;<code>isBelow</code>&nbsp;for tokens below the current map elevation level. I use partly transparent, 'Yield' (down arrow) and 'Triangle' images in the 2x2 grid. Tokens will also appear faded when not on the current elevation.</li><br />
<li><strong>To highlight/mark elevation tokens for GMs</strong>&nbsp;(doors, background maps, etc. set to a particular elevation), add an 'isElevationToken' state to your game and check the 'GM' and 'Mouseover' options. I use the 'Shaded' type state set to teal and 25% opacity. You can also change the property name in&nbsp;<code>getLinkedStateName</code>.</li><br />
</ul><br />
<h2>Usage</h2><br />
<p>By default, new maps have no elevations explicitly defined and won't show the elevation list overlay for the GM. Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations.&nbsp;<strong>Changing elevations changes them for all connected players</strong>, unlike layers which the GM can freely choose between without impacting how players see the map.</p><br />
<p>Each elevation saves a set of blocking layers (VBL and MBL) for the map, and can have tokens linked to it (<em>elevation tokens</em>) which will be hidden when a different elevation is chosen (unless that elevation also uses that elevation token). Changing between elevation layers swaps out which blocking layers are active and which elevation tokens are visible.</p><br />
<p>On a new map without any elevations defined, the implicit default elevation is zero - but adding a different elevation will set that as the only elevation.</p><br />
<h3>Elevation Management Buttons</h3><br />
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown:</p><br />
<ul><br />
<li><code>Add Elev</code>&nbsp;will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like the map stamp.</li><br />
<li><code>&#8593;&#8593;&#8593;</code>,&nbsp;<code>&#8595;&#8595;&#8595;</code>, and&nbsp;<code>&#8593;&#8595;</code>&nbsp;switches the map elevation up, down, or to a map elevation you choose.</li><br />
<li><code>T&#8593;&#8595;</code>&nbsp;button switches the map elevation to the selected token.</li><br />
<li><code>Link Tokens</code>&nbsp;links the selected token to an elevation you select. You can use&nbsp;<code>Unlink Tokns</code>&nbsp;to undo this, or&nbsp;<code>Select Tokens</code>&nbsp;to select all the current map elevation's linked tokens.</li><br />
</ul><br />
<h3>Token Management Buttons</h3><br />
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect.</p><br />
<p>Please note that using these buttons usually also switches to the new elevation.</p><br />
<h2>About Elevation</h2><br />
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to 'fill' the vertical space until the next elevation.</p><br />
<p>Here are some ideas on how to use this feature:</p><br />
<ul><br />
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations.</li><br />
<li>Remove vision entirely to simulate flying or scrying.</li><br />
<li>Change the background map at different elevations for a truly 'vertical' feeling, such as flying islands or tall, fog-filled canyons.</li><br />
</ul><br />
<h2>Limitations</h2><br />
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p><br />
<ul><br />
<li>Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.</li><br />
<li>While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.</li><br />
</ul><br />
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p><br />
<h2>Developer notes</h2><br />
<p>Here are outlines the data structures and basic mechanism behind the library.</p><br />
<h3>Library Properties</h3><br />
<table><br />
<tr><br />
<th>Property</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>libData.elevation.elevations</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for the current elevation. The current elevation is set when saving a map or loading a map, which happens whenever the map is switched with a UI macro. Essentially, this is almost always the 'display' elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td><br />
</tr><br />
<tr><br />
<td>libData.elevation.maps</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for JSON objects containing elevation data. This data structure is described below.</td><br />
</tr><br />
</table><br />
<h3>Data Structures</h3><br />
<p>Note that Lib:Elevation uses Map and Token IDs stored on the library; this means that the library is pretty tightly coupled with a campaign. Any change to the IDs expected by the data structure will lead to undefined behavior. Importing/Exporting maps with elevation data is not currently supported.</p><br />
<h4><code>libData.elevation.maps</code></h4><br />
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called 'Map Elevation Objects'. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>label</td><br />
<td>String</td><br />
<td>A display name for the elevation. Defined elevations don't require names.</td><br />
</tr><br />
<tr><br />
<td>vbl</td><br />
<td>JSON Array</td><br />
<td>VBL is a shape object array as returned by&nbsp;<code>getVBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>mbl</td><br />
<td>JSON Array</td><br />
<td>MBL is a shape object array as returned by&nbsp;<code>getMBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>tokens</td><br />
<td>JSON Object</td><br />
<td>Token ID keys containing&nbsp;<strong>token appearance</strong>&nbsp;objects. Token appearance is described below.</td><br />
</tr><br />
</table><br />
<h4>Token appearance objects</h4><br />
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in&nbsp;<code>getTokenAppearance()</code>&nbsp;and&nbsp;<code>setTokenAppearance()</code>. The token appearance JSON Object includes the following keys and the associated token data:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Data function</th><br />
</tr><br />
<tr><br />
<td>ID</td><br />
<td>Same as Field ID</td><br />
</tr><br />
<tr><br />
<td>Layer</td><br />
<td><code>getLayer(ID)</code></td><br />
</tr><br />
<tr><br />
<td>X</td><br />
<td><code>getTokenX(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Y</td><br />
<td><code>getTokenY(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Z</td><br />
<td><code>getTokenDrawOrder(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Height</td><br />
<td><code>getTokenHeight(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Width</td><br />
<td><code>getTokenWidth(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Size</td><br />
<td><code>getSize(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Facing</td><br />
<td><code>getTokenFacing(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Opacity</td><br />
<td><code>getTokenOpacity(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Visible</td><br />
<td><code>getVisible(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Shape</td><br />
<td><code>getTokenShape(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Layout</td><br />
<td><code>getTokenLayoutProps(';', ID)</code></td><br />
</tr><br />
</table><br />
<h4>Token Fade Data Lists</h4><br />
<p>Tokens on other elevations are faded with the&nbsp;<code>elevation.setTokenElevationStates</code>&nbsp;function have their opacity reduced and are assigned either the&nbsp;<code>isAbove</code>&nbsp;or&nbsp;<code>isBelow</code>&nbsp;state. Additionally, according to the&nbsp;<code>fadedTokenSight</code>&nbsp;option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p><br />
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format:&nbsp;<code>opacity, sight_type, has_sight</code></p><br />
<p>This is stored by default on the token in the&nbsp;<code>libRefData.elevation.fadeData</code>&nbsp;property. This property can be changed in the&nbsp;<code>elevation.getTokenFadePropName</code>&nbsp;method.</p><br />
<h4>Options</h4><br />
<p>There is a simple options API using&nbsp;<code>elevation.getOption</code>&nbsp;and&nbsp;<code>elevation.setOption</code>. This is a simple JSON object with keys (option names) and the option value, where a missing key is treated as '0'. Here are the available options:</p><br />
<ul><br />
<li><code>fadedSightType</code>&nbsp;Determines how faded tokens have their sight settings changed when faded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Do not change sight settings when faded.</li><br />
<li><code>1</code>&nbsp;- Uncheck 'Has Sight' when faded. Prior settings are restored when unfaded.</li><br />
<li><code>sight_type</code>&nbsp;- Assigns the sight type. Does not alter the 'Has Sight' checkbox. Prior settings are retored when token is unfaded.</li><br />
</ul><br />
</li><br />
<li><code>useFogHack</code>&nbsp;restores fog of war each time an elevation is loaded/reloaded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Disable fog hack.</li><br />
<li><code>1</code>&nbsp;- Enable fog hack.</li><br />
</ul><br />
</li><br />
</ul><br />
<h4>Sample&nbsp;<code>libData.elevation.maps</code>&nbsp;object</h4><br />
<p>A trivial example object may look like this:</p><br />
<pre>{<br />
"A14EF2FE619B42AF828CBBAC0192131A": {<br />
"0": {<br />
"label": "Ground level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
},<br />
"60": {<br />
"label": "Cliff top",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
}<br />
},<br />
"28CBBAC0192131AA14EF2FE619B42AF8": {<br />
"0": {<br />
"label": "Sea Level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
},<br />
"10": {<br />
"label": "Flying",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
}<br />
}<br />
}<br />
</pre><br />
<br />
[[Category:Drafts]][[Category:How To]]</div>Melekhttps://wiki.rptools.info/index.php?title=File:lib_elevation.png&diff=11439File:lib elevation.png2021-07-18T04:51:39Z<p>Melek: Sample screenshot of Lib:Elevation</p>
<hr />
<div>== Summary ==<br />
Sample screenshot of Lib:Elevation</div>Melekhttps://wiki.rptools.info/index.php?title=lib:Elevation_Manual&diff=11438lib:Elevation Manual2021-07-18T04:23:27Z<p>Melek: Initial copy of Lib:Elevation user guide.</p>
<hr />
<div><h1>Welcome to Lib:Elevation!</h1><br />
<p><strong>Download Lib:Elevation [https://github.com/melek/lib_elevation on GitHub]</strong></p><br />
<p>This library adds an elevation feature to MapTool, allowing you to&nbsp;<strong>set Visual and Movement blocking layers based on elevation</strong>&nbsp;and&nbsp;<strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p><br />
<h2>Campaign Setup</h2><br />
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p><br />
<ul><br />
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong>&nbsp;for quick access. The overlay UI may have some of these options, but it is nice to have the buttons handy.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li><br />
<li><strong>To show special states for token-layer tokens at different elevations</strong>, add two states:&nbsp;<code>isAbove</code>&nbsp;to mark tokens on a higher defined map elevation level, and&nbsp;<code>isBelow</code>&nbsp;for tokens below the current map elevation level. I use partly transparent, 'Yield' (down arrow) and 'Triangle' images in the 2x2 grid. Tokens will also appear faded when not on the current elevation.</li><br />
<li><strong>To highlight/mark elevation tokens for GMs</strong>&nbsp;(doors, background maps, etc. set to a particular elevation), add an 'isElevationToken' state to your game and check the 'GM' and 'Mouseover' options. I use the 'Shaded' type state set to teal and 25% opacity. You can also change the property name in&nbsp;<code>getLinkedStateName</code>.</li><br />
</ul><br />
<h2>Usage</h2><br />
<p>By default, new maps have no elevations explicitly defined and won't show the elevation list overlay for the GM. Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations.&nbsp;<strong>Changing elevations changes them for all connected players</strong>, unlike layers which the GM can freely choose between without impacting how players see the map.</p><br />
<p>Each elevation saves a set of blocking layers (VBL and MBL) for the map, and can have tokens linked to it (<em>elevation tokens</em>) which will be hidden when a different elevation is chosen (unless that elevation also uses that elevation token). Changing between elevation layers swaps out which blocking layers are active and which elevation tokens are visible.</p><br />
<p>On a new map without any elevations defined, the implicit default elevation is zero - but adding a different elevation will set that as the only elevation.</p><br />
<h3>Elevation Management Buttons</h3><br />
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown:</p><br />
<ul><br />
<li><code>Add Elev</code>&nbsp;will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like the map stamp.</li><br />
<li><code>&#8593;&#8593;&#8593;</code>,&nbsp;<code>&#8595;&#8595;&#8595;</code>, and&nbsp;<code>&#8593;&#8595;</code>&nbsp;switches the map elevation up, down, or to a map elevation you choose.</li><br />
<li><code>T&#8593;&#8595;</code>&nbsp;button switches the map elevation to the selected token.</li><br />
<li><code>Link Tokens</code>&nbsp;links the selected token to an elevation you select. You can use&nbsp;<code>Unlink Tokns</code>&nbsp;to undo this, or&nbsp;<code>Select Tokens</code>&nbsp;to select all the current map elevation's linked tokens.</li><br />
</ul><br />
<h3>Token Management Buttons</h3><br />
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect.</p><br />
<p>Please note that using these buttons usually also switches to the new elevation.</p><br />
<h2>About Elevation</h2><br />
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to 'fill' the vertical space until the next elevation.</p><br />
<p>Here are some ideas on how to use this feature:</p><br />
<ul><br />
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations.</li><br />
<li>Remove vision entirely to simulate flying or scrying.</li><br />
<li>Change the background map at different elevations for a truly 'vertical' feeling, such as flying islands or tall, fog-filled canyons.</li><br />
</ul><br />
<h2>Limitations</h2><br />
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p><br />
<ul><br />
<li>Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.</li><br />
<li>While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.</li><br />
</ul><br />
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p><br />
<h2>Developer notes</h2><br />
<p>Here are outlines the data structures and basic mechanism behind the library.</p><br />
<h3>Library Properties</h3><br />
<table><br />
<tr><br />
<th>Property</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>libData.elevation.elevations</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for the current elevation. The current elevation is set when saving a map or loading a map, which happens whenever the map is switched with a UI macro. Essentially, this is almost always the 'display' elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td><br />
</tr><br />
<tr><br />
<td>libData.elevation.maps</td><br />
<td>JSON Object</td><br />
<td>Map IDs are keys for JSON objects containing elevation data. This data structure is described below.</td><br />
</tr><br />
</table><br />
<h3>Data Structures</h3><br />
<p>Note that Lib:Elevation uses Map and Token IDs stored on the library; this means that the library is pretty tightly coupled with a campaign. Any change to the IDs expected by the data structure will lead to undefined behavior. Importing/Exporting maps with elevation data is not currently supported.</p><br />
<h4><code>libData.elevation.maps</code></h4><br />
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called 'Map Elevation Objects'. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Type</th><br />
<th>Purpose</th><br />
</tr><br />
<tr><br />
<td>label</td><br />
<td>String</td><br />
<td>A display name for the elevation. Defined elevations don't require names.</td><br />
</tr><br />
<tr><br />
<td>vbl</td><br />
<td>JSON Array</td><br />
<td>VBL is a shape object array as returned by&nbsp;<code>getVBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>mbl</td><br />
<td>JSON Array</td><br />
<td>MBL is a shape object array as returned by&nbsp;<code>getMBL()</code>.</td><br />
</tr><br />
<tr><br />
<td>tokens</td><br />
<td>JSON Object</td><br />
<td>Token ID keys containing&nbsp;<strong>token appearance</strong>&nbsp;objects. Token appearance is described below.</td><br />
</tr><br />
</table><br />
<h4>Token appearance objects</h4><br />
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in&nbsp;<code>getTokenAppearance()</code>&nbsp;and&nbsp;<code>setTokenAppearance()</code>. The token appearance JSON Object includes the following keys and the associated token data:</p><br />
<table><br />
<tr><br />
<th>Key</th><br />
<th>Data function</th><br />
</tr><br />
<tr><br />
<td>ID</td><br />
<td>Same as Field ID</td><br />
</tr><br />
<tr><br />
<td>Layer</td><br />
<td><code>getLayer(ID)</code></td><br />
</tr><br />
<tr><br />
<td>X</td><br />
<td><code>getTokenX(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Y</td><br />
<td><code>getTokenY(1, ID)</code></td><br />
</tr><br />
<tr><br />
<td>Z</td><br />
<td><code>getTokenDrawOrder(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Height</td><br />
<td><code>getTokenHeight(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Width</td><br />
<td><code>getTokenWidth(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Size</td><br />
<td><code>getSize(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Facing</td><br />
<td><code>getTokenFacing(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Opacity</td><br />
<td><code>getTokenOpacity(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Visible</td><br />
<td><code>getVisible(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Shape</td><br />
<td><code>getTokenShape(ID)</code></td><br />
</tr><br />
<tr><br />
<td>Layout</td><br />
<td><code>getTokenLayoutProps(';', ID)</code></td><br />
</tr><br />
</table><br />
<h4>Token Fade Data Lists</h4><br />
<p>Tokens on other elevations are faded with the&nbsp;<code>elevation.setTokenElevationStates</code>&nbsp;function have their opacity reduced and are assigned either the&nbsp;<code>isAbove</code>&nbsp;or&nbsp;<code>isBelow</code>&nbsp;state. Additionally, according to the&nbsp;<code>fadedTokenSight</code>&nbsp;option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p><br />
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format:&nbsp;<code>opacity, sight_type, has_sight</code></p><br />
<p>This is stored by default on the token in the&nbsp;<code>libRefData.elevation.fadeData</code>&nbsp;property. This property can be changed in the&nbsp;<code>elevation.getTokenFadePropName</code>&nbsp;method.</p><br />
<h4>Options</h4><br />
<p>There is a simple options API using&nbsp;<code>elevation.getOption</code>&nbsp;and&nbsp;<code>elevation.setOption</code>. This is a simple JSON object with keys (option names) and the option value, where a missing key is treated as '0'. Here are the available options:</p><br />
<ul><br />
<li><code>fadedSightType</code>&nbsp;Determines how faded tokens have their sight settings changed when faded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Do not change sight settings when faded.</li><br />
<li><code>1</code>&nbsp;- Uncheck 'Has Sight' when faded. Prior settings are restored when unfaded.</li><br />
<li><code>sight_type</code>&nbsp;- Assigns the sight type. Does not alter the 'Has Sight' checkbox. Prior settings are retored when token is unfaded.</li><br />
</ul><br />
</li><br />
<li><code>useFogHack</code>&nbsp;restores fog of war each time an elevation is loaded/reloaded.<br />
<ul><br />
<li><code>0</code>&nbsp;- Disable fog hack.</li><br />
<li><code>1</code>&nbsp;- Enable fog hack.</li><br />
</ul><br />
</li><br />
</ul><br />
<h4>Sample&nbsp;<code>libData.elevation.maps</code>&nbsp;object</h4><br />
<p>A trivial example object may look like this:</p><br />
<pre>{<br />
"A14EF2FE619B42AF828CBBAC0192131A": {<br />
"0": {<br />
"label": "Ground level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
},<br />
"60": {<br />
"label": "Cliff top",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array",<br />
"tokens": {<br />
"BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",<br />
"19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"<br />
}<br />
}<br />
},<br />
"28CBBAC0192131AA14EF2FE619B42AF8": {<br />
"0": {<br />
"label": "Sea Level",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
},<br />
"10": {<br />
"label": "Flying",<br />
"vbl": "JSON Shapes Array",<br />
"mbl": "JSON Shapes Array"<br />
}<br />
}<br />
}<br />
</pre><br />
<br />
[[Category:Drafts]][[Category:How To]]</div>Melekhttps://wiki.rptools.info/index.php?title=JSON_Object&diff=11436JSON Object2021-07-15T05:18:46Z<p>Melek: Reversing category change.</p>
<hr />
<div>The JSON Object is a native JSON Data Type and supported by many MapTool macro functions as an input or output. <br />
<br />
[http://www.json.org JSON.org] defines it like this:<br />
<blockquote>An object is an '''unordered''' set of name/value pairs. An object begins with {{code|{}} (left brace) and ends with {{code|<nowiki>}</nowiki>}} (right brace). Each name is followed by {{code|:}} (colon) and the name/value pairs are separated by {{code|,}} (comma).<br />
</blockquote><br />
<br />
The values in an object's name/value pairs may be of any of the supported JSON Data Types: Number, String, Object, Array, Boolean and Null. The names must be strings.<br />
<br />
== Examples of JSON Objects ==<br />
A simple object with two name/value pairs.<br />
<source lang="mtmacro"><br />
[h: flower = '{"type":"Rose","color":"Red"}']<br />
</source><br />
The same object created with {{func|json.set}}.<br />
<source lang="mtmacro"><br />
[h: flower = json.set("","type","Rose","color","Red")]<br />
</source><br />
A more complex example with an object in an object.<br />
<source lang="mtmacro"><br />
[h: flower = json.set("","type","Rose","color","Red")]<br />
[h: flower = json.set(flower,"quantity",12)]<br />
[h: order = json.set("","customer","Hopeless Romantic","address","End of Lonely Street", "flower",flower)]<br />
<pre>[r: json.indent(order,2)]</pre><br />
</source><br />
Produces:<br />
<source lang="javascript"><br />
{<br />
"customer": "Hopeless Romantic",<br />
"address": "End of Lonely Street",<br />
"flower": {<br />
"type": "Rose",<br />
"color": "Red",<br />
"quantity": 12<br />
}<br />
}<br />
</source><br />
<br />
- <br />
[[Category:Variable Type]]</div>Melekhttps://wiki.rptools.info/index.php?title=JSON_Object&diff=11435JSON Object2021-07-15T05:08:36Z<p>Melek: </p>
<hr />
<div>The JSON Object is a native JSON Data Type and supported by many MapTool macro functions as an input or output. <br />
<br />
[http://www.json.org JSON.org] defines it like this:<br />
<blockquote>An object is an '''unordered''' set of name/value pairs. An object begins with {{code|{}} (left brace) and ends with {{code|<nowiki>}</nowiki>}} (right brace). Each name is followed by {{code|:}} (colon) and the name/value pairs are separated by {{code|,}} (comma).<br />
</blockquote><br />
<br />
The values in an object's name/value pairs may be of any of the supported JSON Data Types: Number, String, Object, Array, Boolean and Null. The names must be strings.<br />
<br />
== Examples of JSON Objects ==<br />
A simple object with two name/value pairs.<br />
<source lang="mtmacro"><br />
[h: flower = '{"type":"Rose","color":"Red"}']<br />
</source><br />
The same object created with {{func|json.set}}.<br />
<source lang="mtmacro"><br />
[h: flower = json.set("","type","Rose","color","Red")]<br />
</source><br />
A more complex example with an object in an object.<br />
<source lang="mtmacro"><br />
[h: flower = json.set("","type","Rose","color","Red")]<br />
[h: flower = json.set(flower,"quantity",12)]<br />
[h: order = json.set("","customer","Hopeless Romantic","address","End of Lonely Street", "flower",flower)]<br />
<pre>[r: json.indent(order,2)]</pre><br />
</source><br />
Produces:<br />
<source lang="javascript"><br />
{<br />
"customer": "Hopeless Romantic",<br />
"address": "End of Lonely Street",<br />
"flower": {<br />
"type": "Rose",<br />
"color": "Red",<br />
"quantity": 12<br />
}<br />
}<br />
</source><br />
<br />
- <br />
[[Category:Variable Type]][[Category:JSON Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=setSize&diff=11425setSize2021-06-27T08:36:17Z<p>Melek: Document "Free" and "Native" size options.</p>
<hr />
<div>{{MacroFunction<br />
|name=setSize<br />
|trusted=true<br />
|version=1.3b48<br />
|description=<br />
Sets the size of a [[Token]] with one of the defined sizes according to each Grid Type. The sizes can be found on the [[Token Size]] page. "Free" or "Native" are also valid values.<br />
<br />
|usage=<br />
<source lang="mtmacro" line><br />
setSize(size)<br />
setSize(size, id)<br />
setSize(size, id, mapname)<br />
</source><br />
'''Parameters'''<br />
{{param|size|A [[Token Size]] to set the token to. Can be "Free" or "Native" as well.}}<br />
{{param|id|The token {{code|id}} of the token which will have its [[Token Size]] set. Defaults to the [[Current Token]].}}<br />
{{param|mapname|The name of the map to find the token. Defaults to the current map.}}<br />
<br />
|examples=<br />
To set the size of the current token to {{code|Medium}}:<br />
<source lang="mtmacro" line><br />
[h: setSize("Medium")]<br />
</source><br />
<br />
To set the size of the current token to whatever string is stored in the macro variable '''mySize''':<br />
<source lang="mtmacro" line><br />
[h: mySize = "Large"]<br />
[h: setSize(mySize)]<br />
</source><br />
<br />
|also=<br />
{{func|getSize}}<br />
<br />
|changes=<br />
{{change|1.3b51|Added {{code|id}} parameter option.}}<br />
{{change|1.5.4|Added {{code|mapname}} parameter option.}}<br />
<br />
}}<br />
[[Category:Token Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=size&diff=11424size2021-06-27T02:55:07Z<p>Melek: Update to a proper redirect.</p>
<hr />
<div>#REDIRECT [[Token Size]]</div>Melekhttps://wiki.rptools.info/index.php?title=Template:VideoTutorial&diff=11423Template:VideoTutorial2021-06-26T16:47:56Z<p>Melek: /* Template Usage */ Add link to sandbox.</p>
<hr />
<div><noinclude><br />
=Template Usage=<br />
This template wraps a YouTube video slug into a link/callout box intended for demonstration and tutorial videos. To test out this template there is a [[VideoTutorial|VideoTutorial sandbox page]].<br />
<br />
==Example Output==<br />
<div style="display: inline-block;padding: 0;border: 1px solid silver;background: #fdfdfd; background-position: left center;background-size: 4rem;background-repeat: no-repeat" class="video_tutorial"><br />
<div style="float:left">[[File:clapperboard.png|48px]]</div><br />
<div style="float:right; padding:.5rem; .75rem .5rem 0;"><strong>[https://www.youtube.com/watch?v=9rVo2Yj-xcw Tom Chapman's first MapTool tutorial]</strong><br><em>The most watched tutorial series for MapTool.</em><br />
</div><br />
</div><br />
<br />
==Example==<br />
<pre>{{VideoTutorial<br />
|9rVo2Yj-xcw<br />
|Tom Chapman's MapTool Tutorial<br />
|The first video in the series.<br />
}}</pre><br />
<br />
=Source=<br />
Edit this section to view template source.<br />
</noinclude><includeonly><div style="display: inline-block;padding: 0;border: 1px solid silver;background: #fdfdfd; background-position: left center;background-size: 4rem;background-repeat: no-repeat" class="video_tutorial"><br />
<div style="float:left">[[File:clapperboard.png|48px]]</div><br />
<div style="float:right; padding:.5rem; .75rem .5rem 0;"><strong>[https://www.youtube.com/watch?v={{{1}}} {{{2|Video Tutorial}}}]</strong><br><em>{{{3}}}</em><br />
</div></div>[[Category:Pages with Video Tutorials]]</includeonly><noinclude>[[Category:Templates]]</noinclude></div>Melekhttps://wiki.rptools.info/index.php?title=Template:VideoTutorial&diff=11422Template:VideoTutorial2021-06-26T16:47:10Z<p>Melek: Update to be cuter.</p>
<hr />
<div><noinclude><br />
=Template Usage=<br />
This template wraps a YouTube video slug into a link/callout box intended for demonstration and tutorial videos.<br />
<br />
==Example Output==<br />
<div style="display: inline-block;padding: 0;border: 1px solid silver;background: #fdfdfd; background-position: left center;background-size: 4rem;background-repeat: no-repeat" class="video_tutorial"><br />
<div style="float:left">[[File:clapperboard.png|48px]]</div><br />
<div style="float:right; padding:.5rem; .75rem .5rem 0;"><strong>[https://www.youtube.com/watch?v=9rVo2Yj-xcw Tom Chapman's first MapTool tutorial]</strong><br><em>The most watched tutorial series for MapTool.</em><br />
</div><br />
</div><br />
<br />
==Example==<br />
<pre>{{VideoTutorial<br />
|9rVo2Yj-xcw<br />
|Tom Chapman's MapTool Tutorial<br />
|The first video in the series.<br />
}}</pre><br />
<br />
=Source=<br />
Edit this section to view template source.<br />
</noinclude><includeonly><div style="display: inline-block;padding: 0;border: 1px solid silver;background: #fdfdfd; background-position: left center;background-size: 4rem;background-repeat: no-repeat" class="video_tutorial"><br />
<div style="float:left">[[File:clapperboard.png|48px]]</div><br />
<div style="float:right; padding:.5rem; .75rem .5rem 0;"><strong>[https://www.youtube.com/watch?v={{{1}}} {{{2|Video Tutorial}}}]</strong><br><em>{{{3}}}</em><br />
</div></div>[[Category:Pages with Video Tutorials]]</includeonly><noinclude>[[Category:Templates]]</noinclude></div>Melekhttps://wiki.rptools.info/index.php?title=Category:Pages_with_Video_Tutorials&diff=11421Category:Pages with Video Tutorials2021-06-26T16:30:07Z<p>Melek: Created page with "Category:Tutorial"</p>
<hr />
<div>[[Category:Tutorial]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Pages_with_ignored_display_titles&diff=11420Category:Pages with ignored display titles2021-06-26T16:29:46Z<p>Melek: Created page with "Category:Meta"</p>
<hr />
<div>[[Category:Meta]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Pages_with_broken_file_links&diff=11419Category:Pages with broken file links2021-06-26T16:29:34Z<p>Melek: Created page with "Category:Meta"</p>
<hr />
<div>[[Category:Meta]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Pages_using_deprecated_source_tags&diff=11418Category:Pages using deprecated source tags2021-06-26T16:29:12Z<p>Melek: Contextualize and categorize.</p>
<hr />
<div>This category is populated automatically by the MediaWiki software. It contains pages where MediaWiki has detected deprecated <code>&lt;source&gt;...&lt;/source&gt;</code>. These should be replaced by <code>&lt;syntaxhighlight&gt;...&lt;/syntaxhighlight&gt;</code>.<br />
[[Category:Meta]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Hidden_categories&diff=11417Category:Hidden categories2021-06-26T16:25:48Z<p>Melek: Created page with "Category:Meta"</p>
<hr />
<div>[[Category:Meta]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Pages_with_syntax_highlighting_errors&diff=11416Category:Pages with syntax highlighting errors2021-06-26T16:25:32Z<p>Melek: Hide this category since 'mtmacro' lang attributes are common.</p>
<hr />
<div>Lists pages that have a bad <code>lang</code> attribute in a {{code|<source>}} or {{code|<syntaxhighlight>}} tag to this tracking category.<br />
<br />
The most common error that leads to pages being tagged with this category is a {{code|syntaxhighlight}} or {{code|source}} tag with no <code>lang</code> attribute at all. These can typically be replaced with {{code|pre}} or <code>lang="bash"</code> can be added.<br />
<br />
The second most common error is the use of <code>lang="sh"</code> or <code>lang="shell"</code> which are unsupported. These can typically be replaced with <code>lang="bash"</code> or <code>lang="shell-session"</code>.<br />
__HIDDENCAT__</div>Melekhttps://wiki.rptools.info/index.php?title=addAllNPCsToInitiative&diff=11415addAllNPCsToInitiative2021-06-26T16:23:50Z<p>Melek: Replace deprecated <source> tag with <syntaxhighlight></p>
<hr />
<div>{{MacroFunction<br />
|name=Function addAllNPCsToInitiative<br />
|trusted=true<br />
|description=Adds all the [[Introduction_to_Tokens#Token_Type|NPC token]]s on the current [[Map:map|map]] to the [[Initiative:initiative panel|initiative panel]]. This function returns the number of [[Token:token|token]]s that were added to the [[Initiative:initiative panel|initiative panel]]. <br />
<br />
This function will not assign any initiative value to the [[Token:token|token]]s, you can use the [[setInitiative | {{code|setInitiative()}}]] function<br />
to set the initiative value of tokens.<br />
<br />
|usage=<br />
<syntaxhighlight lang="mtmacro" line><br />
addAllNPCsToInitiative()<br />
</syntaxhighlight><br />
<br />
|example=<br />
<syntaxhighlight lang="mtmacro" line><br />
[h: noTokens = addAllNPCsToInitiative()]<br />
</syntaxhighlight><br />
<br />
<br />
<syntaxhighlight lang="mtmacro" line><br />
Added [r: addAllNPCsToInitiative()] NPCs to the initiative panel.<br />
</syntaxhighlight><br />
<br />
|also=<br />
[[setInitiative | setInitiative()]] [[addAllPCsToInitiative | addAllPCsToInitiative()]] [[addAllToInitiative | addAllToInitiative()]]<br />
<br />
}}<br />
[[Category:Initiative Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Experimental&diff=11414Category:Experimental2021-06-26T16:20:08Z<p>Melek: Created page with "Category:Macro Function"</p>
<hr />
<div>[[Category:Macro Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Pythagorean&diff=11413Category:Pythagorean2021-06-26T16:19:46Z<p>Melek: Created page with "Category:Mathematical Function"</p>
<hr />
<div>[[Category:Mathematical Function]]</div>Melekhttps://wiki.rptools.info/index.php?title=Category:Sandbox&diff=11412Category:Sandbox2021-06-26T16:18:52Z<p>Melek: Created page with "Category:Meta"</p>
<hr />
<div>[[Category:Meta]]</div>Melekhttps://wiki.rptools.info/index.php?title=VideoTutorial&diff=11411VideoTutorial2021-06-26T16:16:18Z<p>Melek: Correct category</p>
<hr />
<div>==Example VideoTutorial Template Output==<br />
This is a sandbox page for execution of [[Template:VideoTutorial]] and related experiments.<br />
<br />
===Template Use===<br />
<code><nowiki>{{VideoTutorial | 9rVo2Yj-xcw | Tom Chapman's first MapTool tutorial | The most watched tutorial series for MapTool.}}</nowiki></code><br />
===Result===<br />
{{VideoTutorial|9rVo2Yj-xcw|Tom Chapman's first MapTool tutorial|The most watched tutorial series for MapTool.}}<br />
<br />
[[Category:Sandbox]]</div>Melek