Skip to content

Instantly share code, notes, and snippets.

@sturtus
Last active January 2, 2016 19:58
Show Gist options
  • Save sturtus/8353433 to your computer and use it in GitHub Desktop.
Save sturtus/8353433 to your computer and use it in GitHub Desktop.
Deed script for Dungeon Crawl Classics
/*
Deed script for Dungeon Crawl Classics in Roll20. Calculates a Mighty Deed or Deed die style attack by rolling the deed die and adding to both attack and damage. Optionally does Smite for the Crawl! magazine paladin and a deed attack for the ranger or other custom class that uses a deed die without a Mighty Deed of Arms.
Requires my Roll20 Library script. https://gist.github.com/sturtus/8352577
To use, the character must have the attributes defined in the config portion of the script.
- ActionDie: the die to roll for the spell check, as a d20 or d16 or whatever.
- DeedDie: the die to roll for the deed, as a d4, d7 or whatever.
- List of attributes to possibly affect the roll, expressed as bonuses such as +1 or -1 or 0. In my campaign we use 3 letter abbreviations for these like STR, AGI, PER, LCK, and INT. Change the array to match your campaign.
- Threat: Expressed as the lowest number necessary to crit for the character. If a warrior crits on 18-20, this attribute should be 18. Defaults to 20 if it is not defined.
Also optionally calculates success and failure of a Mighty Deed of Arms and a critical hit for warriors with increased threat die or characters wielding weapons with higher threat die.
- Optional: Type of Deed defined in array. Mighty, Smite, Normal. If undefined, defaults to normal and will not determine success or failure of a Mighty Deed of Arms
To call the script do this.
!deed weapon damage|attack modifiers|damage modifiers|deed type|threat
!deed: the command to call
weapon damage: expressed as a die roll, 1d8, 2d4, etc
attack modifiers: expressed as the name of the attributes containing the bonuses and any misc. bonuses to apply to attack
damage modifiers: expressed as the name of the attributes containing the bonuses and any misc. bonuses to apply to damage
deed type: Mighty, Smite, or Normal to determine Mighty Deed calculation
for example:
!deed 1d8|STR,LCK,+2|+2,STR|Mighty|18
Performs a Mighty Deed of Arms, will roll the character's Deed die, the die in the character's ActionDie attribute, add the STR bonus, LCK bonus, and +2 to attack along with the deed die result, then calculate damage as the weapon damage plus deed die result plus STR bonus, and +2. If the deed die is 3 or more, it gives a success result. If the Action Die was 18 or more natural roll, it sends a crit to chat.
!deed 1d8|STR,AGI,-2|None
Performs a normal attack with a deed die. will roll the character's Deed die, the die in the character's ActionDie attribute, add the STR bonus, AGI bonus, and -2 to attack along with the deed die result, then calculate damage as the weapon damage plus deed die result only. If the Action Die was natural 20, it sends a crit to chat.
*/
function deed(characterObj, attributeObjArray, deedDamageDie, deedAttackArray, deedDamageArray, deedTypeArray, deedType, threat) {
// assign the variables for output.
var characterName = characterObj.get("name");
var actionDieValue = attributeObjArray[0].get("current"); //attributeValue[0];
var deedDeedValue = attributeObjArray[1].get("current"); //attributeValue[1];
//get the values in deedAttackArray, return current numbers if attributes and numbers if numbers
var attackMods = deedAttackArray;
for (var i = 2; i < attributeObjArray.length; i++) {
for (var j = 0; j < deedAttackArray.length; j++) {
if (attributeObjArray[i].get("name") == deedAttackArray[j]) {
attackMods[j] = attributeObjArray[i].get("current");
};
};
};
//get the values in deedDamageArray, return current numbers if attributes and numbers if numbers
var damageMods = deedDamageArray;
for (var i = 2; i < attributeObjArray.length; i++) {
for (var j = 0; j < deedDamageArray.length; j++) {
if (attributeObjArray[i].get("name") == deedDamageArray[j]) {
damageMods[j] = attributeObjArray[i].get("current");
};
};
};
//clean up any + symbols
damageMods = removePlus(damageMods);
attackMods = removePlus(attackMods);
// get the deed die value, as expressed as 1d7 or d5 or whatever in the current value of the attribute.
var d = deedDeedValue.indexOf("d")+1;
var deedDeedDie = parseInt(deedDeedValue.slice(d));
d = actionDieValue.indexOf("d")+1;
var actionDieMax = parseInt(actionDieValue.slice(d));
var actionDieResult = randomInteger(actionDieMax);
var deedResult = randomInteger(deedDeedDie);
// check to see what kind of deed it is, and spit out the right text
if ((deedType == deedTypeArray[0]) || (deedType == undefined)) {
sendChat("Deed Die", deedResult + " ");
};
if (deedType == deedTypeArray[1]) {
if (deedResult >= 3) {
sendChat("Mighty Deed", deedResult + ": Succeeds if hits!");
} else {
sendChat("Mighty Deed", deedResult + ": Fails!");
};
};
if (deedType == deedTypeArray[2]) {
sendChat("Smite", deedResult + " ");
};
//build results and send to chat
var attackChatString = "[[" + actionDieResult;
if (deedAttackArray[0] != "None") {
for (var i = 0; i < attackMods.length; i++) {
attackChatString = attackChatString.concat(" +", attackMods[i]);
};
};
attackChatString = attackChatString.concat(" +", deedResult, "]] vs. AC, for [[", deedDamageDie);
if (deedDamageArray[0] != "None") {
for (var i = 0; i < damageMods.length; i++) {
attackChatString = attackChatString.concat(" +", damageMods[i]);
};
};
attackChatString = attackChatString.concat(" +", deedResult, "]] points of damage!");
sendChat(characterName,attackChatString);
if (threat == undefined) {
threat = "20";
}
if (actionDieResult >= threat) {
sendChat(characterName, actionDieResult + "! Critical Hit!");
};
};
on("chat:message", function(msg) {
if (msg.type == "api" && msg.content.indexOf("!deed ") !== -1) {
var selected = msg.selected;
var deedTypeArray = ["Normal", "Mighty", "Smite"];
var attributeArray = ["ActionDie", "DeedDie", "STR", "AGI", "LCK"];
var param = msg.content.split("!deed ")[1];
var deedDamageDie = param.split("|")[0];
var deedAttack = param.split("|")[1];
var deedAttackArray = deedAttack.split(",");
var deedDamage = param.split("|")[2];
var deedDamageArray = deedDamage.split(",");
var deedType = param.split("|")[3];
var threat = param.split("|")[4];
if(!selected) {
sendChat("", "/desc Select token and try again.");
return; //quit if nothing selected
};
//loop through selected tokens
_.each(selected, function(obj) {
var characterObj = getCharacterObj(obj);
if (characterObj == false) return;
var attributeObjArray = getAttributeObjects(characterObj, attributeArray);
if (attributeObjArray == false) return;
deed(characterObj, attributeObjArray, deedDamageDie, deedAttackArray, deedDamageArray, deedTypeArray, deedType, threat);
});
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment