// ==UserScript==
// @name Better BiteFight
// @namespace https://lobby.bitefight.gameforge.com/
// @version 0.7.1
// @description Adds an healthbar, energybar, links and other QOL to BiteFight
// @author Spychopat
// @match https://*.bitefight.gameforge.com/*
// @icon https://lobby.bitefight.gameforge.com/favicon.ico
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict';
// uncomment to reset character data if needed
//GM_setValue('character', {})
// Script storage keys
const KEY_CHARACTER = 'character';
const pageLoadTime = Date.now();
// Define character object
const CHARACTER = GM_getValue(KEY_CHARACTER, {
energy: 0,
maxEnergy: 0,
health: 0,
maxHealth: 0,
regenHealth: 0,
potionCooldownEnd: 0,
churchCooldownEnd: 0,
autoRedirectGrotte: true,
autoGrotto: [false, false, false],
goldEarned: { 0: [], 1: [], 2: [] },
dmgTaken: { 0: [], 1: [], 2: [] },
xpEarned: { 0: [], 1: [], 2: [] }
});
//console.log(parseInt(formatNumber(document.getElementsByClassName("gold")[1].firstChild.textContent.split("\n")[1])));
redirectAfterGrotteFight(); // run it first, because it has chances to redirect, so we don't work uselessly
// early, to avoid the page jump as much as possible
insertCSS();
addAdditionnalLink();
extractCharacterStats();
updatePotionTimer(); // Run the church cooldown update function if on the church page
updateRegenHealth();
insertProgressBars(); // Insert progress bars after updating the character
startHealthRegeneration(); // Start health regeneration on page load
if (window.location.pathname.contains('/profile')){
moveGameEventDiv(); // move down the game event div
} else if (window.location.pathname.contains('/city/church')){
updateChurchCooldownTimer();
} else if (window.location.pathname.contains('/city/grotte')){
addAutoGrottoButton();
autoFightGrotto();
} else if (window.location.pathname.contains('/city/shop')){
defaultNonPremiumShop();
}
updateCharacter();
//console.log(CHARACTER);
// make the overview link open the attributes by default
document.querySelectorAll('#menuHead li a')[1].href="/profile/index#tabs-2";
function insertCSS() {
GM_addStyle(`
#upgrademsg {
display: none;
}
#premium > img {
display: none;
}
#mmonetbar {
display: none !important;
visibility: hidden;
}
`);
}
function extractCharacterStats(){
// Get Stats
var allStatsElement = document.getElementsByClassName("gold")[0];
var statsValues = allStatsElement.textContent.split("\n");
statsValues = statsValues.map(value => value.trim());
statsValues.shift();
// Extract energy, fragments, gold, health, and hellStones
var energy = statsValues[3].trim();
var currentEnergy = energy.split("/")[0];
var maxEnergy = energy.split("/")[1];
if (currentEnergy && maxEnergy) {
CHARACTER.energy = parseInt(currentEnergy); // Use parseFloat to preserve decimals
CHARACTER.maxEnergy = parseInt(maxEnergy); // Use parseFloat to preserve decimals
}
var health = statsValues[4].trim();
var currentHealth = formatNumber(health.split("/")[0]);
var maxHealth = formatNumber(health.split("/")[1]);
if (currentHealth && maxHealth) {
CHARACTER.health = parseInt(currentHealth);
CHARACTER.maxHealth = parseInt(maxHealth);
}
}
// Format texts to return as numbers (no thousand separators)
function formatNumber(value) {
while (value.indexOf(".") > 0) value = value.replace(".", "");
return value;
}
function updateRegenHealth() {
if (!window.location.pathname.endsWith('/profile/index')) return;
var elements = document.getElementsByClassName("triggerTooltip");
// Loop through the elements
for (let i = 0; i < elements.length; i++) {
// Check if the inner text or inner HTML contains "/ h"
if (elements[i].innerText.includes("/ h") || elements[i].innerHTML.includes("/ h")) {
CHARACTER.regenHealth = parseInt(elements[i].textContent);
//console.log("Regen per hour found : ", parseInt(elements[i].textContent));
break; // Exit the loop once the element is found
}
}
}
// Update character in local storage
function updateCharacter() {
GM_setValue(KEY_CHARACTER, CHARACTER);
}
function updatePotionTimer() {
if (!window.location.pathname.endsWith('/profile/index')) return; // Ensure this only runs on the right page
// Get all elements with the class "inactive"
const inactiveElements = document.getElementsByClassName('inactive');
let targetElement = null;
// Loop through each "inactive" element to find the target
for (const inactiveElement of inactiveElements) {
// Find elements with the class "countdown_row countdown_amount" within the current "inactive" element
const matchingElements = inactiveElement.getElementsByClassName('countdown_row countdown_amount');
if (matchingElements.length > 0) {
targetElement = matchingElements[0]; // Take the first matching element
break; // Stop once we find the target
}
}
if (targetElement) {
// Get the current time and add the potion cooldown to get the end time
const currentTime = new Date().getTime() / 1000; // Current time in seconds
const cooldownTime = timeToSeconds(targetElement.textContent); // Convert cooldown time to seconds
const endTime = currentTime + cooldownTime; // Calculate the end time
// Save the end time to the character object
CHARACTER.potionCooldownEnd = endTime;
updateCharacter(); // Save updated character data
}
}
function timeToSeconds(timeStr) {
const [hours, minutes, seconds] = timeStr.split(':').map(Number);
return (hours * 3600) + (minutes * 60) + seconds;
}
function insertProgressBars() {
// Check if the layout container is already present
if (document.getElementById('progressBarsTimersContainer')) {
return;
}
// Create the main container for the layout
let mainContainer = document.createElement('div');
mainContainer.id = 'progressBarsTimersContainer';
mainContainer.style.display = 'flex';
mainContainer.style.justifyContent = 'space-between';
mainContainer.style.alignItems = 'center';
mainContainer.style.marginTop = '3px';
// Left section for progress bars
let progressBarsContainer = document.createElement('div');
progressBarsContainer.style.display = 'flex';
progressBarsContainer.style.flexDirection = 'column';
progressBarsContainer.style.alignItems = 'flex-start';
progressBarsContainer.style.paddingLeft = '50px';
// Create Health Progress Bar
let healthBarContainer = document.createElement('div');
healthBarContainer.style.width = '250px';
healthBarContainer.style.position = 'relative';
healthBarContainer.id = 'healthProgressBar';
healthBarContainer.style.backgroundColor = 'black'; // Black background
healthBarContainer.style.border = '3px solid rgb(117, 117, 117)'; // White outline
healthBarContainer.style.borderRadius = '3px 3px 0px 0px';
let healthBar = document.createElement('div');
healthBar.style.height = '20px';
healthBar.style.width = `${(CHARACTER.health / CHARACTER.maxHealth) * 100}%`;
healthBar.style.backgroundColor = '#b80000';
let healthText = document.createElement('div');
healthText.textContent = `${CHARACTER.health > 999 ? CHARACTER.health.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.') : CHARACTER.health}`;
healthText.style.position = 'absolute';
healthText.style.top = '50%';
healthText.style.left = '50%';
healthText.style.transform = 'translate(-50%, -50%)';
healthText.style.color = 'white';
healthText.style.fontSize = '12px';
healthText.style.fontFamily = 'monospace';
healthBarContainer.appendChild(healthBar);
healthBarContainer.appendChild(healthText);
// Create Energy Progress Bar
let energyBarContainer = document.createElement('div');
energyBarContainer.style.width = '250px';
energyBarContainer.style.marginBottom = '5px';
energyBarContainer.style.position = 'relative';
energyBarContainer.id = 'energyProgressBar';
energyBarContainer.style.backgroundColor = 'black'; // Black background
energyBarContainer.style.borderLeft = '3px solid rgb(117, 117, 117)'; // White outline
energyBarContainer.style.borderRight = '3px solid rgb(117, 117, 117)'; // White outline
energyBarContainer.style.borderBottom = '3px solid rgb(117, 117, 117)'; // White outline
energyBarContainer.style.borderRadius = '0px 0px 3px 3px';
let energyBar = document.createElement('div');
energyBar.style.height = '20px';
energyBar.style.width = `${(CHARACTER.energy / CHARACTER.maxEnergy) * 100}%`;
energyBar.style.backgroundColor = '#0000a4';
let energyText = document.createElement('div');
energyText.textContent = `${CHARACTER.energy}`;
energyText.style.position = 'absolute';
energyText.style.top = '50%';
energyText.style.left = '50%';
energyText.style.transform = 'translate(-50%, -50%)';
energyText.style.color = 'white';
energyText.style.fontSize = '12px';
energyText.style.fontFamily = 'monospace';
energyBarContainer.appendChild(energyBar);
energyBarContainer.appendChild(energyText);
progressBarsContainer.appendChild(healthBarContainer);
progressBarsContainer.appendChild(energyBarContainer);
// Right section for timers
let timersContainer = document.createElement('div');
timersContainer.style.textAlign = 'center';
timersContainer.style.paddingRight = '50px';
timersContainer.style.width = '256px';
// Ensure timers are stacked vertically
timersContainer.style.display = 'flex';
timersContainer.style.flexDirection = 'column'; // Stack vertically
timersContainer.style.alignItems = 'center'; // Center align each timer
// Potion Timer Link
let potionTimer = document.createElement('a');
potionTimer.id = 'potionCooldownTimer';
potionTimer.style.color = 'white';
potionTimer.style.fontSize = '14px';
potionTimer.style.fontFamily = 'monospace';
potionTimer.style.margin = '0px';
//potionTimer.href = '/profile/index#potions';
potionTimer.href = '/profile/useItem/2/20';
potionTimer.textContent = 'Potion Cooldown: Calculating...';
// Church Timer Link
let churchTimer = document.createElement('a');
churchTimer.id = 'churchCooldownTimer';
churchTimer.style.color = 'white';
churchTimer.style.fontSize = '14px';
churchTimer.style.fontFamily = 'monospace';
churchTimer.style.margin = '0px';
churchTimer.href = '/city/church';
churchTimer.textContent = 'Church Cooldown: Calculating...';
timersContainer.appendChild(potionTimer);
timersContainer.appendChild(churchTimer);
// Add both sections to the main container
mainContainer.appendChild(progressBarsContainer);
mainContainer.appendChild(timersContainer);
// Append the main container to the desired parent element
document.getElementsByClassName("gold")[0].appendChild(mainContainer);
// Start updating the timers
updatePotionCooldownDisplay();
setInterval(updatePotionCooldownDisplay, 1000);
updateChurchCooldownDisplay();
setInterval(updateChurchCooldownDisplay, 1000);
}
function calculateCurrentHealth(){
const regenPerSecond = CHARACTER.regenHealth / 3600; // Convert regenHealth from per hour to per second
// Calculate the total health regenerated since the page loaded
const elapsedSeconds = (Date.now() - pageLoadTime) / 1000; // Time elapsed in seconds
const regeneratedHealth = regenPerSecond * elapsedSeconds;
// Calculate the updated health, without modifying the original CHARACTER.health
const updatedHealth = Math.min(
CHARACTER.health + regeneratedHealth,
CHARACTER.maxHealth
);
return updatedHealth;
}
// Start real-time health regeneration
function startHealthRegeneration() {
const regenInterval = 200; // Update every 200 ms
setInterval(() => {
// Update the progress bar with the calculated health
updateProgressBars(calculateCurrentHealth());
}, regenInterval);
}
// Update the existing progress bars
function updateProgressBars(calculatedHealth) {
// Update Energy Progress Bar
//const energyBar = document.getElementById('energyProgressBar').children[0];
//energyBar.style.width = `${(CHARACTER.energy / CHARACTER.maxEnergy) * 100}%`;
//const energyText = document.getElementById('energyProgressBar').children[1];
//energyText.textContent = `${CHARACTER.energy}`;
// Update Health Progress Bar
const healthBar = document.getElementById('healthProgressBar').children[0];
healthBar.style.width = `${(calculatedHealth / CHARACTER.maxHealth) * 100}%`;
const healthText = document.getElementById('healthProgressBar').children[1];
// Format the health value with thousands separators
let healthWithoutDecimals = Math.floor(calculatedHealth);
healthText.textContent = `${healthWithoutDecimals > 999 ? healthWithoutDecimals.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.'): healthWithoutDecimals}`;
}
// Function to update the timer display
function updatePotionCooldownDisplay() {
const timerElement = document.getElementById('potionCooldownTimer');
const currentTime = new Date().getTime() / 1000; // Current time in seconds
if (CHARACTER.potionCooldownEnd > currentTime) {
const remainingTime = CHARACTER.potionCooldownEnd - currentTime; // Remaining time in seconds
const hours = Math.floor(remainingTime / 3600);
const minutes = Math.floor((remainingTime % 3600) / 60);
const seconds = Math.round(remainingTime % 60);
timerElement.textContent = `Potion : ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
} else {
timerElement.textContent = 'Potion Ready!';
}
}
// Add the church cooldown timer display
function updateChurchCooldownTimer() {
const churchCountdownElement = document.getElementsByClassName('hasCountdown')[0];
if (churchCountdownElement) {
const cooldownTime = churchCountdownElement.textContent.trim();
const currentTime = new Date().getTime() / 1000; // Current time in seconds
const cooldownSeconds = timeToSeconds(cooldownTime); // Convert cooldown time to seconds
const endTime = currentTime + cooldownSeconds; // Calculate the end time
// Save the end time to the character object
CHARACTER.churchCooldownEnd = endTime;
updateCharacter(); // Save updated character data
}
}
// Function to update the church cooldown display
function updateChurchCooldownDisplay() {
const timerElement = document.getElementById('churchCooldownTimer');
const currentTime = new Date().getTime() / 1000; // Current time in seconds
if (CHARACTER.churchCooldownEnd > currentTime) {
const remainingTime = CHARACTER.churchCooldownEnd - currentTime; // Remaining time in seconds
const hours = Math.floor(remainingTime / 3600);
const minutes = Math.floor((remainingTime % 3600) / 60);
const seconds = Math.round(remainingTime % 60);
timerElement.textContent = `Church : ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
} else {
timerElement.textContent = 'Church Ready!';
}
}
function addAdditionnalLink() {
// Find the <li> containing the Chasse link
const chasseListItem = document.querySelector('li.free-space > a[href$="/robbery/index"]');
if (chasseListItem) {
// Navigate to the parent <li> element
const chasseLi = chasseListItem.closest('li');
// Remove the class "free-space"
chasseLi.removeAttribute('class');
if (window.location.pathname.contains('robbery')){
chasseLi.className = "active";
}
// Create a new <li> for the Grotte link
const grotteLi = document.createElement('li');
if (window.location.pathname.contains('/grotte')){
if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class');
grotteLi.className = "active";
}
grotteLi.innerHTML = '<a href="/city/grotte" target="_top">Grotto</a>';
const graveLi = document.createElement('li');
if (window.location.pathname.contains('/city/graveyard') || window.location.pathname.contains('/user/working')){
if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class');
graveLi.className = "active";
}
graveLi.innerHTML = '<a href="/city/graveyard" target="_top">Graveyard</a>';
const shopLi = document.createElement('li');
if (window.location.pathname.contains('/city/shop/')){
if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class');
shopLi.className = "active";
}
shopLi.innerHTML = '<a href="/city/shop/potions/&page=1&premiumfilter=nonpremium" target="_top">Shop</a>';
const questsLi = document.createElement('li');
questsLi.className = "free-space";
if (window.location.pathname.contains('/city/missions')){
if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class');
questsLi.className = "active free-space";
}
questsLi.innerHTML = '<a href="/city/missions" target="_top">Quests</a>';
// Insert the new links (in reverse)
chasseLi.insertAdjacentElement('afterend', questsLi);
chasseLi.insertAdjacentElement('afterend', shopLi);
chasseLi.insertAdjacentElement('afterend', graveLi);
chasseLi.insertAdjacentElement('afterend', grotteLi);
}
}
function moveGameEventDiv() {
const gameEventDiv = document.getElementById('gameEvent');
const itemsDiv = document.getElementById('items');
if (gameEventDiv && itemsDiv) {
itemsDiv.insertAdjacentElement('afterend', gameEventDiv);
}
//scroll up after upgrading a skill
if (window.location.hash=='#tabs-2') window.scrollTo(0, 0);
//if (window.location.hash=='#potions') document.getElementsByClassName("ui-accordion-header")[2].scrollIntoView({ behavior: 'smooth' });
}
function defaultNonPremiumShop() {
const links = document.querySelectorAll('a'); // Select all anchor elements
links.forEach(link => {
// Check if the link href contains '/city/shop/'
if (link.href.includes('/city/shop')) {
// If the URL doesn't already have a query string, add it
if (!link.href.includes('&premiumfilter=nonpremium')) {
link.href += '&premiumfilter=nonpremium';
}
}
});
/*
var premiumfilter = document.querySelector('select[name="premiumfilter"]'); // Replace with the correct selector if necessary
if (premiumfilter) {
premiumfilter.value = 'nonpremium'; // Set default value to 'nonpremium'
}*/
}
function redirectAfterGrotteFight() {
if ((CHARACTER.autoRedirectGrotte || CHARACTER.autoGrotto[0] || CHARACTER.autoGrotto[1] || CHARACTER.autoGrotto[2]) && window.location.href.includes('report/fightreport/') && window.location.href.includes('/grotte')) {
// Redirect to '/city/grotte'
for (let index = 0; index < 3; index++) {
if(CHARACTER.autoGrotto[index])saveGrottoStats(index);
}
window.location.href = '/city/grotte';
}
// all below is to add the checkbox
if (!window.location.pathname.contains('/city/grotte')) return;
const buildingDescElement = document.getElementsByClassName('buildingDesc')[0];
if (!buildingDescElement) return;
// Create the switch container
const switchContainer = document.createElement('div');
switchContainer.classList.add('auto-redirect-switch');
switchContainer.style.marginTop = '10px';
// Create the label for the switch
const label = document.createElement('label');
label.textContent = 'Auto redirect after fight';
label.style.marginRight = '10px';
// Create the switch itself
const switchInput = document.createElement('input');
switchInput.type = 'checkbox';
switchInput.style.transform = 'scale(1.2)'; // Optional: make it slightly bigger
switchInput.style.display = 'block';
switchInput.checked = CHARACTER.autoRedirectGrotte; // Get the saved state
// Add change event to store the state of the switch
switchInput.addEventListener('change', () => {
CHARACTER.autoRedirectGrotte = switchInput.checked;
updateCharacter();
// Implement logic for auto redirection here if needed
});
// Append the label and input (switch) to the container
switchContainer.appendChild(label);
switchContainer.appendChild(switchInput);
// Append the switch to the buildingDesc element
buildingDescElement.appendChild(switchContainer);
}
function addAutoGrottoButton() {
// make sure the variable is defined
if (!Array.isArray(CHARACTER.autoGrotto)) {
CHARACTER.autoGrotto = [false, false, false];
}
if (!CHARACTER.goldEarned) {
CHARACTER.goldEarned = {};
}
if (!CHARACTER.dmgTaken) {
CHARACTER.dmgTaken = {};
}
if (!CHARACTER.xpEarned) {
CHARACTER.xpEarned = {};
}
for (let index = 0; index < 3; index++) {
//const target = $(`table.noBackground form.clearfix div input`)[index];
const target = document.querySelectorAll('table.noBackground form.clearfix div input')[index];
if (!target) return;
// Create the button
const button = document.createElement("button");
if(CHARACTER.autoGrotto[index]){
button.textContent = "Auto : ON";
button.style.backgroundPosition = '0 -183px';
} else {
button.textContent = "Auto : OFF";
//button.style.backgroundPosition = '0 -44px';
}
button.className = "btn-small left btn-autoGrotto";
button.style.margin = "10px";
button.style.padding = "0 0 5px";
// Add a click event listener
button.addEventListener("click", function (event) {
event.preventDefault(); // Prevent default button behavior
if(!CHARACTER.autoGrotto[index] && isReadyForGrotto()){
CHARACTER.autoGrotto[index] = true;
updateCharacter();
button.textContent = "Auto : ON";
button.style.backgroundPosition = '0 -183px';
document.querySelectorAll('table.noBackground form.clearfix div input')[index].click();
} else {
CHARACTER.autoGrotto[index] = false;
updateCharacter();
button.textContent = "Auto : OFF";
button.style.backgroundPosition = '0 -44px';
}
//console.log(`CHARACTER.autoGrotto[${index}] is now `, CHARACTER.autoGrotto);
});
// Insert the button after the target element
target.parentNode.insertBefore(button, target.nextSibling);
displayStatsAverage(index);
}
}
function autoFightGrotto() {
if(!CHARACTER.autoGrotto[0] && !CHARACTER.autoGrotto[1] && !CHARACTER.autoGrotto[2]) return;
const randomDelay = Math.random() * 1000 + 200;
console.log(`Action will be executed after ${randomDelay.toFixed(0)}ms`);
// Set the timeout
setTimeout(() => {
if(!isReadyForGrotto()){
CHARACTER.autoGrotto[0] = false;
CHARACTER.autoGrotto[1] = false;
CHARACTER.autoGrotto[2] = false;
updateCharacter();
const buttons = document.querySelectorAll('.btn-autoGrotto');
buttons.forEach(button => {
button.textContent = 'Auto : OFF';
button.style.backgroundPosition = '0 -44px';
});
} else {
if(CHARACTER.autoGrotto[0])document.querySelectorAll('table.noBackground form.clearfix div input')[0].click();
if(CHARACTER.autoGrotto[1])document.querySelectorAll('table.noBackground form.clearfix div input')[1].click();
if(CHARACTER.autoGrotto[2])document.querySelectorAll('table.noBackground form.clearfix div input')[2].click();
}
}, randomDelay);
}
function isReadyForGrotto() {
return (calculateCurrentHealth() > 9000 && CHARACTER.energy > 0);
}
function saveGrottoStats(grottoDifficulty){
const goldEarned = parseInt(formatNumber(document.getElementsByClassName("gold")[1].firstChild.textContent.split("\n")[1]));
const xpEarned = parseInt(document.getElementsByClassName("gold")[1].lastChild.textContent.replace(/\D/g, ''));
// Ensure the goldEarned array for the selected difficulty exists
if (!CHARACTER.goldEarned[grottoDifficulty]) {
CHARACTER.goldEarned[grottoDifficulty] = [];
}
// Push the new gold earned value into the array
CHARACTER.goldEarned[grottoDifficulty].push(goldEarned);
// Keep only the last 20 entries for each difficulty
if (CHARACTER.goldEarned[grottoDifficulty].length > 20) {
CHARACTER.goldEarned[grottoDifficulty].shift(); // Remove the oldest entry
}
// Ensure the dmgTaken array for the selected difficulty exists
if (!CHARACTER.dmgTaken[grottoDifficulty]) {
CHARACTER.dmgTaken[grottoDifficulty] = [];
}
// Push the new dmg taken value into the array
CHARACTER.dmgTaken[grottoDifficulty].push(getGrottoHealthDamage(goldEarned));
// Keep only the last 20 entries for each difficulty
if (CHARACTER.dmgTaken[grottoDifficulty].length > 20) {
CHARACTER.dmgTaken[grottoDifficulty].shift(); // Remove the oldest entry
}
// Ensure the xpEarned array for the selected difficulty exists
if (!CHARACTER.xpEarned[grottoDifficulty]) {
CHARACTER.xpEarned[grottoDifficulty] = [];
}
// Push the new dmg taken value into the array
CHARACTER.xpEarned[grottoDifficulty].push(xpEarned);
// Keep only the last 20 entries for each difficulty
if (CHARACTER.xpEarned[grottoDifficulty].length > 20) {
CHARACTER.xpEarned[grottoDifficulty].shift(); // Remove the oldest entry
}
// Update the character data with the new gold earnings
updateCharacter();
}
// This function calculates the average gold for a given difficulty
function calculateGoldAverage(grottoDifficulty) {
if (!CHARACTER.goldEarned[grottoDifficulty] || CHARACTER.goldEarned[grottoDifficulty].length < 1) return 0;
let totalGold = 0;
// Loop through the gold history for the given difficulty
for (let i = 0; i < CHARACTER.goldEarned[grottoDifficulty].length; i++) {
totalGold += CHARACTER.goldEarned[grottoDifficulty][i];
}
return totalGold / CHARACTER.goldEarned[grottoDifficulty].length;
}
function calculateDamageAverage(grottoDifficulty) {
if (!CHARACTER.dmgTaken[grottoDifficulty] || CHARACTER.dmgTaken[grottoDifficulty].length < 1) return 0;
let totalDmg = 0;
// Loop through the gold history for the given difficulty
for (let i = 0; i < CHARACTER.dmgTaken[grottoDifficulty].length; i++) {
totalDmg += CHARACTER.dmgTaken[grottoDifficulty][i];
}
return totalDmg / CHARACTER.dmgTaken[grottoDifficulty].length;
}
function calculateXPAverage(grottoDifficulty) {
if (!CHARACTER.xpEarned[grottoDifficulty] || CHARACTER.xpEarned[grottoDifficulty].length < 1) return 0;
let totalGold = 0;
// Loop through the gold history for the given difficulty
for (let i = 0; i < CHARACTER.xpEarned[grottoDifficulty].length; i++) {
totalGold += CHARACTER.xpEarned[grottoDifficulty][i];
}
return totalGold / CHARACTER.xpEarned[grottoDifficulty].length;
}
// Function to display the average gold under each button
function displayStatsAverage(grottoDifficulty) {
//console.log("Average gold for difficult "+grottoDifficulty+" : "+calculateGoldAverage(grottoDifficulty));
const button = document.querySelectorAll('.btn-autoGrotto')[grottoDifficulty];
if (!button) return;
let avgGoldText = `${calculateGoldAverage(grottoDifficulty).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} `;
let avgDmg = `${calculateDamageAverage(grottoDifficulty).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} `;
let avgXP = `${calculateXPAverage(grottoDifficulty).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} `;
// Check if the display already exists, and update or create a new one
let avgElement = button.querySelector('.gold-average');
avgElement = document.createElement('div');
avgElement.classList.add('gold-average');
avgElement.style.fontSize = '15px';
avgElement.style.marginLeft = '10px';
avgElement.style.textAlign = 'center'; // Center the text
avgElement.style.display = 'block'; // Make sure it takes up the full width and goes below the button
avgElement.style.width = '160px';
avgElement.style.textShadow = "0 0 4px #FF0000";
avgElement.style.fontFamily = 'monospace';
avgElement.style.fontWeight = 'bold';
avgElement.style.color = 'white';
avgElement.style.lineHeight = '25px';
button.parentNode.insertBefore(avgElement, button.nextSibling);
avgElement.textContent = avgGoldText;
// Create an image element and append it after the text
let imgGold = document.createElement('img');
imgGold.src = '/img/symbols/res2.gif';
avgElement.appendChild(imgGold);
imgGold.align = 'absmiddle';
// health lost
var lineBreak = document.createElement('br');
avgElement.appendChild(lineBreak);
var avgDmgText = document.createTextNode(avgDmg);
avgElement.appendChild(avgDmgText);
let imgHealth = document.createElement('img');
imgHealth.src = '/img/symbols/herz.png';
avgElement.appendChild(imgHealth);
imgHealth.align = 'absmiddle';
// xp earned
var lineBreak2 = document.createElement('br');
avgElement.appendChild(lineBreak2);
var avgXPText = document.createTextNode(avgXP);
avgElement.appendChild(avgXPText);
let imgXP = document.createElement('img');
imgXP.src = '/img/symbols/level.gif';
avgElement.appendChild(imgXP);
imgXP.align = 'absmiddle';
}
// if gold earned = 0, then it's lost,and the dmg taken is on left and not on right
function getGrottoHealthDamage(goldEarned){
var win = 1;
if(goldEarned == 0){
win = 0;
}
const wholeText = document.querySelectorAll('#reportResult div.wrap-left div.wrap-content p')[0].textContent;
const extractedText = wholeText.match(/\(([^)]+)\)/)[1]; // Regular expression to match content between parentheses
const numbers = extractedText.split(":");
return(parseInt(numbers[win]));
}
})();