Skip to content

Instantly share code, notes, and snippets.

@Julexar
Created September 21, 2022 09:21
Show Gist options
  • Save Julexar/b87ed699066e06083557ea22317f4236 to your computer and use it in GitHub Desktop.
Save Julexar/b87ed699066e06083557ea22317f4236 to your computer and use it in GitHub Desktop.
/*
Resolve Tracker for D&D 5e
Made by Julexar (https://app.roll20.net/users/9989180/julexar)
API Commands:
!resolve - Shows you the reolve of a Character. (based on speaking as)
--sel - Shows the Resolve of a selected Character (Select a Token)
--charid - Shows the Resolve of a character based on ID.
--name - Shows the Resolve of a character based on name
--add {Number} - Adds a number of points to the Pool
--rem {Number} - Removes a number of points from the Pool
*/
var resolveTracker = resolveTracker || (function(){
'use strict';
var version = "1.0",
setDefaults = function() {
state.resolve = [];
},
createDefaults = function() {
let players=findObjs({
_type: 'player'
});
let char;
_.each(players, function(player) {
let id=player.get('_id');
char=findObjs({
_type: 'character',
inplayerjournals: id
}, {caseInsensitive: true});
let foundchars=[];
for (let i=0;i<char.length;i++) {
let charid=char[i].get('_id');
for (let j=0;j<state.resolve.length;j++) {
if (state.resolve[i].playerid==id && state.resolve[i].charid==charid) {
foundchars.push(i);
}
}
}
for (let i=0;i<foundchars.length;i++) {
char.splice(foundchars[i]);
}
for (let i=0;i<char.length;i++) {
let newRes = {
dice: 0,
playerid: char[i].get('inplayerjournals'),
charid: char[i].get('_id')
};
state.resolve.push(newRes);
}
});
},
handleInput = function(msg) {
var args=msg.content.split(/\s+--/);
if (msg.type!=="api") {
return;
}
createDefaults();
switch (args[0]) {
case '!resolve':
let option=args[1];
let char;
if (option==undefined) {
char=findObjs({
_type: 'character',
name: msg.who
}, {caseInsensitive: true})[0];
if (char!==undefined) {
viewResolve(char.get('_id'),msg);
}
} else if (option.includes("add")) {
char=findObjs({
_type: 'character',
name: msg.who
}, {caseInsensitive: true})[0];
if (char!==undefined) {
let amount=Number(args[1].replace("add ",""));
editResolve(char.get('_id'),"add",amount,msg);
}
} else if (option.includes("rem")) {
char=findObjs({
_type: 'character',
name: msg.who
}, {caseInsensitive: true})[0];
if (char!==undefined) {
let amount=Number(args[1].replace("add ",""));
editResolve(char.get('_id'),"rem",amount,msg);
}
} else if (option.includes("sel")) {
option=msg.selected;
let charid=getIDsFromTokens(option)[0];
char=findObjs({
_type: 'character',
_id: charid
})[0];
if (char!==undefined) {
if (args[2]==undefined) {
viewResolve(char.get('_id'));
} else if (args[2].includes("add") || args[2].includes("rem")) {
let amount=Number(args[2].replace("add ","").replace("rem ",""));
let type=args[2].replace(" "+amount,"");
editResolve(char.get('_id'),type,amount,msg);
}
}
} else if (option.includes("charid")) {
let charid=option.replace("charid ","");
char=findObjs({
_type: 'character',
_id: charid
})[0];
if (char!==undefined) {
if (args[2]==undefined) {
viewResolve(char.get('_id'));
} else if (args[2].includes("add") || args[2].includes("rem")) {
let amount=Number(args[2].replace("add ","").replace("rem ",""));
let type=args[2].replace(" "+amount,"");
editResolve(char.get('_id'),type,amount,msg);
}
}
} else if (option.includes("name")) {
let name=option.replace("name ","");
char=findObjs({
_type: 'character',
name: name
}, {caseInsensitive: true})[0];
if (char!==undefined) {
if (args[2]==undefined) {
viewResolve(char.get('_id'));
} else if (args[2].includes("add") || args[2].includes("rem")) {
let amount=Number(args[2].replace("add ","").replace("rem ",""));
let type=args[2].replace(" "+amount,"");
editResolve(char.get('_id'),type,amount,msg);
}
}
}
return;
}
},
getIDsFromTokens = function (selected) {
return (selected || []).map(obj => getObj("graphic", obj._id))
.filter(x => !!x)
.map(token => token.get("represents"))
.filter(id => getObj("character", id || ""));
},
viewResolve = function(charid,msg) {
var divstyle = 'style="width: 220px; border: 1px solid black; background-color: #ffffff; padding: 5px;"';
var astyle1 = 'style="text-align:center; border: 1px solid black; margin: 1px; background-color: #7E2D40; border-radius: 4px; box-shadow: 1px 1px 1px #707070; width: 100px;';
var astyle2 = 'style="text-align:center; border: 1px solid black; margin: 1px; background-color: #7E2D40; border-radius: 4px; box-shadow: 1px 1px 1px #707070; width: 150px;';
var tablestyle = 'style="text-align:center;"';
var arrowstyle = 'style="border: none; border-top: 3px solid transparent; border-bottom: 3px solid transparent; border-left: 195px solid rgb(126, 45, 64); margin-bottom: 2px; margin-top: 2px;"';
var headstyle = 'style="color: rgb(126, 45, 64); font-size: 18px; text-align: left; font-variant: small-caps; font-family: Times, serif;"';
var substyle = 'style="font-size: 11px; line-height: 13px; margin-top: -3px; font-style: italic;"';
var tdstyle = 'style="text-align:right;"';
let resolve=state.resolve.find(r => r.charid==charid);
let char=findObjs({
_type: 'character',
_id: charid
})[0];
if (resolve==undefined) {
sendChat("Resolve Tracker","/w "+msg.who+" No Resolve Pool exists for that Character.<br>Creating one...");
createDefaults();
} else {
let feeling;
if (resolve.dice>=6) {
feeling="You feel full of Resolve!";
} else if (resolve.dice<=0) {
feeling="You have no Resolve.";
}
if (feeling) {
sendChat("Resolve Tracker","/w "+msg.who+" <div "+divstyle+">"+//--
'<div ' + headstyle + '>Resolve Tracker</div>' + //--
'<div ' + substyle + '>' + char.get("name") + '\'s Pool</div>' + //--
'<div ' + arrowstyle + '></div>' + //--
'<table ' + tablestyle + '>' + //--
'<tr><td ' + tdstyle + '>Resolve Pool: </td><td ' + tdstyle + '>' + resolve.dice + '</td></tr>' + //--
'</table>' + //--
'<br>' + //--
feeling + //--
'<br><br>' + //--
'<div style="text-align:center;"><a ' + astyle2 + '" href="!resolve --charid ' + charid + ' --add ?{Amount?|1}">Add Resolve</a></div>' + //--
'<div style="text-align:center;"><a ' + astyle2 + '" href="!resolve --charid ' + charid + ' --rem ?{Amount?|1}">Remove Resolve</a></div>' + //--
'</div>'
);
} else {
sendChat("Resolve Tracker","/w "+msg.who+" <div "+divstyle+">"+//--
'<div ' + headstyle + '>Resolve Tracker</div>' + //--
'<div ' + substyle + '>' + char.get("name") + '\'s Pool</div>' + //--
'<div ' + arrowstyle + '></div>' + //--
'<table ' + tablestyle + '>' + //--
'<tr><td ' + tdstyle + '>Resolve Pool: </td><td ' + tdstyle + '>' + resolve.dice + '</td></tr>' + //--
'</table>' + //--
'<br><br>' + //--
'<div style="text-align:center;"><a ' + astyle2 + '" href="!resolve --charid ' + charid + ' --add ?{Amount?|1}">Add Resolve</a></div>' + //--
'<div style="text-align:center;"><a ' + astyle2 + '" href="!resolve --charid ' + charid + ' --rem ?{Amount?|1}">Remove Resolve</a></div>' + //--
'</div>'
);
}
}
},
editResolve = function(charid,type,amount,msg) {
switch (type) {
case 'add':
for (let i=0;i<state.resolve.length;i++) {
if (state.resolve[i].charid==charid) {
state.resolve[i].dice+=amount;
sendChat("Resolve Tracker","/w "+msg.who+" You now have "+Number(state.resolve[i].dice)+" Resolve.");
}
}
break;
case 'rem':
for (let i=0;i<state.resolve.length;i++) {
if (state.resolve[i].charid==charid) {
state.resolve[i].dice-=amount;
sendChat("Resolve Tracker","/w "+msg.who+" You now have "+Number(state.resolve[i].dice)+" Resolve.");
}
}
break;
}
},
checkDefaults = function() {
if (!state.resolve) {
setDefaults();
}
},
registerEventHandlers = function() {
on('chat:message', handleInput);
};
return {
CheckDefaults: checkDefaults,
RegisterEventHandlers: registerEventHandlers
};
}());
on("ready", function(){
"use strict";
resolveTracker.CheckDefaults();
resolveTracker.RegisterEventHandlers();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment