Combatscript

on("chat:message", function(msg) {
// Exit if not an api command
if (msg.type != "api") return;

// Get the API Chat Command
msg.who = msg.who.replace(" (GM)", "");
msg.content = msg.content.replace("(GM) ", "");
var n = msg.content.split(" ");
var command = n[0].toLowerCase();

// log (msg.content); log (msg.inlinerolls.length);

// Set the temp hp value on the selected token(s) or target(s)…
// Usage: !setthp amount target
if (msg.type == "api" && command == "!setthp") {
if (n.length < 2 ) {
sendChat("ERROR", "/w " + msg.who + " You must include how many temporary hit points to set.");
return;
}

// Define variables…
var TargetID = n[1];
var TempHP2Add = n[2];

if(TempHP2Add.indexOf("d") != -1) {
sendChat('', '/r ' + TempHP2Add, function(outs) {
// outs[0] is a message object containing the results of the die roll in parts[0]
// This sendChat message will NOT appear in the actual chat window
// var rollresult = JSON.parse(outs[0].content);
// var total = rollresult.total;
var DiceRolled = TempHP2Add;
var Token = getObj("graphic", TargetID);
TempHP2Add = JSON.parse(outs[0].content).total;
state[Token.id] = {"TempHP": TempHP2Add};
sendChat("STATUS", "/w " + msg.who + " You have set " + DiceRolled + " (" + TempHP2Add + ") temporary hit points on " + Token.get("name") + ".");
sendChat("STATUS", "/w GM " + msg.who + " set " + DiceRolled + " (" + TempHP2Add + ") temporary hit points on " + Token.get("name") + ".");
});
} else {
var Token = getObj("graphic", TargetID);
state[Token.id] = {"TempHP": TempHP2Add};
sendChat("STATUS", "/w " + msg.who + " You have set " + TempHP2Add + " temporary hit points on " + Token.get("name") + ".");
sendChat("STATUS", "/w GM " + msg.who + " set " + TempHP2Add + " temporary hit points on " + Token.get("name") + ".");
}
}

// Check temp hp on a target
// Usage: !chkthp target <— Checks the temp hp on the target
if (msg.type == "api" && command == "!chkthp") {
// Define variables…
var TargetID = n[1];
var Token = getObj("graphic", TargetID);
var TargetName = Token.get("name");
if (Token.id in state) {
var TempHP = parseInt(state[Token.id]["TempHP"]);
} else {
var TempHP = 0;
}
sendChat("STATUS", "/w " + msg.who + " " + TargetName + " has " + TempHP + " temporary hit points.");
}

// Make a roll only the GM can see. Do NOT use anydouble square brackets for inline rolls!
// Usage: !sroll diceroll
if (msg.type == "api" && command == "!sroll") {
msg.content = msg.content.replace("!sroll", "");
msg.content = msg.content.trim();
sendChat("Secret Roll by " + msg.who, "/w gm [[" + msg.content + " ]]");
}

// Removes all status markers from selected tokens
// Usage: !clear
if (msg.type == "api" && command == "!clear") {
_.each(msg.selected, function(obj) {
var token = getObj("graphic", obj._id);
token.set("statusmarkers", "");
});
}

// Resets selected tokens to their fully healed state
// Usage: !reset
if (msg.type == "api" && command == "!reset") {
_.each(msg.selected, function(obj) {
// Get the token and its max bar values…
var token = getObj("graphic", obj._id);
var Bar1Max = token.get("bar1_max");
var Bar2Max = token.get("bar2_max");
var Bar3Max = token.get("bar3_max");

// If the token represents a character, check to see if the token
// has any default icons to set. Usage should be markername@value
// Example: grenade@2
var DefaultIcons = "";
if (token.get("represents") != "") {
DefaultIcons = findObjs({_type: "attribute", name: "DefaultIcons", _characterid: token.get("represents")})[0];
if (DefaultIcons != undefined) {
DefaultIcons = DefaultIcons.get("current");
} else {
DefaultIcons = "";
}
}
// Reset values and remove all status markers…
if (Bar1Max != null) token.set("bar1_value", Bar1Max);
if (Bar2Max != null) token.set("bar2_value", Bar2Max);
if (Bar3Max != null) token.set("bar3_value", Bar3Max);
token.set("statusmarkers", DefaultIcons);
});
}

if (msg.type == "api" && msg.content.indexOf("!eot") !== -1) {
var c = Campaign();
var pre_turnorder = c.get('turnorder');
if (!pre_turnorder) { return; }
var turn_order = JSON.parse(c.get('turnorder'));
if (!turn_order.length) { return; };
var turn = turn_order.shift();
turn_order.push({
id: turn.id,
pr: turn.pr,
custom: "Turn Counter"
});
Campaign().set("turnorder", JSON.stringify(turn_order));
TurnOrderAgent();
}

if (command == "!power") {
// Create the PowerCard object array
var n = msg.content.split(" —");
var inlinerolls = msg.inlinerolls;
var NumberOfAttacks = 1;
var PowerCard = {};
var key = "";
var i = 1;
while (n[i]) {
key = n[i].substring(0, n[i].indexOf(" "));
if (key.substring(0, 6).toLowerCase() == "attack") {
NumberOfAttacks = parseInt(key.substring(6));
if(NumberOfAttacks == 0 || !NumberOfAttacks) NumberOfAttacks = 1;
key = "attack";
}
PowerCard[key] = n[i].substring(n[i].indexOf(" ")+1);
i++;
}

// Default PowerCard Variables
var TitleStyle = " color: #FFF; font-size: large; font-weight: bold; font-family: Times; text-align: center; padding: 5px 10px;";
var AtWill = " background-color: #060;";
var Encounter = " background-color: #600;";
var Daily = " background-color: #666;";
var Odd = " background-color: #CEC7B6;";
var Even = " background-color: #B6AB91;";
var RowStyle = " padding: 5px;";
var RowBackground = Odd;
var RowNumber = 1;
var InlineStyle = " width: 1.75em; padding: 0px; font-weight: bold; cursor: crosshair; text-align: center; vertical-align: middle; background-color: #fef68e;";
var InlineBorder = " border: 3px solid #fef68e;";
var CritHitBorder = " border: 3px solid #0C0;";
var CritMissBorder = " border: 3px solid #C00;";
var Count = 0;

// TITLE - Set the background color of the title card based on PowerCard.usage
if (PowerCard.usage == "daily") { TitleStyle += Daily; }
else if (PowerCard.usage == "encounter") { TitleStyle += Encounter; }
else { TitleStyle += AtWill; }
DisplayCard = "<div style='" + TitleStyle + "'>" + PowerCard.name + "</div>";

// TRIGGER
if (PowerCard.trigger != undefined) {
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };
RowNumber += 1;
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><b>Trigger:</b> " + PowerCard.trigger + "</div>";
}

// REQUIREMENT
if (PowerCard.require != undefined) {
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };
RowNumber += 1;
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><b>Requirement:</b> " + PowerCard.require + "</div>";
}

// SPECIAL
if (PowerCard.special != undefined) {
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };
RowNumber += 1;
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><b>Special:</b> " + PowerCard.special + "</div>";
}

