IWRPG - Skilling - Add more info to estiamtes

Adding level up and materials left timers

// ==UserScript==
// @name         IWRPG - Skilling - Add more info to estiamtes
// @namespace    http://tampermonkey.net/
// @version      2024-07-12
// @description  Adding level up and materials left timers 
// @author       Grotok
// @match        https://ironwoodrpg.com/*
// @icon         https://ironwoodrpg.com/assets/items/raw-bass.png
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

// Function to add new rows
function addNewRow() {
    // Check if there's a button with the text "Estimates"
    var estimatesButton = Array.from(document.querySelectorAll('.tabs .tab')).find(button => button.textContent.trim() === 'Estimates');

    if (!estimatesButton) {
        console.error('Estimates button not found');
        return;
    }

    // Find the 'Actions' row
    var actionsRow = Array.from(document.querySelectorAll('.card .row')).find(row => row.querySelector('.name').textContent.trim() === 'Actions');

    if (!actionsRow) {
        console.error('Actions row not found');
        return;
    }

    // Get the dynamic attribute name from the 'Actions' row
    var dynamicAttr = Array.from(actionsRow.attributes).find(attr => attr.name.startsWith('_ngcontent')).name;

    // Create a new div element for the new row
    var newRow = document.createElement('div');
    newRow.setAttribute(dynamicAttr, '');
    newRow.className = 'row ng-star-inserted level-up'; // Add the level-up class

    // Create the 'name' div
    var nameDiv = document.createElement('div');
    nameDiv.setAttribute(dynamicAttr, '');
    nameDiv.className = 'name';
    nameDiv.textContent = 'Level up';

    // Create the 'value' div
    var valueDiv = document.createElement('div');
    valueDiv.setAttribute(dynamicAttr, '');
    valueDiv.className = 'value';
    valueDiv.textContent = 'Calculating...';  // Placeholder text

    // Append the 'name' and 'value' divs to the new row
    newRow.appendChild(nameDiv);
    newRow.appendChild(valueDiv);

    // Insert the new row after the 'Actions' row
    actionsRow.parentNode.insertBefore(newRow, actionsRow.nextSibling);

    // Call the function to calculate the XP difference and update the value every 5 seconds
    setInterval(() => updateXPDifference(dynamicAttr), 5000);
}

// Function to calculate XP difference and update the "Level up" row
function updateXPDifference(dynamicAttr) {
    // Find the 'skill' element
    var skillElement = document.querySelector('.skill');

    if (!skillElement) {
        console.error('Skill element not found');
        return;
    }

    // Extract the XP values
    var xpText = skillElement.querySelector('.exp').textContent.trim();
    var xpValues = xpText.split(' / ');
    var xpA = parseInt(xpValues[0].replace(',', ''));
    var xpB = parseInt(xpValues[1].replace(',', ''));

    // Calculate the difference
    var xpDifference = xpB - xpA;

    // Find the XP Gained per hour value
    var xpGainedText = Array.from(document.querySelectorAll('.card .row')).find(row => row.querySelector('.name').textContent.trim() === 'XP Gained').querySelector('.value').textContent.trim();
    var xpGainedPerHour = parseInt(xpGainedText.split(' ')[0].replace(',', ''));

    // Calculate the time to level up (in hours) based on XP difference and XP gained per hour
    var hoursToLevelUp = xpDifference / xpGainedPerHour;

    // Convert hours to seconds
    var secondsToLevelUp = hoursToLevelUp * 3600;

    // Convert remaining time to hours, minutes, and seconds format
    var formattedTime = formatTime(secondsToLevelUp);

    // Update the "Level up" row's value
    var levelUpValueDiv = document.querySelector(`.level-up .value[${dynamicAttr}]`);
    if (levelUpValueDiv) {
        levelUpValueDiv.textContent = formattedTime;
    } else {
        console.error('Level up row not found');
    }

    // Update the materials consumption rows
    updateMaterials(dynamicAttr);
}

