Here's a slightly modified version. It should be a little less crash-happy, and do a better job of grabbing the token ID. Make sure you use it with token_id, and not character_id - the script doesn't handle character sheets. So your macro should just be !hp @{target|token_id}. The script didn't do a whole lot with the input - an extra space after !hp would have been enough to cause a sandbox crash.
const HEALTH_DESC = [ 'Unconcious', 'Near Death', 'Badly Injured', 'Injured', 'Barely Injured', 'Uninjured', 'Dead' ];
var health_status = (function(){
return {
config: {
'health_attrib': 'bar1_value',
'health_max_attrib': 'bar1_max'
},
/**
* find and return the token object for a given token ID.
*/
getTokenTarget: function(token_id) {
// this should only return one object, buttttttttttttt...
var tokens = findObjs({type: 'graphic', subtype: 'token', id: token_id}, true);
if(tokens.length === 0) return null; // invalid ID/target doesn't exist/clicked on the map.
return tokens[0]; // return the first token found (it's probably the one we want)
},
/**
* checks if the submitted token has number/non-empty values for supplied attributes.
*/
checkTokenHealth: function(token) {
var current = token.get(this.config.health_attrib);
var max = token.get(this.config.health_max_attrib);
if (current === '' || max === '' || isNaN(current) || isNaN(max)) {
return null;
}
return current / max;
},
respond: function(content) {
// build the output message to send:
var output = '/direct \
<div style="background-color: #ffffee; border-style: solid; border-right-style: none; border-width: 1px; border-left-width: 12px; border-radius: 5px 0px 0px 5px; border-color: #b3b300; border-left-color: #aa80ff; padding: 10px;">' +
content +
'</div>';
sendChat('Health Info', output, null, {noarchive: true});
}
};
})();
on('chat:message', function(msg) {
if (msg.type == 'api') {
if (msg.content.indexOf('!hp ') !== -1) {
// trim command off:
// var target = msg.content.replace('!hp ', '');
const target = (msg.content.match(/-[A-Za-z0-9_-]{19}/)||[])[0];
const tokenObj = target ? health_status.getTokenTarget(target) : null;
if (tokenObj == null) {
health_status.respond('No target found<br /><br />ID: </b>'+target+'</b>');
return;
}
var health_val = health_status.checkTokenHealth(tokenObj);
if (health_val === null) health_status.respond('Who the what now? Your token doesn\'t have the right stats.');
// check if the token is marked as dead or not and get proper value
var health_str;
if (tokenObj.get('status_dead')) {
health_str = HEALTH_DESC[6];
}
else {
health_str = HEALTH_DESC[(Math.max(Math.min(Math.ceil(health_val * 5), 5), 0))];
}
health_status.respond('<b>'+tokenObj.get('name')+'</b> is <b>'+health_str+'</b>');
//ping the token in question so people know which one is being referred to.
var pageid = Campaign().get('playerspecificpages');
if (pageid === false) {
pageid = Campaign().get('playerpageid');
} else {
pageid = pageid[msg.playerid];
}
sendPing(tokenObj.get('left'), tokenObj.get('top'), pageid, null, false);
}
}
});