// ATTACK
if (PowerCard.attack != undefined) {
var AttackRolls = 1;
var CriticalHitMessage = "";
var AttackNumber = parseInt(PowerCard.attack.substring(3).replace("]]", ""));
var AttackTotal = msg.inlinerolls[AttackNumber].results.total;
var AttackRolled = msg.inlinerolls[AttackNumber].results.rolls[0].results[0].v;
var AttackBonus = AttackTotal - AttackRolled;
var AttackTooltip = msg.inlinerolls[AttackNumber].expression.replace("1d20", "[1d20]");
while (AttackRolls <= NumberOfAttacks) {
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };

// Make an attack roll and check for critical hit or miss…
var AttackRoll = randomInteger(20);
if (AttackRoll == 20) {
CriticalHitMessage = " (Critical hit!)";
InlineBorder = CritHitBorder;
} else if (AttackRoll == 1) {
CriticalHitMessage = " (Critical miss!)";
InlineBorder = CritMissBorder;
} else {
CriticalHitMessage = "";
InlineBorder = " border: 3px solid #fef68e;"
}
// Add the attack roll to the DisplayCard construct…
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><table style='width: 100%;'><tr><td style='width: 1.75em;'><div style='" + InlineStyle + InlineBorder + "' title='" + AttackRoll + " " + AttackTooltip + "'>" + (AttackRoll + AttackBonus) + "</div></td><td style='padding-left: 5px;'> vs " + PowerCard.defense + CriticalHitMessage + "</td></tr></table></div>";

// Increment row number and the number of attack rolls completed…
RowNumber += 1;
AttackRolls += 1;
}
}

// Damage Roll
if (PowerCard.damage != undefined) {
var dmg = PowerCard.damage.substring(3).replace("]]", "");
var PowerDamageTotal = msg.inlinerolls[dmg].results.total;
var PowerDamageRoll = msg.inlinerolls[dmg].expression;
var DamageRollBorder = "#fef68e";

// Alternates the background color…
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };
RowNumber += 1;

// Adds the damage line to the DisplayCard
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><table width='100%'><tr><td style='width: 1.75em;'><div style='width: 1.75em; text-align: center; vertical-align: middle; background-color: #fef68e; border: 3px solid " + DamageRollBorder + "; padding: 0px; font-weight: bold; cursor: crosshair;' title='" + PowerDamageRoll + "'>" + PowerDamageTotal + "</div></td><td style='text-align: left; padding-left: 5px;'>" + "" + " damage</td></tr></table></div>";
}

// On Hit
if (PowerCard.onhit != undefined) {
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };
RowNumber += 1;
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><b>On Hit:</b> " + PowerCard.onhit + "</div>";
}

// On Miss
if (PowerCard.onmiss != undefined) {
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };
RowNumber += 1;
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><b>On Miss:</b> " + PowerCard.onmiss + "</div>";
}

// Effect
if (PowerCard.effect != undefined) {
if (RowNumber%2 == 1) { RowBackground = Odd; }
else { RowBackground = Even };
RowNumber += 1;
DisplayCard += "<div style='" + RowStyle + RowBackground + "'><b>Effect:</b> " + PowerCard.effect + "</div>";
}

while (Count < msg.inlinerolls.length) {
// Check for Min/Max rolls…
var RollTotal = msg.inlinerolls[Count].results.total;
var RollResult = 1; // msg.inlinerolls[Count].results.rolls[0].results[0].v;
var RollTooltip = msg.inlinerolls[Count].expression;
var InlineRoll = "<div style='display: inline; " + InlineStyle + InlineBorder + "' title='" + RollResult + " " + RollTooltip + "'>" + RollTotal + "</div>";
log(msg.inlinerolls[Count]);
// Replace inline roll placeholder in DisplayCard
DisplayCard = DisplayCard.replace("$[[" + Count + "]]", InlineRoll);
Count += 1;
}

// Send output to chat…
sendChat(msg.who, "/emas " + PowerCard.emote);
sendChat("", "/direct " + DisplayCard);
}
});