// Function to update materials consumption rows
function updateMaterials(dynamicAttr) {
    // Find the active-link element and extract the timer value
    var activeLinkElement = document.querySelector('.active-link');
    if (!activeLinkElement) {
        console.error('Active link element not found');
        return;
    }

    var timerText = activeLinkElement.querySelector('.interval span').textContent.trim();
    var timerValue = parseFloat(timerText.replace('s', ''));

    // Calculate the actions per hour based on the timer value
    var actionsPerHour = 3600 / timerValue;

    // Find all cards and select the one with the header name 'Materials'
    var cards = document.querySelectorAll('.card');
    var materialsCard = Array.from(cards).find(card => card.querySelector('.header .name').textContent.trim() === 'Materials');

    if (!materialsCard) {
        console.error('Materials card not found');
        return;
    }

    // Extract all material rows
    var materialRows = materialsCard.querySelectorAll('.row.ng-star-inserted');

    // Track existing materials
    var existingMaterials = new Set();

    // Iterate over each material row and calculate the remaining time
    materialRows.forEach(materialRow => {
        var materialName = materialRow.querySelector('.name').textContent.trim();
        var materialValueText = materialRow.querySelector('.value').textContent.trim();
        var materialValues = materialValueText.split(' / ');
        var materialX = parseInt(materialValues[0].replace(',', ''));
        var materialY = parseInt(materialValues[1].replace(',', ''));

        // Calculate the remaining amount
        var remainingAmount = materialX / materialY;

        // Calculate the time until the material runs out (in seconds)
        var timeUntilOutOfMaterial = remainingAmount / actionsPerHour * 3600;

        // Convert remaining time to hours, minutes, and seconds format
        var formattedMaterialTime = formatTime(timeUntilOutOfMaterial);

        existingMaterials.add(materialName);

        // Check if the material row already exists
        var existingMaterialRow = document.querySelector(`.material-time[data-material="${materialName}"]`);

        if (existingMaterialRow) {
            // Update the existing material row's value
            var materialValueDiv = existingMaterialRow.querySelector('.value');
            materialValueDiv.textContent = formattedMaterialTime;
        } else {
            // Create a new div element for the material row
            var newMaterialRow = document.createElement('div');
            newMaterialRow.setAttribute(dynamicAttr, '');
            newMaterialRow.className = 'row ng-star-inserted material-time'; // Add the material-time class
            newMaterialRow.setAttribute('data-material', materialName); // Add a data attribute for the material name

            // Create the 'name' div
            var materialNameDiv = document.createElement('div');
            materialNameDiv.setAttribute(dynamicAttr, '');
            materialNameDiv.className = 'name';
            materialNameDiv.textContent = `${materialName} remaining`;

            // Create the 'value' div
            var materialValueDiv = document.createElement('div');
            materialValueDiv.setAttribute(dynamicAttr, '');
            materialValueDiv.className = 'value';
            materialValueDiv.textContent = formattedMaterialTime;

            // Append the 'name' and 'value' divs to the new material row
            newMaterialRow.appendChild(materialNameDiv);
            newMaterialRow.appendChild(materialValueDiv);

            // Insert the new material row under the "Level up" row
            var levelUpRow = document.querySelector('.level-up');
            if (levelUpRow && levelUpRow.parentNode) {
                levelUpRow.parentNode.insertBefore(newMaterialRow, levelUpRow.nextSibling);
            }
        }
    });

    // Remove material rows that no longer exist
    var materialTimeRows = document.querySelectorAll('.material-time');
    materialTimeRows.forEach(row => {
        var materialName = row.getAttribute('data-material');
        if (!existingMaterials.has(materialName)) {
            row.parentNode.removeChild(row);
        }
    });
}

// Helper function to format time in hours, minutes, and seconds
function formatTime(seconds) {
    var h = Math.floor(seconds / 3600);
    var m = Math.floor((seconds % 3600) / 60);
    var s = Math.floor(seconds % 60);
    return `${h}h ${m}m ${s}s`;
}

// Function to ensure rows are present and add them if missing
function ensureRowsExist() {
    var levelUpRow = document.querySelector('.level-up');
    if (!levelUpRow) {
        addNewRow();
    } else {
        var dynamicAttr = Array.from(levelUpRow.attributes).find(attr => attr.name.startsWith('_ngcontent')).name;
        updateXPDifference(dynamicAttr);
    }
}

// Call the function to add the new row after a 2-second delay
setTimeout(addNewRow, 2000);

// Set an interval to ensure rows are present every few seconds
setInterval(ensureRowsExist, 5000);




})();