From 98031d1e82ff4bc86b9bc1f0d6d7075c920dcc3f Mon Sep 17 00:00:00 2001
From: Azmoria <65363489+Azmoria@users.noreply.github.com>
Date: Sun, 20 Oct 2024 21:28:47 -0400
Subject: [PATCH] QoL - add option to roll initiative with adv/dis
automatically when adding to combat tracker.
---
CombatTracker.js | 4 ++--
CoreFunctions.js | 3 +--
StatHandler.js | 12 ++++++------
TokenMenu.js | 35 +++++++++++++++++++++++++++++++----
abovevtt.css | 35 +++++++++++++++++++++++++++++++++++
5 files changed, 75 insertions(+), 14 deletions(-)
diff --git a/CombatTracker.js b/CombatTracker.js
index 3f3a60bb2..6992dbcdd 100644
--- a/CombatTracker.js
+++ b/CombatTracker.js
@@ -613,7 +613,7 @@ function ct_reorder(persist=true) {
}
-function ct_add_token(token,persist=true,disablerolling=false){
+function ct_add_token(token,persist=true,disablerolling=false, adv=false, dis=false){
if(token.options.name == "Not in the current map")
return;
if (token.isAoe()) {
@@ -766,7 +766,7 @@ function ct_add_token(token,persist=true,disablerolling=false){
window.TOKEN_OBJECTS[token.options.id].update_and_sync()
}
debounceCombatReorder();
- }, token.options.itemId, token.options.id);
+ }, token.options.itemId, token.options.id, adv, dis);
}
}
diff --git a/CoreFunctions.js b/CoreFunctions.js
index f0ef14882..a1b8be7f0 100644
--- a/CoreFunctions.js
+++ b/CoreFunctions.js
@@ -16,8 +16,7 @@ $(function() {
window.AVTT_VERSION = $("#avttversion").attr('data-version');
$("head").append('');
$("head").append('');
- // WORKAROUND FOR ANNOYING DDB BUG WITH COOKIES AND UPVOTING STUFF
- document.cookie="Ratings=;path=/;domain=.dndbeyond.com;expires=Thu, 01 Jan 1970 00:00:00 GMT";
+
if (is_encounters_page()) {
window.DM = true; // the DM plays from the encounters page
dmAvatarUrl = $('#site-bar').attr('user-avatar');
diff --git a/StatHandler.js b/StatHandler.js
index 1ccd33640..dc176e7ba 100644
--- a/StatHandler.js
+++ b/StatHandler.js
@@ -43,8 +43,8 @@ class StatHandler {
}
}
- rollInit(monsterid, callback, open5eSlug = undefined, tokenId = undefined) {
-
+ rollInit(monsterid, callback, open5eSlug = undefined, tokenId = undefined, adv=false, dis=false) {
+ let dice = adv ? '2d20kh1+' : dis ? '2d20kl1+' : '1d20+'
if(window.TOKEN_OBJECTS[tokenId].options.combatGroupToken){
let modArray = [];
let statArray = [];
@@ -86,7 +86,7 @@ class StatHandler {
const sumStat = statArray.reduce((a, b) => a + b, 0);
const stat = (sumStat / statArray.length) || 0;
- let expression = "1d20+" + modifier;
+ let expression = dice + modifier;
let roll = new rpgDiceRoller.DiceRoll(expression);
console.log(expression + "->" + roll.total);
let total = parseFloat(Math.floor(roll.total) + stat/100).toFixed(2);
@@ -103,7 +103,7 @@ class StatHandler {
{
this.getStat(monsterid, function(data) {
let modifier = Math.floor((data.stats[1].value - 10) / 2.0);
- let expression = "1d20+" + modifier;
+ let expression = dice + modifier;
let roll = new rpgDiceRoller.DiceRoll(expression);
console.log(expression + "->" + roll.total);
let total = parseFloat(roll.total + data.stats[1].value/100).toFixed(2);
@@ -116,7 +116,7 @@ class StatHandler {
}
else if(monsterid =='customStat'){
let modifier = (window.TOKEN_OBJECTS[tokenId]?.options?.customInit != undefined) ? parseInt(window.TOKEN_OBJECTS[tokenId].options.customInit) : (window.TOKEN_OBJECTS[tokenId]?.options?.customStat != undefined && window.TOKEN_OBJECTS[tokenId]?.options?.customStat[1]?.mod != undefined) ? parseInt(window.TOKEN_OBJECTS[tokenId].options.customStat[1].mod) : 0;
- let expression = (!isNaN(modifier)) ? "1d20+" + modifier : '0';
+ let expression = (!isNaN(modifier)) ? dice + modifier : '0';
let roll = new rpgDiceRoller.DiceRoll(expression);
let decimalAdd = (window.TOKEN_OBJECTS[tokenId]?.options?.customInit != undefined || (window.TOKEN_OBJECTS[tokenId]?.options?.customStat != undefined && window.TOKEN_OBJECTS[tokenId]?.options?.customStat[1]?.mod != undefined)) ? ((modifier*2)+10)/100 : 0
console.log(expression + "->" + roll.total);
@@ -130,7 +130,7 @@ class StatHandler {
else{
this.getStat(monsterid, function(stat) {
let modifier = Math.floor((stat.data.stats[1].value - 10) / 2.0);
- let expression = "1d20+" + modifier;
+ let expression = dice + modifier;
let roll = new rpgDiceRoller.DiceRoll(expression);
console.log(expression + "->" + roll.total);
let total = parseFloat(roll.total + stat.data.stats[1].value/100).toFixed(2);
diff --git a/TokenMenu.js b/TokenMenu.js
index 234a5255d..b10f4ba3d 100644
--- a/TokenMenu.js
+++ b/TokenMenu.js
@@ -706,11 +706,35 @@ function token_context_menu_expanded(tokenIds, e) {
groupCombatButton.addClass("add-to-ct");
groupCombatButton.html(addGroupButtonInternals);
}
+
+
+ let shiftClick = jQuery.Event("click");
+ shiftClick.shiftKey = true;
+ let ctrlClick = jQuery.Event("click");
+ ctrlClick.ctrlKey = true;
+
+ let roll_adv = $('')
+ roll_adv.click(function(e){
+ e.stopPropagation();
+ $(this).parent().trigger(shiftClick);
+ });
+
+ roll_disadv = $('')
+
+ roll_disadv.click(function(e){
+ e.stopPropagation();
+ $(this).parent().trigger(ctrlClick);
+ });
+
+ combatButton.append(roll_adv, roll_disadv);
+
+
combatButton.on("click", function(clickEvent) {
let clickedButton = $(clickEvent.currentTarget);
if (clickedButton.hasClass("remove-from-ct")) {
clickedButton.removeClass("remove-from-ct").addClass("add-to-ct");
clickedButton.html(addButtonInternals);
+ clickedButton.append(roll_adv.clone(true, true), roll_disadv.clone(true, true));
tokens.forEach(t =>{
t.options.ct_show = undefined;
t.options.combatGroup = undefined;
@@ -722,7 +746,7 @@ function token_context_menu_expanded(tokenIds, e) {
clickedButton.html(removeButtonInternals);
tokens.forEach(t => {
t.options.combatGroup = undefined;
- ct_add_token(t, false)
+ ct_add_token(t, false, undefined, clickEvent.shiftKey, clickEvent.ctrlKey)
t.update_and_sync();
});
}
@@ -736,6 +760,7 @@ function token_context_menu_expanded(tokenIds, e) {
combatButton.html(addButtonInternals);
clickedButton.removeClass("remove-from-ct").addClass("add-to-ct");
clickedButton.html(addGroupButtonInternals);
+ clickedButton.append(roll_adv.clone(true, true), roll_disadv.clone(true, true));
tokens.forEach(t =>{
if(t.options.combatGroup && window.TOKEN_OBJECTS[t.options.combatGroup]){
window.TOKEN_OBJECTS[t.options.combatGroup].delete()
@@ -760,7 +785,7 @@ function token_context_menu_expanded(tokenIds, e) {
allHidden = false
}
t.options.combatGroup = group;
- ct_add_token(t, false);
+ ct_add_token(t, false, undefined, clickEvent.shiftKey, clickEvent.ctrlKey);
t.update_and_sync();
});
let t = new Token({
@@ -778,13 +803,15 @@ function token_context_menu_expanded(tokenIds, e) {
window.MB.sendMessage('custom/myVTT/token', t.options);
}, 10);
t.place_sync_persist();
- ct_add_token(window.TOKEN_OBJECTS[group], false)
+ ct_add_token(window.TOKEN_OBJECTS[group], false, clickEvent.shiftKey, clickEvent.ctrlKey)
}
debounceCombatReorder();
});
-
+
+
body.append(combatButton);
if(tokens.length >1){
+ groupCombatButton.append(roll_adv.clone(true,true), roll_disadv.clone(true,true));
body.append(groupCombatButton);
}
}
diff --git a/abovevtt.css b/abovevtt.css
index 92692715e..eeb3d15e2 100644
--- a/abovevtt.css
+++ b/abovevtt.css
@@ -6095,6 +6095,41 @@ div#selectedTokensBorderRotationGrabberConnector,
box-shadow: inset 0 1px 1px rgb(0 0 0 / 8%);
}
+
+div#tokenOptionsContainer button#adv{
+ filter: sepia(0.3) hue-rotate(63deg) saturate(8) drop-shadow(0px 0px 0px #0F0);
+ right:32px;
+}
+
+div#tokenOptionsContainer button#disadv{
+ filter: sepia(0.3) hue-rotate(312deg) saturate(14) drop-shadow(0px 0px 0px #F00);
+ right: 10px;
+}
+
+div#tokenOptionsContainer button#adv,
+div#tokenOptionsContainer button#disadv{
+ width:20px;
+ background:none;
+ outline:none;
+ border:none;
+ height:20px;
+ position:absolute;
+ opacity:0.2;
+ padding:0px;
+}
+div#tokenOptionsContainer button#adv:hover,
+div#tokenOptionsContainer button#disadv:hover{
+ opacity:1;
+}
+div#tokenOptionsContainer button#adv:before,
+div#tokenOptionsContainer button#disadv:before{
+ width:100%;
+ height:100%;
+}
+
+div#tokenOptionsContainer .remove-from-ct>button{
+ display:none;
+}
.context-menu-list{
border-radius: 10px !important;
}