// VARIABLE & FUNCTION DECLARATIONS -- DO NOT ALTER!! var PowerCardScript = PowerCardScript || {}; var getBrightness = getBrightness || {}; var hexDec = hexDec || {}; // USER CONFIGUATION var POWERCARD_ROUNDED_CORNERS = true; var POWERCARD_ROUNDED_INLINE_ROLLS = true; var POWERCARD_BORDER_SIZE = 1; var POWERCARD_BORDER_COLOR = "#000"; var POWERCARD_USE_PLAYER_COLOR = true; on("chat:message", function(msg) { if (msg.type != "api") return; // Get the API Chat Command msg.who = msg.who.replace(" (GM)", ""); msg.content = msg.content.replace("(GM) ", ""); var command = msg.content.split(" ", 1); // !roll --versus|WeaponSkill --charactername|@{selected|character_name} --tokenname|@{selected|token_name} --modifier|?{Attack Modifier|0} --type|Attack --weapon|Primary // DEFINE VARIABLES var n = msg.content.split(" --"); var parameters = {}; var Tag = ""; var Content = ""; var RollObject = {}; var operator = "<="; // CREATE OBJECT ARRAY var a = 1; while (n[a]) { Tag = n[a].substring(0, n[a].indexOf("|")); Content = n[a].substring(n[a].indexOf("|") + 1); parameters[Tag] = Content; a++; } // Define RollObject Variables RollObject.AttributeName = parameters.versus; RollObject.AttributeValue = ""; RollObject.CharacterName = parameters.charactername; RollObject.DisplayName = parameters.tokenname; RollObject.TestModifier = parameters.modifier; RollObject.RollType = parameters.type; RollObject.DamageAdd = Number("3"); RollObject.WeaponName = "Placeholder"; RollObject.PrimaryWeapon = true; if (parameters.weapon == "Secondary") {RollObject.PrimaryWeapon = false}; RollObject.ImpactWeapon = false; RollObject.RangedAttack = false; if ((RollObject.AttributeName == "BallisticSkill") && (RollObject.RollType == "Attack")) {RollObject.RangedAttack = true}; RollObject.AmmoCount = 0; RollObject.AmmoMax = 0; RollObject.DiceRollExpression = "1d100"; RollObject.DamageRollExpression = "1d10"; RollObject.TestSuccess = "false"; RollObject.HitLocation = ""; RollObject.HitLocationToolTip = ""; RollObject.DiceRollResultToolTip = ""; RollObject.PowerCardContent = "" if (RollObject.RollType == "Attack") { RollObject.PowerCardContent = "--desc --name|" + RollObject.DisplayName + " --leftsub|" + (RollObject.RangedAttack ? "Ranged Attack" : "Melee Attack") + " --rightsub|Half Action --custom_diceroll|"; } else if (RollObject.RollType == "Parry") { RollObject.PowerCardContent = "--desc --name|" + RollObject.DisplayName + " --leftsub|Parry" + " --rightsub|Reaction --custom_diceroll|"; } else if (RollObject.RollType == "Dodge") { RollObject.PowerCardContent = "--desc --name|" + RollObject.DisplayName + " --leftsub|Dodge" + " --rightsub|Reaction --custom_diceroll|"; } else if (RollObject.RollType == "Attribute") { RollObject.PowerCardContent = "--desc --name|" + RollObject.DisplayName + " --leftsub|"+ RollObject.AttributeName + "" + " --rightsub|Stat Test --custom_diceroll|"; } else if (rollType == "Skill") { msgContent = "--desc --name|" + tokenName + " --leftsub|"+ attribute + "" + " --rightsub|Test --diceroll|"; } var characters = findObjs({ _type: "character", name: RollObject.CharacterName }); var character = characters.shift(); var rollDice = function (){ sendChat("", "[[" + RollObject.DiceRollExpression + " ]]", function (m) { var rolldata = m[0].inlinerolls[1]; RollObject.RawDiceRoll = rolldata.results.rolls; sendChat("", "[[" + RollObject.DamageRollExpression + " ]]", function (d) { var rolldata = d[0].inlinerolls[1]; RollObject.RawDamageRoll = rolldata.results.rolls; sendChat("", "[[" + RollObject.DamageRollExpression + " ]]", function (d) { var rolldata = d[0].inlinerolls[1]; RollObject.RawImpactRoll = rolldata.results.rolls; rollResult(); }); }); }); } if (command == "!roll") { rollDice(); } var rollResult = function() { RollObject.DiceRollResult = getResult(RollObject.RawDiceRoll); if (character) { var attributes = findObjs({ _type: "attribute", _characterid: character.get('_id') }); _.each(attributes, function(obj) { var attributeName = obj.get("name"); if (attributeName == RollObject.AttributeName) { RollObject.AttributeValue = obj.get("current"); } if (RollObject.RangedAttack == false) { if (RollObject.PrimaryWeapon) { if (attributeName == "MeleeWeapon") { RollObject.WeaponName = obj.get("current"); } if (attributeName == "MeleeDamage") { RollObject.DamageAdd = Number(obj.get("current")); } } else { if (attributeName == "MeleeWeapon") { RollObject.WeaponName = obj.get("max"); } if (attributeName == "MeleeDamage") { RollObject.DamageAdd = Number(obj.get("max")); } } } else { if (RollObject.PrimaryWeapon) { if (attributeName == "RangedWeapon") { RollObject.WeaponName = obj.get("current"); } if (attributeName == "RangedDamage") { RollObject.DamageAdd = Number(obj.get("current")); } } else { if (attributeName == "RangedWeapon") { RollObject.WeaponName = obj.get("max"); } if (attributeName == "RangedDamage") { RollObject.DamageAdd = Number(obj.get("max")); } } if (attributeName == "Ammo") { RollObject.AmmoCount = Number(obj.get("current")); RollObject.AmmoMax = Number(obj.get("max")); } } }); } modifiedExpression = Number(RollObject.AttributeValue) + Number(RollObject.TestModifier); var result = null; var difference = 0; var degrees = 0; var new_expression = 'result = (' + RollObject.DiceRollResult + ' ' + operator + ' ' + modifiedExpression + ');'; try { eval(new_expression); } catch (e) { //log(e); } try { difference = Math.abs(RollObject.DiceRollResult - eval(modifiedExpression)); } catch (e) { //log(e); } try { degrees = Math.floor(difference / 10); } catch (e) { //log(e); } if (result) { RollObject.TestSuccess = true; if(RollObject.RollType == "Attack") { var x = RollObject.DiceRollResult; var y = x.toString(); if (y.length == 2) { var z = y.split("").reverse().join(""); } else { var z = y + "0"; } var reverseRoll = Number(z); if(reverseRoll < 11) { RollObject.HitLocation = "Head"; RollObject.HitLocationToolTip = RollObject.DiceRollResult + " reversed is " + reverseRoll + "; 01-10 strikes Head location"; } else if (reverseRoll < 26) { RollObject.HitLocation = "Right Arm"; RollObject.HitLocationToolTip = RollObject.DiceRollResult + " reversed is " + reverseRoll + "; 11-25 strikes Right Arm location"; } else if (reverseRoll < 41) { RollObject.HitLocation = "Left Arm"; RollObject.HitLocationToolTip = RollObject.DiceRollResult + " reversed is " + reverseRoll + "; 26-40 strikes Left Arm location"; } else if (reverseRoll < 81) { RollObject.HitLocation = "Body"; RollObject.HitLocationToolTip = RollObject.DiceRollResult + " reversed is " + reverseRoll + "; 41-80 strikes Body location"; } else if (reverseRoll < 91) { RollObject.HitLocation = "Right Leg"; RollObject.HitLocationToolTip = RollObject.DiceRollResult + " reversed is " + reverseRoll + "; 81-90 strikes Right Leg location"; } else if (reverseRoll < 101) { RollObject.HitLocation = "Left Leg"; RollObject.HitLocationToolTip = RollObject.DiceRollResult + " reversed is " + reverseRoll + "; 91-100 strikes Left Arm location"; } if (RollObject.TestSuccess) { RollObject.PowerCardContent += " --custom_dmgroll| "; }; } } if(RollObject.RangedAttack == true) { reduceAmmo(character); } RollObject.DegreesOfSuccess = (degrees + 1); RollObject.DegreesOfSuccessToolTip = "Difference of " + difference; RollObject.DiceRollResultToolTip = "Rolling 1d100(" + RollObject.DiceRollResult + ") versus " + RollObject.AttributeName + " (" + RollObject.AttributeValue + ") " + ( (RollObject.TestModifier > -1) ? " + " : "") + RollObject.TestModifier; RollObject.DamageRollResult = getResult(RollObject.RawDamageRoll) RollObject.DamageRollTotal = RollObject.DamageRollResult + RollObject.DamageAdd; RollObject.DamageRollTotalToolTip = "Rolling 1d10(" + RollObject.DamageRollResult + ") " + ((RollObject.DamageAdd > -1) ? "+ " : "- ") + Math.abs(RollObject.DamageAdd) + " = (" + RollObject.DamageRollTotal + ")"; if (RollObject.WeaponName == "Pistol") {RollObject.ImpactWeapon = true}; RollObject.ImpactRollResult = getResult(RollObject.RawImpactRoll) RollObject.ImpactRollTotal = RollObject.ImpactRollResult + RollObject.DamageAdd; RollObject.ImpactRollTotalToolTip = "Rolling 1d10(" + RollObject.ImpactRollResult + ") " + ((RollObject.DamageAdd > -1) ? "+ " : "- ") + Math.abs(RollObject.DamageAdd) + " = (" + RollObject.ImpactRollTotal + ")"; createPowerCard(msg, RollObject); } }); var reduceAmmo = function(character) { var targetsMatched = findObjs({_type: "graphic", represents: character.get('_id')}); if(targetsMatched.length === 0) { sendChat(msg.who, "target " + character + " not found."); } // Reduce the value of bar2 on the token by 1. for(var x in targetsMatched) { var target = targetsMatched[x]; if(target.get("bar2_value") !== "") { target.set("bar2_value", (target.get("bar2_value") - 1)); } } }; PowerCardScript.buildInline = function (expression, rolls, crit) { var InlineBorderRadius = (POWERCARD_ROUNDED_INLINE_ROLLS) ? 5 : 0; var rollOut = '= max); failRoll = failRoll || (value <= low); rollOut += ''; rollOut += value + '+'; } rollOut = rollOut.substring(0, rollOut.length - 1) + ')'; } // ROLL.TYPE Math var operator, operand; if (r.type == 'M') { rollOut += r.expr; if (r.expr.length == 1) { math = r.expr; } else { operator = ('' + r.expr).substring(0, 1); operand = ('' + r.expr).substring(operator.search(/[\d(]/) === 0 ? 0 : 1); } if (operand.search(/([\d+\-*/() d]|floor\(|ceil\()+\)?/g) === 0) { operand = operand.split('floor').join('Math.floor'); operand = operand.split('ceil').join('Math.ceil'); operand = eval((operator == '-' ? '-' : '') + operand); } else { operand = parseInt(operand); } switch (operator) { default: case '+': case '-': modTotal += operand; break; case '*': modTotal *= operand; break; case '/': modTotal /= operand; break; } } if (r.type == 'G') { // Do nothing... } } } rollOut += '" class="a inlinerollresult showtip tipsy-n'; rollOut += (critRoll && failRoll ? ' importantroll' : (critRoll ? ' fullcrit' : (failRoll ? ' fullfail' : ''))) + '">' + modTotal + ''; return rollOut; }; // These functions determine the brightness of a html color hexcode. // Copied from: http://blog.routydevelopment.com/2010/07/how-to-s... function getBrightness(hex) { hex = hex.replace('#', ''); var c_r = hexDec(hex.substr(0, 2)); var c_g = hexDec(hex.substr(2, 2)); var c_b = hexDec(hex.substr(4, 2)); return ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000; } function hexDec(hex_string) { hex_string = (hex_string + '').replace(/[^a-f0-9]/gi, ''); return parseInt(hex_string, 16); } function createPowerCard (msg, RollObject) { //Custom Variables var critRoll = false; var failRoll = false; // DEFINE VARIABLES var n = RollObject.PowerCardContent.split(" --"); //Customised this line var PowerCard = {}; var DisplayCard = ""; var NumberOfAttacks = 1; var NumberOfDmgRolls = 1; var Tag = ""; var Content = ""; // CREATE POWERCARD OBJECT ARRAY var a = 1; while (n[a]) { Tag = n[a].substring(0, n[a].indexOf("|")); Content = n[a].substring(n[a].indexOf("|") + 1); if (Tag.substring(0, 6).toLowerCase() == "attack") { NumberOfAttacks = Tag.substring(6); if (NumberOfAttacks === 0 || !NumberOfAttacks) NumberOfAttacks = 1; Tag = "attack"; } if (Tag.substring(0, 6).toLowerCase() == "damage") { NumberOfDmgRolls = Tag.substring(6); if (NumberOfDmgRolls === 0 || !NumberOfDmgRolls) NumberOfDmgRolls = 1; Tag = "damage"; } PowerCard[Tag] = Content; a++; } // CREATE TITLE STYLE var TitleStyle = " font-family: Georgia; font-size: large; font-weight: normal; text-align: center; vertical-align: middle; padding: 5px 0px; margin-top: 0.2em; border: " + POWERCARD_BORDER_SIZE + "px solid " + POWERCARD_BORDER_COLOR + ";"; // ROUNDED CORNERS ON TOP OF POWER CARD TitleStyle += (POWERCARD_ROUNDED_CORNERS) ? " border-radius: 10px 10px 0px 0px;" : ""; // LIST OF PRE-SET TITLE TEXT & BACKGROUND COLORS var AtWill = " color: #FFF; background-color: #040;"; var Encounter = " color: #FFF; background-color: #400;"; var Daily = " color: #FFF; background-color: #444;"; var Item = " color: #FFF; background-color: #e58900;"; var Recharge = " color: #FFF; background-color: #004;"; // CHECK FOR PRESET TITLE COLORS if (!POWERCARD_USE_PLAYER_COLOR) { if (PowerCard.usage !== undefined && PowerCard.txcolor === undefined && PowerCard.bgcolor === undefined) { // PRESET TITLE COLORS TitleStyle += AtWill; if (PowerCard.usage.toLowerCase() == "encounter") TitleStyle += Encounter; if (PowerCard.usage.toLowerCase() == "daily") TitleStyle += Daily; if (PowerCard.usage.toLowerCase() == "item") TitleStyle += Item; if (PowerCard.usage.toLowerCase().substring(0, 8) == "recharge") TitleStyle += Recharge; } else { // CUSTOM TITLECARD TEXT & BACKGROUND COLORS TitleStyle += (PowerCard.txcolor !== undefined) ? " color: " + PowerCard.txcolor + ";" : " color: #FFF;"; TitleStyle += (PowerCard.bgcolor !== undefined) ? " background-color: " + PowerCard.bgcolor + ";" : " background-color: #040;"; } } else { // SET TITLE BGCOLOR TO PLAYER COLOR --- OVERRIDES ALL OTHER COLOR OPTIONS --- var PlayerBGColor = getObj("player", msg.playerid).get("color"); var PlayerTXColor = "#000"; if (getBrightness(PlayerBGColor) < 50) { PlayerTXColor = "#FFF"; } TitleStyle += " color: " + PlayerTXColor + "; background-color: " + PlayerBGColor + ";"; } // DEFINE .leftsub and .rightsub if (PowerCard.leftsub === undefined) PowerCard.leftsub = (PowerCard.usage !== undefined) ? PowerCard.usage : ""; if (PowerCard.rightsub === undefined) PowerCard.rightsub = (PowerCard.action !== undefined) ? PowerCard.action : ""; var PowerCardDiamond = (PowerCard.leftsub == "" || PowerCard.rightsub == "") ? "" : " ♦ "; // BEGIN DISPLAYCARD CREATION DisplayCard += "