Skip to content

Instantly share code, notes, and snippets.

@bripod
Last active December 25, 2015 00:19
Show Gist options
  • Save bripod/6887201 to your computer and use it in GitHub Desktop.
Save bripod/6887201 to your computer and use it in GitHub Desktop.
Mighty Deeds of Arms command for roll20
// Mighty Deeds of Arms for Dungeon Crawl Classics in roll20.net
// This script creates a command which will compute the Mighty Deed Die roll for a
// warrior's attack, and then use that value as a modifier for the attack and damage
// rolls, and output the computed roll to chat.
// The script assumes that 1) any character performing a mighty deed has an attribute called
// "DeedDie" whose max value is used to determine which die to roll for the mighty deed
// (i.e., 3 = 1d3, 4 = 1d4), and 2) ability modifiers are stored on the character sheets.
// I use STR, AGL, etc., but the script doesn't care what the attributes are called (although
// if they have commas in their names that will cause issues)
// The command format is as follows:
// !mightyDeed character_Name|action_die|damage_die|attack,mods|damage,mods
// - character_name: The full name of the character (not the token) performing the mighty deed
// - action_die: the roll expression to use for the base attack roll, i.e. 1d20
// - damage_die: the roll expression to use for the base damage roll, i.e. 1d8
// - attack,mods: comma-separated lists of character attribute values to add to the attack roll. Use "None" for no mods.
// - damage,mods: comma-separated lists of character attribute values to add to the attack roll. Use "None" for no mods.
// Example character abilities using the command:
// /emas attacks with his lucky weapon, a longsword.
// !mightyDeed Johnny Meatshield|1d20|1d8|STR,LCK|STR
// /emas attacks with his longbow, at medium range.
// !mightyDeed Johnny Meatshield|1d20-2|1d6|AGL|None
function mightyDeed(mightyCharacterName, mightyActionDie, mightyDeedDie, mightyDamageDie, mightyAttackArray, mightyDamageArray) {
var deedDieMax = mightyDeedDie.get("max");
var deedResult = randomInteger(deedDieMax);
if (deedResult >= 3) {
sendChat("Mighty Deed", deedResult + ": Succeeds if hits!")
} else {
sendChat("Mighty Deed", deedResult + ": Fails!")
};
var attackChatString = "[[" + mightyActionDie;
if (mightyAttackArray[0] != "None") {
for (var i = 0; i < mightyAttackArray.length; i++) {
attackChatString = attackChatString.concat(" + @{", mightyCharacterName, "|", mightyAttackArray[i], "}");
};
};
attackChatString = attackChatString.concat(" + " + deedResult + "]] vs. AC, for [[" + mightyDamageDie);
if (mightyDamageArray[0] != "None") {
for (var i = 0; i < mightyDamageArray.length; i++) {
attackChatString = attackChatString.concat(" + @{", mightyCharacterName, "|", mightyDamageArray[i], "}");
};
};
attackChatString = attackChatString.concat(" + " + deedResult + "]] points of damage!");
log(attackChatString);
sendChat(mightyCharacterName,attackChatString);
};
on("chat:message", function(msg) {
if (msg.type == "api" && msg.content.indexOf("!mightyDeed") !== -1) {
var mightyParameters = msg.content.split("!mightyDeed ")[1];
var mightyCharacterName = mightyParameters.split("|")[0];
var mightyActionDie = mightyParameters.split("|")[1];
var mightyDamageDie = mightyParameters.split("|")[2];
var mightyAttack = mightyParameters.split("|")[3];
var mightyAttackArray = mightyAttack.split(",");
var mightyDamage = mightyParameters.split("|")[4];
var mightyDamageArray = mightyDamage.split(",");
var mightyCharacterId = findObjs({_type: "character", name: mightyCharacterName})[0].get("_id");
var mightyDeedDieId = findObjs({_type: "attribute", name: "DeedDie", _characterid: mightyCharacterId})[0].get("_id");
var mightyDeedDie = getObj("attribute", mightyDeedDieId);
mightyDeed(mightyCharacterName, mightyActionDie, mightyDeedDie, mightyDamageDie, mightyAttackArray, mightyDamageArray);
};
});
@sturtus
Copy link

sturtus commented Jan 3, 2014

I messed around with it to make fewer arguments passed, and have it pull info off the token that is currently selected. Having issues with the final sendChat() command though. Keep getting unexpected number error.

// Mighty Deeds of Arms for Dungeon Crawl Classics in roll20.net
// This script creates a command which will compute the Mighty Deed Die roll for a
// warrior's attack, and then use that value as a modifier for the attack and damage
// rolls, and output the computed roll to chat.
// The script assumes that 1) any character performing a mighty deed has an attribute called
// "DeedDie" whose value is used to determine which die to roll for the mighty deed
// (i.e., d3, d4), 2) ability modifiers are stored on the character sheets.
// and 3) character uses an attribute called "ActionDie" to determine the attack roll.
// I use STR, AGL, etc., but the script doesn't care what the attributes are called (although
// if they have commas in their names that will cause issues)
// The command format is as follows:
// !mightyDeed damage_die|attack,mods|damage,mods
// - character_name: The full name of the character (not the token) performing the mighty deed
// - action_die: the roll expression to use for the base attack roll, i.e. 1d20
// - damage_die: the roll expression to use for the base damage roll, i.e. 1d8
// - attack,mods: comma-separated lists of character attribute values to add to the attack roll. Use "None" for no mods.
// - damage,mods: comma-separated lists of character attribute values to add to the attack roll. Use "None" for no mods.
// Example character abilities using the command:
// /emas attacks with his lucky weapon, a longsword.
// !mightyDeed 1d8|STR,LCK|STR
// /emas attacks with his longbow, at medium range.
// !mightyDeed 1d6|AGL|None

