Skip to content

Commit 2610407

Browse files
authoredJun 24, 2024
Merge pull request Roll20#1953 from DameryDad/RoundMasterAPI
RoundMaster --state-extract & -load
2 parents 5127b5a + 9900f21 commit 2610407

File tree

3 files changed

+7234
-11
lines changed

3 files changed

+7234
-11
lines changed
 

‎RoundMaster/5.056/RoundMaster.js

+7,110
Large diffs are not rendered by default.

‎RoundMaster/RoundMaster.js

+122-9
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,15 @@ API_Meta.RoundMaster={offset:Number.MAX_SAFE_INTEGER,lineCount:-1};
127127
* "duration" and "direction" as well as save mods. Addition of '#' to RPGM maths to
128128
* represent number of creatures targeted with a --target multi. Fix support of ^^duration^^
129129
* tag in effects.
130+
* v5.056 22/06/2024 Added --state-extract & --state-load functions to support migration to JumpGate
130131
**/
131132

132133
var RoundMaster = (function() {
133134
'use strict';
134-
var version = 5.055,
135+
var version = 5.056,
135136
author = 'Ken L. & RED',
136137
pending = null;
137-
const lastUpdate = 1717750563;
138+
const lastUpdate = 1719059275;
138139

139140
var RW_StateEnum = Object.freeze({
140141
ACTIVE: 0,
@@ -158,6 +159,7 @@ var RoundMaster = (function() {
158159

159160
var msg_orig = {};
160161
var undoList = {};
162+
const doneMsgDiv = '<div style="color:green;font-weight:bold;border:2px solid black;background-color:white;border-radius:1em;padding:1em;">' ;
161163

162164
var fields = {
163165
feedbackName: 'RoundMaster',
@@ -793,18 +795,19 @@ var RoundMaster = (function() {
793795

794796
var handouts = Object.freeze({
795797
RoundMaster_Help: {name:'RoundMaster Help',
796-
version:1.13,
798+
version:1.14,
797799
avatar:'https://s3.amazonaws.com/files.d20.io/images/257656656/ckSHhNht7v3u60CRKonRTg/thumb.png?1638050703',
798800
bio:'<div style="font-weight: bold; text-align: center; border-bottom: 2px solid black;">'
799-
+'<span style="font-weight: bold; font-size: 125%">RoundMaster Help v1.13</span>'
801+
+'<span style="font-weight: bold; font-size: 125%">RoundMaster Help v1.14</span>'
800802
+'</div>'
801803
+'<div style="padding-left: 5px; padding-right: 5px; overflow: hidden;">'
802804
+'<h1>RoundMaster API v'+version+'</h1>'
803-
+'<p><span style='+design.selected_button+'>New:</span> RPGM maths for duration & direction of --target</p>'
804-
+'<p><span style='+design.selected_button+'>New:</span> Saving throw mods & prompts for --target commands</p>'
805-
+'<p><span style='+design.selected_button+'>New:</span> <b>--target multi</b> to target status changes for multiple tokens</p>'
806-
+'<p><span style='+design.selected_button+'>New:</span> <b>--target-nosave</b> and <b>--target-save</b> to deny/force GM <i>confirm</i></p>'
807-
+'<p><span style='+design.selected_button+'>New:</span> <b>--nosave on/off</b> configures --target-nosave behaviour</p>'
805+
+'<p><span style='+design.selected_button+'>New for v5.056:</span> <b>--state-extract</b> & <b>--state-load</b> support campaign copying</p>'
806+
+'<p><span style='+design.selected_button+'>New for v5.055:</span> RPGM maths for duration & direction of --target</p>'
807+
+'<p><span style='+design.selected_button+'>New for v5.055:</span> Saving throw mods & prompts for --target commands</p>'
808+
+'<p><span style='+design.selected_button+'>New for v5.055:</span> <b>--target multi</b> to target status changes for multiple tokens</p>'
809+
+'<p><span style='+design.selected_button+'>New for v5.055:</span> <b>--target-nosave</b> and <b>--target-save</b> to deny/force GM <i>confirm</i></p>'
810+
+'<p><span style='+design.selected_button+'>New for v5.055:</span> <b>--nosave on/off</b> configures --target-nosave behaviour</p>'
808811
+'<p>RoundMaster is an API for the Roll20 RPG-DS. Its purpose is to extend the functionality of the Turn Tracker capability already built in to Roll20. It is one of several other similar APIs available on the platform that support the Turn Tracker and manage token and character statuses related to the passing of time: the USP of this one is the full richness of its functionality and the degree of user testing that has occurred over a 12 month period.</p>'
809812
+'<p>RoundMaster is based on the much older TrackerJacker API, and many thanks to Ken L. for creating TrackerJacker. However, roundMaster is a considerable fix and extension to TrackerJacker, suited to many different applications in many different RPG scenarios. RoundMaster is also the first release as part of the wider RPGMaster series of APIs for Roll20, composed of <b>RoundMaster, CommandMaster, InitiativeMaster, AttackMaster, MagicMaster</b> and <b>MoneyMaster</b> - other than RoundMaster (which is generic) these initially support only the AD&D2e RPG.</p>'
810813
+'<p><b><u>Note:</u></b> For some aspects of the APIs to work, the <b>ChatSetAttr API</b> and the <b>Tokenmod API</b>, both from the Roll20 Script Library, must be loaded. It is also <i>highly recommended</i> to load all the other RPGMaster series APIs listed above. This will provide the most immersive game-support environment</p>'
@@ -872,6 +875,8 @@ var RoundMaster = (function() {
872875
+'--deltargetstatus tokenID|status(es) / ALL<br>'
873876
+'--delglobalstatus status(es) / ALL<br>'
874877
+'--movestatus<br>'
878+
+'--state-extract<br>'
879+
+'--state-load [RPGM/ALL/API-Name]<br>'
875880
+'--disptokenstatus [tokenID]<br>'
876881
+'--dancer cmd|tokenID|weapon|[plusChange]|[duration]<br>'
877882
+'--listmarkers<br>'
@@ -1009,6 +1014,17 @@ var RoundMaster = (function() {
10091014
+'<p>Works the same as removetargetstatus command, except that it does not run any effect macros.</p>'
10101015
+'<pre>!rounds --movestatus</pre>'
10111016
+'<p>For each of the selected tokens in turn, searches for tokens in the whole campaign with the same name and representing the same character sheet, and moves all existing statuses and markers from all the found tokens to the selected token (removing any duplicates). This supports Players moving from one Roll20 map to another and, indeed, roundMaster detects page changes and automatically runs this command for all tokens on the new page controlled by the Players who have moved to the new page.</p>'
1017+
+'<pre>!rounds --state-extract<br>'
1018+
+'!rounds --state-load [RPGM/ALL/API-Name][|API-Name2|API-Name3|...]</pre>'
1019+
+'<p><span style='+design.selected_button+'>New for v5.056:</span> These commands extract the current Roll20 <i>state variable</i> for the current campaign to a character sheet called "StatusMule", ready to be copied or transmogrified to a new (identical) campaign, and then provide the ability to load all or part of the <i>state variable</i> into the copy campaign. This provides support for Roll20 upgrades, such as <b><i>JumpGate</i></b>.</p>'
1020+
+'<p>The <i>--state-extract</i> command does not take any arguments, and extracts the whole Roll20 <i>state variable</i> for the current campaign in JSON text form to the "State" ability on the character sheet "StatusMule".</p>'
1021+
+'<p>The <i>--state-load</i> command takes one text argument, which can be:</p>'
1022+
+'<table>'
1023+
+'<tr><th>RPGM</th><td>Loads only the parts of the state variable relevant to the currently installed RPGMaster Mods - including RoundMaster</td></tr>'
1024+
+'<tr><th>ALL</th><td>Loads the whole state variable for all installed Mods (See Note below)</td></tr>'
1025+
+'<tr><th>API-names</th><td>Loads the state variables for the named API/Mod(s). Additional names can be separated with pipes "|" (See note below).</td></tr>'
1026+
+'</table>'
1027+
+'<p><b>Note:</b> Individual API / Mod names are case sensitive (except for RPGM API names, which are checked & corrected automatically). <i><u>No guarantee is given<u> for the validity or effect of loading non-RPGM API / Mod state variables.</i> You should only load non-RPGM state variables to a copy of a campaign you are prepared to loose if the load does not work properly.</p>'
10121028
+'<pre>!rounds --disptokenstatus [tokenID]</pre>'
10131029
+'<p>Shows the statuses on the specified token to the DM using the same display format as used in the Turn Announcement.</p>'
10141030
+'<pre>!rounds --dancer [INHAND/REBUILD]|tokenID|weapon|[plusChange]|[duration]</pre>'
@@ -5943,6 +5959,97 @@ var RoundMaster = (function() {
59435959
return;
59445960
}
59455961

5962+
/**
5963+
* Extract the whole status object to a character sheet
5964+
* to be transmogrified to another game (generally a copy)
5965+
* so that effects and other configuration options are
5966+
* also copied across
5967+
**/
5968+
5969+
var doExtractState = function(senderId) {
5970+
5971+
var stateMule = findObjs({type: 'character',name: 'StatusMule'},{caseInsensitive:true});
5972+
if (!stateMule || !stateMule.length) {
5973+
stateMule = createObj('character',{name: 'StatusMule'});
5974+
} else {
5975+
stateMule = stateMule[0];
5976+
}
5977+
if (!stateMule) {
5978+
sendError('Unable to create state mule');
5979+
return;
5980+
}
5981+
var stateText = JSON.stringify(state);
5982+
if (!stateText || !stateText.length) {
5983+
sendError('Unable to create the JSON string of current state');
5984+
return;
5985+
}
5986+
var muleObj = findObjs({type:'ability',characterid:stateMule.id,name:'State'},{caseInsensitive:true});
5987+
if (!muleObj || !muleObj.length) {
5988+
muleObj = createObj('ability',{name:'State',characterid:stateMule.id});
5989+
} else {
5990+
muleObj = muleObj[0];
5991+
}
5992+
if (!muleObj) {
5993+
sendError('Not able to create state mule ability');
5994+
return;
5995+
}
5996+
muleObj.set('action',stateText);
5997+
sendFeedback(doneMsgDiv + 'State extracted to StatusMule character sheet. Transmogrify to desired Campaign copy, then run *!rounds --state-load RPGM*.</div>');
5998+
return;
5999+
};
6000+
6001+
/**
6002+
* Load a JSON version of the state object from a
6003+
* State Mule character sheet.
6004+
**/
6005+
6006+
var doLoadState = function(args, senderId) {
6007+
6008+
var loadState = args[0] || 'rpgm',
6009+
stateMule = findObjs({type:'character',name:'StatusMule'},{caseInsensitive:true});
6010+
if (!stateMule || !stateMule.length) {
6011+
sendError('Unable to find StatusMule character sheet');
6012+
return;
6013+
} else {
6014+
stateMule = stateMule[0];
6015+
};
6016+
var muleObj = findObjs({type:'ability',characterid:stateMule.id,name:'State'},{caseInsensitive:true});
6017+
if (!muleObj || !muleObj.length) {
6018+
sendError('Not able to find State ability');
6019+
return;
6020+
} else {
6021+
muleObj = muleObj[0];
6022+
};
6023+
var stateObj = JSON.parse(muleObj.get('action'));
6024+
if (!stateObj) {
6025+
sendError('State ability is blank or incorrectly formatted');
6026+
return;
6027+
}
6028+
const states = 'RPGMaster|libRPGMaster|roundMaster|initMaster|moneyMaster|attackMaster|MagicMaster|CommandMaster';
6029+
switch (loadState.toLowerCase()) {
6030+
case 'all':
6031+
state = stateObj;
6032+
break;
6033+
case 'rpgm':
6034+
loadState = states;
6035+
default:
6036+
if (!loadState || !loadState.length) break;
6037+
let lowerState = states.toLowerCase().split('|');
6038+
let stateArray = states.split('|');
6039+
_.each( loadState.trim().toLowerCase().split('|').filter( s => !!s ), s => {
6040+
let ls = stateArray[lowerState.indexOf(s)];
6041+
if (s && s.length && stateObj[ls]) {
6042+
state[ls] = stateObj[ls];
6043+
}
6044+
});
6045+
break;
6046+
};
6047+
6048+
sendFeedback(doneMsgDiv + 'States for '+loadState+' loaded from the StatusMule character sheet.</div>');
6049+
return;
6050+
}
6051+
6052+
59466053
/**
59476054
* Update or create the help handouts
59486055
**/
@@ -6574,6 +6681,12 @@ var RoundMaster = (function() {
65746681
case 'stop':
65756682
if (isGM) doStopTracker();
65766683
break;
6684+
case 'state-extract':
6685+
if (isGM) doExtractState(senderId);
6686+
break;
6687+
case 'state-load':
6688+
if (isGM) doLoadState(arg,senderId);
6689+
break;
65776690
case 'target':
65786691
doTarget(arg,senderId,selected);
65796692
break;

‎RoundMaster/script.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"$schema": "https://github.com/DameryDad/roll20-api-scripts/blob/RoundMasterAPI/RoundMaster/Script.json",
33
"name": "RoundMaster",
44
"script": "RoundMaster.js",
5-
"version": "5.055",
6-
"previousversions": ["3.020","3.022","3.024","3.025","3.026","3.027","3.029","4.033","4.034","4.035","4.036","4.038","4.039","4.040","4.041","4.042","4.043","4.044","4.045","4.046","4.047","4.048","5.049","5.050","5.051","5.052","5.053","5.054"],
5+
"version": "5.056",
6+
"previousversions": ["3.020","3.022","3.024","3.025","3.026","3.027","3.029","4.033","4.034","4.035","4.036","4.038","4.039","4.040","4.041","4.042","4.043","4.044","4.045","4.046","4.047","4.048","5.049","5.050","5.051","5.052","5.053","5.054","5.055"],
77
"description": "RoundMaster is an API for the Roll20 RPG-DS. Its purpose is to extend the functionality of the Turn Tracker capability already built in to Roll20. It is one of several other similar APIs available on the platform that support the Turn Tracker and manage token and character statuses related to the passing of time: the USP of this one is the full richness of its functionality including token status effect macros that make real things happen.[RoundMaster Documentation](https://wiki.roll20.net/Script:RoundMaster) \n\n### Related APIs\nThis API works best with the RPGMaster series of APIs, and most especially the InitMaster API\n[RPGMaster Documentation](https://wiki.roll20.net/RPGMaster)\n[InitMaster Documentation](https://wiki.roll20.net/Script:InitMaster) \n\n### If using with InitMaster\n* As a Macro in the DM's macro quick bar, add the command `!init --maint` to manage RoundMaster functions\n* Add the command `!init --menu` as an Ability Macros on Character Sheets of Characters, NPCs & Monsters that will use the API, and tick 'Show as Token Action'. These menus will then be available to Players controlling those sheets and give access to all common commands used in game-play.\n\n### Further Information\nRoundMaster is based on the much older TrackerJacker API, and many thanks to Ken L. for creating TrackerJacker. However, RoundMaster is a considerable fix and extension to TrackerJacker, suited to many different applications in many different RPG scenarios. On loading, RoundMaster will create handouts in the Campaign with help on all its commands and functions. It will also create a Character Sheet database of Effect macros - see the documentation in the handouts for more information.",
88
"authors": "Richard E. based on TrackerJacker by Ken L.",
99
"roll20userid": "6497708",

0 commit comments

Comments
 (0)
Please sign in to comment.