Skip to content

Commit c76fd76

Browse files
committed
Readme update
1 parent 174ace5 commit c76fd76

File tree

3 files changed

+223
-20
lines changed

3 files changed

+223
-20
lines changed

CardTables/cardtable.js renamed to CardTables/0.0/cardtable.js

+21-20
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
function parseTable(keys,values){
1+
// cardtable.js - version 1.0
2+
3+
function parseTable(keys,values){ //This function takes an array of keys and an array of values and returns an array of objects, each object representing one row of the table
24
table=[]
35
for (row of values) {
46
object={}
5-
array=row.split("\t") //Change this to \t in final stage
7+
array=row.split("\t")
68
object.roll=array[0].replace(/\./g,"").trim()
79
for ([idx,key] of keys.entries()){
810
object[key]=array[idx+1].replace(/^([0-9]+\.)/gm,"").trim()
@@ -13,7 +15,7 @@ function parseTable(keys,values){
1315
return table
1416
}
1517

16-
function copyRows(table){
18+
function copyRows(table){ //This function checks if any row of the table has a range of rolls and then copies the row to make a separate entry for each roll value
1719
for (row of table){
1820
if (row.roll.includes("-")){
1921
min=parseInt(row.roll.split("-")[0])
@@ -30,7 +32,7 @@ function copyRows(table){
3032
return table
3133
}
3234

33-
function makeMacro(namestr,table,dicestr,color,end=1,mlen=0){
35+
function makeMacro(namestr,table,dicestr,color,end=1,mlen=0){ // This function takes all the information from the table entered into the chat and converts into a scriptcard to be then put into a macro
3436
if (mlen==0){
3537
macro=["!scriptcard{{","--#title|"+namestr,"--#titlecardgradient|1","--#titlecardbottomborder|1px solid black","--#titleCardBackground|"+color]
3638
}
@@ -61,29 +63,27 @@ on("chat:message", function(msg) {
6163
var colors=["#cb99c9","#fdfd96","#ff6961","#ff694f","#ff9899","#ffb7ce","#ca9bf7","#87cded","#0165fc","#41fdfe","#1974d2","#24a0ed","#1ac1dd","#c4fff7","#7df9ff","#3f00ff","#00fdff","#1166ff","#15f2fd","#04d9ff","#0203e2","#0044ff","#00bffe","#010fcc","#d0ff14","#8cff9e","#cfff00","#66ff00","#87fd05","#9dff00","#c1f80a","#21fc0d","#08ff08","#00ff00","#aeff6e","#53fe5c","#56fca2","#4efd54","#aaff32","#7af9ab","#a0d404","#00fa9a","#45cea2","#39ff14","#77dd77","#19a700","#68e52f","#7ded17","#00f900","#00ff7c","#06c2ac","#0add08","#2fef10","#fea051","#fe6700","#ff7034","#ffc82a","#ff7124","#eb5030","#ed872d","#fd6f3b","#ffa600","#ee8800","#ff7f50","#ffa812","#fc642d","#ff3503","#ffcf00","#eb6123","#ff8d28","#ffa62b","#f08300","#ffa368","#ff9889","#ff9933","#ff5721","#ffa500","#ff7f00","#ffa000","#ff6f52","#fa5b3d","#fc845d","#ff7518","#fc9e21","#ff6600","#ff9300","#ff7420","#ff5f00","#fe01b1","#ff85ff","#ff7fa7","#d90166","#f4bfff","#ff0490","#fe1493","#fd3f92","#ee6d8a","#ff00cc","#ff028d","#ffb3de","#ff00ff","#ff2feb","#fe4164","#fe019a","#ff66ff","#ff1476","#f62681","#d648d7","#df4ec8","#e25098","#f6688e","#ca2c92","#fe02a2","#ff1cae","#ff6ffc","#ff878d","#f06fff","#fb5ffc","#be03fd","#ad0afd","#6600ff","#bf00ff","#8f00f1","#cb00f5","#b56edc","#bc13fe","#e0b0ff","#65318e","#b80ce3","#9f00ff","#ff000d","#e30022","#f7022a","#f2013f","#ff4040","#e60000","#d01c1f","#fe0002","#ff5555","#eb5406","#fd5956","#f1172f","#cf1020","#bc2731","#fc2847","#ff073a","#ff1b2d","#fe4401","#f43605","#f10c45","#d22d1d","#b0054b","#dd1133","#b00149","#e30b5d","#ff0000","#ee204d","#ff3f34","#fa2a55","#e40078","#fe2713","#f8481c","#fe2c54","#ca0147","#ff2400","#bb1237","#d73c26","#ff1111","#ec2d01","#b21807","#fd0d35","#bf1932","#c6174e","#ef3939","#cc0033","#ff006c","#f70d1a","#e56024","#eddd59","#fffc79","#fffd01","#ffff81","#fff600","#fcfc5d","#fcd116","#ffff31","#fedf08","#ffff33","#fffc00","#ffd700","#fff700","#f1ff62","#f0e681","#cfff04","#d1e231","#ffc324","#fada50","#eed202","#f4c430","#ffd800","#f7b718","#e8ff2a","#ffdc41","#dfff4f","#ffe302","#f7c114","#ffff00","#ffef00","#ffff11","#ffcc3a","#fcfd74","#fff000","#ffff14"]
6264
color=colors[Math.floor(Math.random() * colors.length)];
6365

64-
//var str="!cardtable{{<br/>m-table-name<br/>d20|key1|key2|key3<br/>1-3|2|3|9<br/>4|5|6|8<br/>-----<br/>d21|key1|key2|key3<br/>1-5|2|3|9<br/>4|5|6|8<br/>-----<br/>d22|key1|key2|key3<br/>1-7|2|3|9<br/>4|5|6|8<br/>}}" //=String(msg.content)
65-
//var str="!cardtable{{<br/>s-table-name<br/>d20+d8|key1|key2|key3<br/>1-7|2|3|9<br/>4|5|6|8<br/>}}" //=String(msg.content)
6666
var str=String(msg.content)
6767
str=str.replace(/(\r\n|\n|\r)/gm, "");
6868
str=str.split("<br/>").slice(1,-1)
6969
macroName=str[0]
7070
namestr=macroName.split("-").slice(1).map(w => w[0].toUpperCase() + w.substring(1).toLowerCase()).join(' ')
71-
if (macroName.split('-')[0]=="s"){
71+
if (macroName.split('-')[0]=="s"){ // this checks if input is a single or multi table entry
7272

7373
values=str.slice(2)
74-
if (str[1].split("\t").length==1 && str[2].split("\t").length>1){
75-
roller="d"+String(values.length)
74+
if (str[1].split("\t").length==1 && str[2].split("\t").length>1){ // This and the next few conditions check and correct for data formatting issues like not separating the rolls and values by tabs, having extra characters in the rolls column, etc.
75+
roller="d"+String(values.length) // This particular condition is to check if the header is not formatted correctly but the values are formatted correctly
7676
str[1]=roller+"\t"+str[1]
7777
}
78-
else if (str[1].split("\t").length==1 && str[2].split("\t").length==1){
78+
else if (str[1].split("\t").length==1 && str[2].split("\t").length==1){ // If the header and values are both formatted incorrectly
7979
flag=0
8080
for (v=0;v<values.length;v++) {
8181
if(/^((\[|\()* *[0-9]+ *- *[0-9]+ *(\]|\))*)|^[0-9]+/g.test(values[v])==false){
8282
flag=1
8383
break;
8484
}
8585
}
86-
if (flag==0) {
86+
if (flag==0) { // If each row value starts with a number or a range of numbers then interpret that as the roll values and separate them into a different column
8787
max=values.length
8888
for (v=0;v<values.length;v++) {
8989
r=values[v].match(/^((\[|\()* *[0-9]+ *- *[0-9]+ *(\]|\))*)|^[0-9]+/g)[0].replace(/(\[|\])|(\(|\))/g,"")
@@ -92,9 +92,9 @@ on("chat:message", function(msg) {
9292
val=r+"\t"+values[v].split(r)[1].replace(/^\./g,"")
9393
values[v]=val
9494
}
95-
roller="d"+String(max)
95+
roller="d"+String(max) //Correct the dice type string
9696
}
97-
else if(flag==1){
97+
else if(flag==1){ //If roll values are not present at all, assume one unique value for each row and decide a die accordingly
9898
for (v=0;v<values.length;v++) {
9999
values[v]=String(v+1)+"\t"+values[v]
100100
}
@@ -104,25 +104,25 @@ on("chat:message", function(msg) {
104104
str[1]=roller+"\t"+str[1]
105105
}
106106

107-
roller=str[1].split("\t")[0] // Change this to \t in final stage
108-
keys=str[1].split("\t").slice(1) // Change this to \t in final stage
107+
roller=str[1].split("\t")[0] //dice
108+
keys=str[1].split("\t").slice(1) //column names
109109
table=parseTable(keys,values)
110110
table=copyRows(table)
111-
dicestr=roller.split("+").map(w => "1"+w).join("+")
111+
dicestr=roller.split("+").map(w => "1"+w).join("+") //create a rollable dice string for scriptcards
112112
macro=makeMacro(namestr,table,dicestr,color)
113113
}
114-
else {
114+
else { // if the input contains multiple tables
115115
splitter=str.map((e,i) => e.includes("-----")?i:'').filter(String)
116116
tables=[]
117117
k=0
118-
for (i of splitter) {
118+
for (i of splitter) { // create an array of tables
119119
tables.push(str.slice(k,i))
120120
k=i
121121
}
122122
tables.push(str.slice(k))
123123
macro=[]
124124
k=0
125-
for (i of tables){
125+
for (i of tables){ //For each table, basically do everything that was done for the single table
126126

127127
values=i.slice(2)
128128
if (i[1].split("\t").length==1 && i[2].split("\t").length>1){
@@ -169,7 +169,7 @@ on("chat:message", function(msg) {
169169
macro.push("}}")
170170
}
171171

172-
macro=macro.join("\n")
172+
macro=macro.join("\n") // create macro
173173
createObj("macro",{
174174
name: macroName,
175175
action:macro,
@@ -179,6 +179,7 @@ on("chat:message", function(msg) {
179179
});
180180

181181
}
182+
//Help display
182183
else if (msg.type == "api" && ((msg.content.indexOf("!cardtable -h") !== -1 || msg.content.indexOf("!cardtable -h") !== -1) || (msg.content.indexOf("!cardtable -help") !== -1 || msg.content.indexOf("!cardtable -help")))) {
183184
sendChat("Cardtable help","<br><br><b>-h/-help</b>&emsp;Display this help and exit<br><br>Input data format example- <br><br><pre style='font-size: 0.8em'>!cardtable{{<br>x-table-name<br>dicetype\tkey1\tkey2\t.....<br>roll\tvalue1\tvalue2\t.....<br>.<br>.<br>.<br>-----<br>dicetype\tkey1\tkey2\t.....<br>.<br>.<br>.<br><br>}}<br><br></pre>The x in the table name needs to be replaced by s or m. s if rolling on one table is enough to generate the whole card. m if rolling on multiple tables is required (eg - weather). If using multiple tables, separate each table by a line containing \"-----\" as shown in the example format. All columns should be separated by a tab. Output is a macro with the name \"x-table-name\" and running the macro will output scriptcards")
184185
}

CardTables/1.0/cardtable.js

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// cardtable.js - version 1.0
2+
3+
function parseTable(keys,values){ //This function takes an array of keys and an array of values and returns an array of objects, each object representing one row of the table
4+
table=[]
5+
for (row of values) {
6+
object={}
7+
array=row.split("\t")
8+
object.roll=array[0].replace(/\./g,"").trim()
9+
for ([idx,key] of keys.entries()){
10+
object[key]=array[idx+1].replace(/^([0-9]+\.)/gm,"").trim()
11+
object[key]=object[key][0].toUpperCase()+object[key].slice(1)
12+
}
13+
table.push(object)
14+
}
15+
return table
16+
}
17+
18+
function copyRows(table){ //This function checks if any row of the table has a range of rolls and then copies the row to make a separate entry for each roll value
19+
for (row of table){
20+
if (row.roll.includes("-")){
21+
min=parseInt(row.roll.split("-")[0])
22+
max=parseInt(row.roll.split("-")[1])
23+
table=table.filter((el) => el!=row)
24+
for (i=min;i<=max;i++){
25+
row.roll=String(i)
26+
newrow=JSON.parse(JSON.stringify(row))
27+
table.push(newrow)
28+
}
29+
}
30+
}
31+
table.sort((a,b) => parseInt(a.roll) - parseInt(b.roll));
32+
return table
33+
}
34+
35+
function makeMacro(namestr,table,dicestr,color,end=1,mlen=0){ // This function takes all the information from the table entered into the chat and converts into a scriptcard to be then put into a macro
36+
if (mlen==0){
37+
macro=["!scriptcard{{","--#title|"+namestr,"--#titlecardgradient|1","--#titlecardbottomborder|1px solid black","--#titleCardBackground|"+color]
38+
}
39+
else{
40+
macro=[]
41+
}
42+
macro.push("--=var"+mlen+"|"+dicestr)
43+
for (i of table) {
44+
compstr=i.roll
45+
macro.push("--? [$var"+mlen+"] -eq "+compstr+"|[")
46+
for (j in i){
47+
if (j!="roll") {
48+
macro.push("--+"+j+"|"+i[j])
49+
}
50+
}
51+
macro.push("--]|")
52+
}
53+
if (end==1){
54+
macro.push("}}")
55+
}
56+
return macro
57+
}
58+
59+
60+
on("chat:message", function(msg) {
61+
if(msg.type == "api" && msg.content.indexOf("!cardtable{{") !== -1) {
62+
gmid=msg.playerid
63+
var colors=["#cb99c9","#fdfd96","#ff6961","#ff694f","#ff9899","#ffb7ce","#ca9bf7","#87cded","#0165fc","#41fdfe","#1974d2","#24a0ed","#1ac1dd","#c4fff7","#7df9ff","#3f00ff","#00fdff","#1166ff","#15f2fd","#04d9ff","#0203e2","#0044ff","#00bffe","#010fcc","#d0ff14","#8cff9e","#cfff00","#66ff00","#87fd05","#9dff00","#c1f80a","#21fc0d","#08ff08","#00ff00","#aeff6e","#53fe5c","#56fca2","#4efd54","#aaff32","#7af9ab","#a0d404","#00fa9a","#45cea2","#39ff14","#77dd77","#19a700","#68e52f","#7ded17","#00f900","#00ff7c","#06c2ac","#0add08","#2fef10","#fea051","#fe6700","#ff7034","#ffc82a","#ff7124","#eb5030","#ed872d","#fd6f3b","#ffa600","#ee8800","#ff7f50","#ffa812","#fc642d","#ff3503","#ffcf00","#eb6123","#ff8d28","#ffa62b","#f08300","#ffa368","#ff9889","#ff9933","#ff5721","#ffa500","#ff7f00","#ffa000","#ff6f52","#fa5b3d","#fc845d","#ff7518","#fc9e21","#ff6600","#ff9300","#ff7420","#ff5f00","#fe01b1","#ff85ff","#ff7fa7","#d90166","#f4bfff","#ff0490","#fe1493","#fd3f92","#ee6d8a","#ff00cc","#ff028d","#ffb3de","#ff00ff","#ff2feb","#fe4164","#fe019a","#ff66ff","#ff1476","#f62681","#d648d7","#df4ec8","#e25098","#f6688e","#ca2c92","#fe02a2","#ff1cae","#ff6ffc","#ff878d","#f06fff","#fb5ffc","#be03fd","#ad0afd","#6600ff","#bf00ff","#8f00f1","#cb00f5","#b56edc","#bc13fe","#e0b0ff","#65318e","#b80ce3","#9f00ff","#ff000d","#e30022","#f7022a","#f2013f","#ff4040","#e60000","#d01c1f","#fe0002","#ff5555","#eb5406","#fd5956","#f1172f","#cf1020","#bc2731","#fc2847","#ff073a","#ff1b2d","#fe4401","#f43605","#f10c45","#d22d1d","#b0054b","#dd1133","#b00149","#e30b5d","#ff0000","#ee204d","#ff3f34","#fa2a55","#e40078","#fe2713","#f8481c","#fe2c54","#ca0147","#ff2400","#bb1237","#d73c26","#ff1111","#ec2d01","#b21807","#fd0d35","#bf1932","#c6174e","#ef3939","#cc0033","#ff006c","#f70d1a","#e56024","#eddd59","#fffc79","#fffd01","#ffff81","#fff600","#fcfc5d","#fcd116","#ffff31","#fedf08","#ffff33","#fffc00","#ffd700","#fff700","#f1ff62","#f0e681","#cfff04","#d1e231","#ffc324","#fada50","#eed202","#f4c430","#ffd800","#f7b718","#e8ff2a","#ffdc41","#dfff4f","#ffe302","#f7c114","#ffff00","#ffef00","#ffff11","#ffcc3a","#fcfd74","#fff000","#ffff14"]
64+
color=colors[Math.floor(Math.random() * colors.length)];
65+
66+
var str=String(msg.content)
67+
str=str.replace(/(\r\n|\n|\r)/gm, "");
68+
str=str.split("<br/>").slice(1,-1)
69+
macroName=str[0]
70+
namestr=macroName.split("-").slice(1).map(w => w[0].toUpperCase() + w.substring(1).toLowerCase()).join(' ')
71+
if (macroName.split('-')[0]=="s"){ // this checks if input is a single or multi table entry
72+
73+
values=str.slice(2)
74+
if (str[1].split("\t").length==1 && str[2].split("\t").length>1){ // This and the next few conditions check and correct for data formatting issues like not separating the rolls and values by tabs, having extra characters in the rolls column, etc.
75+
roller="d"+String(values.length) // This particular condition is to check if the header is not formatted correctly but the values are formatted correctly
76+
str[1]=roller+"\t"+str[1]
77+
}
78+
else if (str[1].split("\t").length==1 && str[2].split("\t").length==1){ // If the header and values are both formatted incorrectly
79+
flag=0
80+
for (v=0;v<values.length;v++) {
81+
if(/^((\[|\()* *[0-9]+ *- *[0-9]+ *(\]|\))*)|^[0-9]+/g.test(values[v])==false){
82+
flag=1
83+
break;
84+
}
85+
}
86+
if (flag==0) { // If each row value starts with a number or a range of numbers then interpret that as the roll values and separate them into a different column
87+
max=values.length
88+
for (v=0;v<values.length;v++) {
89+
r=values[v].match(/^((\[|\()* *[0-9]+ *- *[0-9]+ *(\]|\))*)|^[0-9]+/g)[0].replace(/(\[|\])|(\(|\))/g,"")
90+
mm=r.match(/[0-9]+/g).map(w => parseInt(w)).sort().reverse()[0]
91+
max=(mm>max)?mm:max
92+
val=r+"\t"+values[v].split(r)[1].replace(/^\./g,"")
93+
values[v]=val
94+
}
95+
roller="d"+String(max) //Correct the dice type string
96+
}
97+
else if(flag==1){ //If roll values are not present at all, assume one unique value for each row and decide a die accordingly
98+
for (v=0;v<values.length;v++) {
99+
values[v]=String(v+1)+"\t"+values[v]
100+
}
101+
102+
roller="d"+String(values.length)
103+
}
104+
str[1]=roller+"\t"+str[1]
105+
}
106+
107+
roller=str[1].split("\t")[0] //dice
108+
keys=str[1].split("\t").slice(1) //column names
109+
table=parseTable(keys,values)
110+
table=copyRows(table)
111+
dicestr=roller.split("+").map(w => "1"+w).join("+") //create a rollable dice string for scriptcards
112+
macro=makeMacro(namestr,table,dicestr,color)
113+
}
114+
else { // if the input contains multiple tables
115+
splitter=str.map((e,i) => e.includes("-----")?i:'').filter(String)
116+
tables=[]
117+
k=0
118+
for (i of splitter) { // create an array of tables
119+
tables.push(str.slice(k,i))
120+
k=i
121+
}
122+
tables.push(str.slice(k))
123+
macro=[]
124+
k=0
125+
for (i of tables){ //For each table, basically do everything that was done for the single table
126+
127+
values=i.slice(2)
128+
if (i[1].split("\t").length==1 && i[2].split("\t").length>1){
129+
roller="d"+String(values.length)
130+
i[1]=roller+"\t"+i[1]
131+
}
132+
else if (i[1].split("\t").length==1 && i[2].split("\t").length==1){
133+
flag=0
134+
for (v=0;v<values.length;v++) {
135+
if(/^((\[|\()* *[0-9]+ *- *[0-9]+ *(\]|\))*)|^[0-9]+/g.test(values[v])==false){
136+
flag=1
137+
break;
138+
}
139+
}
140+
if (flag==0) {
141+
max=values.length
142+
for (v=0;v<values.length;v++) {
143+
r=values[v].match(/^((\[|\()* *[0-9]+ *- *[0-9]+ *(\]|\))*)|^[0-9]+/g)[0].replace(/(\[|\])|(\(|\))/g,"")
144+
mm=r.match(/[0-9]+/g).map(w => parseInt(w)).sort().reverse()[0]
145+
max=(mm>max)?mm:max
146+
val=r+"\t"+values[v].split(r)[1].replace(/^\./g,"")
147+
values[v]=val
148+
}
149+
roller="d"+String(max)
150+
}
151+
else if(flag==1){
152+
for (v=0;v<values.length;v++) {
153+
values[v]=String(v+1)+"\t"+values[v]
154+
}
155+
156+
roller="d"+String(values.length)
157+
}
158+
i[1]=roller+"\t"+i[1]
159+
}
160+
roller=i[1].split("\t")[0] // Change this to \t in final stage
161+
keys=i[1].split("\t").slice(1) // Change this to \t in final stage
162+
163+
table=parseTable(keys,values)
164+
table=copyRows(table)
165+
dicestr=roller.split("+").map(w => "1"+w).join("+")
166+
macro=macro.concat(makeMacro(namestr,table,dicestr,color,0,k))
167+
k+=1
168+
}
169+
macro.push("}}")
170+
}
171+
172+
macro=macro.join("\n") // create macro
173+
createObj("macro",{
174+
name: macroName,
175+
action:macro,
176+
visibleto:"all",
177+
playerid: gmid,
178+
istokenaction: false
179+
});
180+
181+
}
182+
//Help display
183+
else if (msg.type == "api" && ((msg.content.indexOf("!cardtable -h") !== -1 || msg.content.indexOf("!cardtable -h") !== -1) || (msg.content.indexOf("!cardtable -help") !== -1 || msg.content.indexOf("!cardtable -help")))) {
184+
sendChat("Cardtable help","<br><br><b>-h/-help</b>&emsp;Display this help and exit<br><br>Input data format example- <br><br><pre style='font-size: 0.8em'>!cardtable{{<br>x-table-name<br>dicetype\tkey1\tkey2\t.....<br>roll\tvalue1\tvalue2\t.....<br>.<br>.<br>.<br>-----<br>dicetype\tkey1\tkey2\t.....<br>.<br>.<br>.<br><br>}}<br><br></pre>The x in the table name needs to be replaced by s or m. s if rolling on one table is enough to generate the whole card. m if rolling on multiple tables is required (eg - weather). If using multiple tables, separate each table by a line containing \"-----\" as shown in the example format. All columns should be separated by a tab. Output is a macro with the name \"x-table-name\" and running the macro will output scriptcards")
185+
}
186+
})
187+
// Visit the <a href=\"\" style='color: blue; font-weight: bold; cursor: pointer'>wiki</a> for a more detailed guide.

CardTables/script.JSON

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "Card Tables",
3+
"script": "cardtable.js",
4+
"version": "1.0",
5+
"previousversions":["0.0"],
6+
"description":"Give your rollable tables a bit more flair or consolidate rolling on multiple tables into one macro or make rollable tables with multiple columns using ScriptCards",
7+
"authors":"Riddhi M.",
8+
"roll20userid":"9979800",
9+
"useroptions":[],
10+
"dependencies":["ScriptCards"],
11+
"modifies":{
12+
"macro":"write"
13+
},
14+
"conflicts":[]
15+
}

0 commit comments

Comments
 (0)