function mightyDeed(obj, actionDieAttrib, deedAttrib, mightyDamageDie, mightyAttackArray, mightyDamageArray) {

if (obj._type != 'graphic') return; //exclude non-graphics
var tok = getObj("graphic", obj._id);
if (tok.get('subtype') != 'token') return; //exclude non-tokens

// find the character the token represents
if (tok.get("represents") != "") {
   var oCharacter = getObj("character", tok.get("represents"));
   log(oCharacter)
   log("will do a mighty deed");
} else {
    log(obj);
    log("does not represent a character.");
    sendChat("", "/desc Selected token does not represent a character.");
    return;
};

// get the attributes from the character
if (oCharacter != undefined ) {
    var mightyDeedDieId = findObjs({_type: "attribute", name: deedAttrib, _characterid: oCharacter.id})[0];
    log("mightyDeedDieId should be the full attribute for the deedAttrib defined")
    log(mightyDeedDieId);
    var actionDieAttribId = findObjs({_type: "attribute", name: actionDieAttrib, _characterid: oCharacter.id})[0];
    log("actionDieAttribId should be the full attribute for the actionDieAttrib defined")
    log(actionDieAttribId);
    var mightyCharacterName = oCharacter.get("name");
    log("mightyCharacterName should be the full name of the character")
    log(mightyCharacterName);
};

// make sure attribute ActionDie and DeedDie exists, fail and send message to manually create attributes if it does not exist.  
if ((actionDieAttribId == undefined ) || (mightyDeedDieId == undefined )) {
    log("actionDieAttrib or deedAttrib did not exist, character requires attributes");
    log(actionDieAttrib);
    log(deedAttrib);
    sendChat("", "/desc Selected character needs the attributes" + actionDieAttrib + " and " + deedAttrib + " to be set in character journal, like d20.");
    return;
} else {
    var actionDieAttribName = findObjs({name: actionDieAttrib,_type: "attribute", _characterid: oCharacter.id})[0].get("name");
    var actionDieValue = findObjs({name: actionDieAttrib,_type: "attribute", _characterid: oCharacter.id})[0].get("current");
    log("this should match the name of Action Die attribute, pulled from the actual attribute");
    log(actionDieAttribName);
    log("the existing value of the input attribute, that already exists, is");
    log(actionDieValue);
    var mightyDeedName = findObjs({name: deedAttrib,_type: "attribute", _characterid: oCharacter.id})[0].get("name");
    var mightyDeedValue = findObjs({name: deedAttrib,_type: "attribute", _characterid: oCharacter.id})[0].get("current");
    log("this should match the name of deed die attribute, pulled from the actual attribute");
    log(mightyDeedName);
    log("the existing value of the input attribute, that already exists, is");
    log(mightyDeedValue);
};

// fix so deed die is expressed as d7 or d5 or whatever, parse out "d" and get the number after
// make this var equal to mightyDeedDieValue minus the d.

var d = mightyDeedValue.indexOf("d")+1;
var mightyDeedDie = parseInt(mightyDeedValue.slice(d));
log("mightyDeedDie");
log(mightyDeedDie);



// check if mighty deed fails or succeeds
var deedResult = randomInteger(mightyDeedDie);
log("deedResult is");
log(deedResult)
if (deedResult >= 3) {
    sendChat("Mighty Deed", deedResult + ": Succeeds if hits!");
} else {
    sendChat("Mighty Deed", deedResult + ": Fails!");
};

var attackChatString = "[[" + actionDieValue;
if (mightyAttackArray[0] != "None") {
for (var i = 0; i < mightyAttackArray.length; i++) {
attackChatString = attackChatString.concat(" + @{", mightyCharacterName, "|", mightyAttackArray[i], "}");
};
};
attackChatString = attackChatString.concat(" +", deedResult, "]] vs. AC, for [[", mightyDamageDie);
if (mightyDamageArray[0] != "None") {
for (var i = 0; i < mightyDamageArray.length; i++) {
attackChatString = attackChatString.concat(" + @{", mightyCharacterName, "|", mightyDamageArray[i], "}");
};
};
attackChatString = attackChatString.concat(" +", deedResult, "]] points of damage!");
log(attackChatString);
sendChat(mightyCharacterName,attackChatString);

};

on("chat:message", function(msg) {

var cmd = "!mightyDeed ";
var deedAttrib = "DeedDie";
var actionDieAttrib = "ActionDie"
var selected = msg.selected;

if (msg.type == "api" && msg.content.indexOf(cmd) !== -1) {

    //!mightyDeed 1d8|STR,LCK|STR

    //parse the input into two variables, oAttrib and newValue
    var parameters = msg.content.split(cmd)[1];
    log("Splitting, removing the command, creating variables");
    var mightyDamageDie = parameters.split("|")[0];
    log(mightyDamageDie);
    var mightyAttack = parameters.split("|")[1];
    log(mightyAttack);
    var mightyAttackArray = mightyAttack.split(",");
    log(mightyAttackArray);
    var mightyDamage = parameters.split("|")[2];
    log(mightyDamage);
    var mightyDamageArray = mightyDamage.split(",");
    log(mightyDamageArray);

    if(!selected) {
        sendChat("", "/desc Select token and try again.");
        return; //quit if nothing selected
    }; 

    //loop through selected tokens
    _.each(selected, function(obj) {
        mightyDeed(obj, actionDieAttrib, deedAttrib, mightyDamageDie, mightyAttackArray, mightyDamageArray);
    });

};

});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment