MediaWiki:DropCalc.js: Difference between revisions

From Roat Pkz
Jump to navigation Jump to search
No edit summary
Tag: Reverted
mNo edit summary
 
(44 intermediate revisions by 2 users not shown)
Line 10: Line 10:
         '<br><button id="calcDropBtn">Calculate Drop Rate</button>' +
         '<br><button id="calcDropBtn">Calculate Drop Rate</button>' +
         '<div style="margin-top:10px;">Final Drop Rate: <span id="finalDrop">0</span></div>';
         '<div style="margin-top:10px;">Final Drop Rate: <span id="finalDrop">0</span></div>';
        var dropTable = document.getElementById("dropCalcTable");
dropTable.style.border = "1px solid #596e96";  // same color as SlayerPointsCalc
dropTable.style.borderCollapse = "collapse";
dropTable.style.borderRadius = "8px";          // optional rounded corners


     var table = document.getElementById("dropCalcTable");
     var table = document.getElementById("dropCalcTable");
Line 26: Line 30:


     var bonuses = [
     var bonuses = [
         { name: "Donator Rank", id: "donatorBonus", options: [
         { name: "Donator Rank", id: "donatorBonus", options: [{name:"None",value:0},{name:"Donator 15%",value:15},{name:"Super Donator 25%",value:25},{name:"Extreme Donator 30%",value:30},{name:"Legendary Donator 35%",value:35},{name:"Royal Donator 40%",value:40},{name:"Divine Donator 45%",value:45}]},
            {name:"None",value:0},{name: "Donator 15%", value: 15, icon: "https://wiki.roatpkz.com/images/5/59/Donatoricon.png"},{name:"Super Donator 25%",value:25, icon: "https://wiki.roatpkz.com/images/2/2d/Superdonatoricon.png"},
         { name: "Monster Slayer Perk (Clan)", id: "slayerBonus", options: [{name:"None",value:0},{name:"10%",value:10}]},
            {name:"Extreme Donator 30%",value:30},{name:"Legendary Donator 35%",value:35},
            {name:"Royal Donator 40%",value:40},{name:"Divine Donator 45%",value:45}]},
         { name: "Monster Slayer Perk", id: "slayerBonus", options: [{name:"None",value:0},{name:"10%",value:10}]},
         { name: "Collector's Ring", id: "ringBonus", options: [{name:"None",value:0},{name:"3%",value:3},{name:"6%",value:6}]},
         { name: "Collector's Ring", id: "ringBonus", options: [{name:"None",value:0},{name:"3%",value:3},{name:"6%",value:6}]},
         { name: "Skull Bonus", id: "skullBonus", options: [{name:"None",value:0},{name:"20%",value:20}]},
         { name: "Skull Bonus", id: "skullBonus", options: [{name:"None",value:0},{name:"20%",value:20}]},
         { name: "Voting Bonus", id: "voteBonus", options: [{name:"None",value:0},{name:"20%",value:20}]}
         { name: "Voting Bonus", id: "voteBonus", options: [{name:"None",value:0},{name:"20%",value:20}]},
        // Pet Collector Scroll dropdown, only for pets
        { name: "Pet Collector Scroll", id: "petScrollBonus", options: [{name:"None",value:0},{name:"10%",value:10}], petOnly: true }
     ];
     ];


     // Items that disable Skull Bonus
     // Items where Skull Bonus is disabled
     var skullDisabledItems = ["TokHaar-kal"];
     var skullDisabledItems = ["TokHaar-kal"];
    // Example pets
    var petItems = ["Tzrek-jad", "Nexling", "Skotos", "Pet Lil Gemstone Crab", "Pet Dark core", "Pet Tiny Tormentor", "Pet Revenant dragon", "Callisto cub", "Venenatis spiderling", "Vet\'ion jr", "Scorpia\'s offspring", "Prince black dragon", "Pet chaos elemental (Chaos Fanatic)", "Pet chaos elemental (Chaos Elemental)", "Guardian of Votes", "Pet Demonic Gorilla", "Pet snakeling", "Pet kraken", "Pet aquanite (2026)", "Pet Royal Revenant Dragon", "Pet Divine Glod", "Divine Third Age Warrior", "Pet Divine dark core", "Pet Divine Chaos elemental", "Pet Divine Venenatis spiderling", "Pet Divine Callisto cub", "Divine Vet\'ion jr.", "Divine Nexling", "Prince Divine Dragon", "Pet Divine Demonic Gorilla", "Pet Tiny Divine Tormentor"];


     bonuses.forEach(function(bonus, index) {
     bonuses.forEach(function(bonus, index) {
Line 43: Line 48:
         row.style.background = index % 2 === 0 ? '#313e59' : '#222e45';
         row.style.background = index % 2 === 0 ? '#313e59' : '#222e45';


        var cell1 = row.insertCell();
var cell1 = row.insertCell();
        cell1.textContent = bonus.name;
         cell1.style.padding = '5px';
         cell1.style.padding = '5px';
        cell1.style.borderRight = '1px solid #596e96';
if(bonus.name !== "Skull Bonus") {
    // Create a wiki-style link
    var pageName = bonus.name.replace(/ /g, '_');
    var link = document.createElement('a');
    link.href = '/' + pageName;
    link.textContent = bonus.name;
    link.style.color = '#fff';
    cell1.appendChild(link);
} else {
    // Just plain text for this one
    cell1.textContent = bonus.name;
    cell1.style.color = '#fff';
}


         var cell2 = row.insertCell();
         var cell2 = row.insertCell();
         cell2.style.padding = '5px';
         cell2.style.padding = '5px';
        cell2.style.borderRight = '1px solid #596e96';


         var cell3 = row.insertCell();
         var cell3 = row.insertCell();
Line 54: Line 73:
         cell3.textContent = "-";
         cell3.textContent = "-";
         cell3.style.padding = '5px';
         cell3.style.padding = '5px';
        cell3.style.textAlign = 'center';
       
        var select = document.createElement('select');
        select.id = bonus.id;


         if(bonus.id === "donatorBonus") {
         bonus.options.forEach(function(opt){
            // Custom dropdown with icons
             var option = document.createElement('option');
             var dropdown = document.createElement('div');
             option.value = opt.value;
             dropdown.className = 'custom-dropdown';
             option.textContent = opt.name;
             dropdown.id = bonus.id;
            select.appendChild(option);
        });


            var selected = document.createElement('div');
        // Disable pet scroll by default if petOnly
            selected.className = 'selected';
        if (bonus.petOnly) {
            selected.textContent = "Select Rank";
             select.disabled = true;
            dropdown.appendChild(selected);
             select.style.opacity = 0.5;
 
        }
            var optionsContainer = document.createElement('div');
             optionsContainer.className = 'options';
 
             bonus.options.forEach(function(opt){
                var optionDiv = document.createElement('div');
                optionDiv.dataset.value = opt.value;
 
                // Optional: icon path (replace with your actual image paths)
var img = document.createElement('img');
img.src = opt.icon; // use the icon from the option
img.className = 'icon';
img.style.width = '16px';
img.style.height = '16px';
img.style.marginRight = '5px';
optionDiv.appendChild(img);


                var textNode = document.createTextNode(opt.name);
        cell2.appendChild(select);
                optionDiv.appendChild(textNode);


                optionsContainer.appendChild(optionDiv);
         select.addEventListener('change', function() {
 
            document.getElementById("calcDropBtn").click();
                optionDiv.addEventListener('click', function() {
        });
                    selected.textContent = opt.name;
                    selected.dataset.value = opt.value;
                    optionsContainer.style.display = 'none';
                    document.getElementById("calcDropBtn").click();
                });
            });
 
            dropdown.appendChild(optionsContainer);
            cell2.appendChild(dropdown);
 
            selected.addEventListener('click', function() {
                optionsContainer.style.display = optionsContainer.style.display === 'block' ? 'none' : 'block';
            });
 
         } else {
            var select = document.createElement('select');
            select.id = bonus.id;
            bonus.options.forEach(function(opt){
                var option = document.createElement('option');
                option.value = opt.value;
                option.textContent = opt.name;
                select.appendChild(option);
            });
            cell2.appendChild(select);
 
            // Trigger recalculation when bonus changes
            select.addEventListener('change', function() {
                document.getElementById("calcDropBtn").click();
            });
        }
     });
     });


Line 124: Line 102:
     baseDiv.style.margin = '10px 0';
     baseDiv.style.margin = '10px 0';
     baseDiv.innerHTML =
     baseDiv.innerHTML =
         'Item: <input list="dropItems" id="itemSearch" placeholder="Search item..." style="width:260px;"> ' +
         'Item: <input list="dropItems" id="itemSearch" placeholder="Search item..." style="width:280px;"> ' +
         'Base Rate: <input type="number" id="baseRate" value="1000" style="width:80px;">' +
         'Base Rate: <input type="number" id="baseRate" value="1000" style="width:80px;">' +
         '<datalist id="dropItems">' +
         '<datalist id="dropItems">' +
Line 130: Line 108:
         '<option data-rate="350" value="Torva Full Helm (1/350)">' +
         '<option data-rate="350" value="Torva Full Helm (1/350)">' +
         '<option data-rate="2560" value="Voidwaker gem (1/2560)">' +
         '<option data-rate="2560" value="Voidwaker gem (1/2560)">' +
         '<option data-rate="2560" value="Voidwaker hilt (1/2560)">' +
         '<option data-rate="2560" value="Voidwaker hilt (1/2560)">' +  
         '<option data-rate="2560" value="Voidwaker blade (1/2560)">' +
         '<option data-rate="2560" value="Voidwaker blade (1/2560)">' +  
         '<option data-rate="128" value="Ancient godsword (1/128)">' +
         '<option data-rate="128" value="Ancient godsword (1/128)">' +  
         '<option data-rate="64" value="Zaryte vambraces (1/64)">' +
         '<option data-rate="64" value="Zaryte vambraces (1/64)">' +  
         '<option data-rate="10240" value="Elysian sigil (1/10240)">' +
         '<option data-rate="10240" value="Elysian sigil (1/10240)">' +  
         '<option data-rate="1024" value="Smoudering heart (1/1024)">' +
         '<option data-rate="1024" value="Smouldering heart (1/1024)">' +  
         '<option data-rate="75" value="TokHaar-kal (1/75)">' +
         '<option data-rate="75" value="TokHaar-kal (1/75)">' +
         '<option data-rate="2560" value="Enchanted Collector\'s Ring (6%) (1/2560)">' +
         '<option data-rate="2560" value="Enchanted Collector\'s Ring (6%) (1/2560)">' +
        '<option data-rate="512" value="Nexling (1/512)">' +
        '<option data-rate="150" value="Tzrek-jad (1/150)">' +
        '<option data-rate="150" value="Skotos (1/150)">' +
        '<option data-rate="1024" value="Pet Lil Gemstone Crab (1/1024)">' +
        '<option data-rate="750" value="Pet Dark core (1/750)">' +
        '<option data-rate="1500" value="Pet Tiny Tormentor (1/1500)">' +
        '<option data-rate="5000" value="Pet Revenant dragon (1/5000)">' +
        '<option data-rate="500" value="Callisto cub (1/500)">' +
        '<option data-rate="500" value="Venenatis spiderling (1/500)">' +
        '<option data-rate="500" value="Vet\'ion jr (1/500)">' +
        '<option data-rate="1500" value="Scorpia\'s offspring (1/1500)">' +
        '<option data-rate="5000" value="Pet Royal Revenant dragon (1/5000)">' +
        '<option data-rate="512" value="Pet Divine Glod (1/512)">' +
        '<option data-rate="4000" value="Divine Third Age Warrior (1/4000)">' +
        '<option data-rate="750" value="Pet Divine dark core (1/750)">' +
        '<option data-rate="1500" value="Pet Divine Chaos elemental (1/1500)">' +
        '<option data-rate="500" value="Pet Divine Venenatis spiderling (1/500)">' +
        '<option data-rate="500" value="Pet Divine Callisto cub (1/500)">' +
        '<option data-rate="500" value="Divine Vet\'ion jr.  (1/500)">' +
        '<option data-rate="512" value="Divine Nexling (1/512)">' +
        '<option data-rate="1500" value="Prince Divine Dragon (1/1500)">' +
        '<option data-rate="2000" value="Pet Divine Demonic Gorilla (1/2000)">' +
        '<option data-rate="1500" value="Pet Tiny Divine Tormentor (1/1500)">' +
        '<option data-rate="1500" value="Prince black dragon (1/1500)">' +
        '<option data-rate="2250" value="Pet chaos elemental (Chaos Fanatic) (1/2250)">' +
        '<option data-rate="1500" value="Pet chaos elemental (Chaos Elemental) (1/1500)">' +
        '<option data-rate="100" value="Guardian of Votes (1/100)">' +
        '<option data-rate="2000" value="Pet Demonic Gorilla (1/2000)">' +
        '<option data-rate="1500" value="Pet snakeling (1/1500)">' +
        '<option data-rate="1500" value="Pet kraken (1/1500)">' +
        '<option data-rate="7000" value="Pet aquanite (2026) (1/7000)">' +
        '<option data-rate="5000" value="Summer ring (2026) (1/5000)">' +
         '</datalist>';
         '</datalist>';
     container.insertBefore(baseDiv, table);
     container.insertBefore(baseDiv, table);


     // Clear button inside search box
     // Wrap input for clear button
     var itemInput = document.getElementById("itemSearch");
     var itemInput = document.getElementById("itemSearch");
     itemInput.style.paddingRight = '20px';
     var wrapper = document.createElement('div');
    wrapper.style.position = 'relative';
    wrapper.style.display = 'inline-block';
    itemInput.parentNode.insertBefore(wrapper, itemInput);
    wrapper.appendChild(itemInput);
 
    var clearBtn = document.createElement('span');
    clearBtn.textContent = '✕';
    clearBtn.style.position = 'absolute';
    clearBtn.style.right = '5px';
    clearBtn.style.top = '50%';
    clearBtn.style.transform = 'translateY(-50%)';
    clearBtn.style.cursor = 'pointer';
    clearBtn.style.color = '#888';
    clearBtn.style.fontWeight = 'bold';
    clearBtn.title = 'Clear search';
    wrapper.appendChild(clearBtn);
 
    clearBtn.addEventListener('click', function() {
        itemInput.value = '';
        document.getElementById('baseRate').value = 0;
        document.getElementById('finalDrop').textContent = 0;
        bonuses.forEach(function(bonus) {
            document.getElementById(bonus.id + "Preview").textContent = '-';
            var sel = document.getElementById(bonus.id);
            if(sel.tagName === 'SELECT') sel.value = 0;
        });
    });
 
    // Auto-fill base rate and handle Skull & Pet Scroll enabling
     itemInput.addEventListener('input', function() {
     itemInput.addEventListener('input', function() {
         var options = document.getElementById("dropItems").options;
         var options = document.getElementById("dropItems").options;
Line 153: Line 192:
                 document.getElementById("baseRate").value = rate;
                 document.getElementById("baseRate").value = rate;


                 // Disable Skull Bonus if necessary
                 // Skull Bonus
                 var skullSelect = document.getElementById("skullBonus");
                 var skullSelect = document.getElementById("skullBonus");
                 var rawName = val.replace(/\s*\(1\/\d+\)$/, '');
                 var rawName = val.replace(/\s*\(1\/\d+\)$/, '');
                 if(skullDisabledItems.includes(rawName)) {
                 if (skullDisabledItems.includes(rawName)) {
                     skullSelect.disabled = true;
                     skullSelect.disabled = true;
                     skullSelect.style.opacity = 0.5;
                     skullSelect.style.opacity = 0.5;
Line 162: Line 201:
                     skullSelect.disabled = false;
                     skullSelect.disabled = false;
                     skullSelect.style.opacity = 1;
                     skullSelect.style.opacity = 1;
                }
                // Pet Scroll
                var petScroll = document.getElementById("petScrollBonus");
                if (petItems.includes(rawName)) {
                    petScroll.disabled = false;
                    petScroll.style.opacity = 1;
                } else {
                    petScroll.disabled = true;
                    petScroll.style.opacity = 0.5;
                    petScroll.value = 0; // reset to None
                 }
                 }


Line 168: Line 218:
             }
             }
         }
         }
    });
    // Recalculate when any bonus changes
    bonuses.forEach(function(bonus) {
        document.getElementById(bonus.id).addEventListener('change', function() {
            document.getElementById("calcDropBtn").click();
        });
     });
     });


Line 176: Line 233:


         bonuses.forEach(function(bonus){
         bonuses.forEach(function(bonus){
             var val;
             var val = parseFloat(document.getElementById(bonus.id).value) || 0;
            if(bonus.id === "donatorBonus") {
                val = parseFloat(document.getElementById("donatorBonus").querySelector('.selected').dataset.value) || 0;
            } else {
                val = parseFloat(document.getElementById(bonus.id).value) || 0;
            }
             finalRate *= (1 - val / 100);
             finalRate *= (1 - val / 100);
             document.getElementById(bonus.id + "Preview").textContent = Math.floor(finalRate);
             document.getElementById(bonus.id + "Preview").textContent = Math.floor(finalRate);

Latest revision as of 18:36, 18 July 2026

// --- DROPRATE CALCULATOR WITH TABLE ---
mw.hook('wikipage.content').add(function () {
    var container = document.getElementById("dropCalcContainer");
    if (!container) return;

    // Build HTML: Table
    container.innerHTML =
        '<table id="dropCalcTable" style="border-collapse: collapse; width: 100%; max-width: 500px;">' +
        '<thead></thead><tbody></tbody></table>' +
        '<br><button id="calcDropBtn">Calculate Drop Rate</button>' +
        '<div style="margin-top:10px;">Final Drop Rate: <span id="finalDrop">0</span></div>';
        var dropTable = document.getElementById("dropCalcTable");
dropTable.style.border = "1px solid #596e96";  // same color as SlayerPointsCalc
dropTable.style.borderCollapse = "collapse";
dropTable.style.borderRadius = "8px";          // optional rounded corners

    var table = document.getElementById("dropCalcTable");
    var header = table.createTHead();
    var headerRow = header.insertRow();
    headerRow.innerHTML =
        '<th style="padding-left: 10px;">Bonus</th>' +
        '<th>Percentage</th>' +
        '<th>Drop Rate</th>';
    headerRow.style.background = '#222e45';
    headerRow.style.color = '#fff';
    headerRow.style.fontWeight = 'bold';
    headerRow.style.textAlign = 'left';

    var tbody = table.tBodies[0];

    var bonuses = [
        { name: "Donator Rank", id: "donatorBonus", options: [{name:"None",value:0},{name:"Donator 15%",value:15},{name:"Super Donator 25%",value:25},{name:"Extreme Donator 30%",value:30},{name:"Legendary Donator 35%",value:35},{name:"Royal Donator 40%",value:40},{name:"Divine Donator 45%",value:45}]},
        { name: "Monster Slayer Perk (Clan)", id: "slayerBonus", options: [{name:"None",value:0},{name:"10%",value:10}]},
        { name: "Collector's Ring", id: "ringBonus", options: [{name:"None",value:0},{name:"3%",value:3},{name:"6%",value:6}]},
        { name: "Skull Bonus", id: "skullBonus", options: [{name:"None",value:0},{name:"20%",value:20}]},
        { name: "Voting Bonus", id: "voteBonus", options: [{name:"None",value:0},{name:"20%",value:20}]},
        // Pet Collector Scroll dropdown, only for pets
        { name: "Pet Collector Scroll", id: "petScrollBonus", options: [{name:"None",value:0},{name:"10%",value:10}], petOnly: true }
    ];

    // Items where Skull Bonus is disabled
    var skullDisabledItems = ["TokHaar-kal"];
    // Example pets
    var petItems = ["Tzrek-jad", "Nexling", "Skotos", "Pet Lil Gemstone Crab", "Pet Dark core", "Pet Tiny Tormentor", "Pet Revenant dragon", "Callisto cub", "Venenatis spiderling", "Vet\'ion jr", "Scorpia\'s offspring", "Prince black dragon", "Pet chaos elemental (Chaos Fanatic)", "Pet chaos elemental (Chaos Elemental)", "Guardian of Votes", "Pet Demonic Gorilla", "Pet snakeling", "Pet kraken", "Pet aquanite (2026)", "Pet Royal Revenant Dragon", "Pet Divine Glod", "Divine Third Age Warrior", "Pet Divine dark core", "Pet Divine Chaos elemental", "Pet Divine Venenatis spiderling", "Pet Divine Callisto cub", "Divine Vet\'ion jr.", "Divine Nexling", "Prince Divine Dragon", "Pet Divine Demonic Gorilla", "Pet Tiny Divine Tormentor"];

    bonuses.forEach(function(bonus, index) {
        var row = tbody.insertRow();
        row.style.background = index % 2 === 0 ? '#313e59' : '#222e45';

var cell1 = row.insertCell();
        cell1.style.padding = '5px';
        cell1.style.borderRight = '1px solid #596e96';
if(bonus.name !== "Skull Bonus") {
    // Create a wiki-style link
    var pageName = bonus.name.replace(/ /g, '_');
    var link = document.createElement('a');
    link.href = '/' + pageName;
    link.textContent = bonus.name;
    link.style.color = '#fff';
    cell1.appendChild(link);
} else {
    // Just plain text for this one
    cell1.textContent = bonus.name;
    cell1.style.color = '#fff';
}

        var cell2 = row.insertCell();
        cell2.style.padding = '5px';
        cell2.style.borderRight = '1px solid #596e96';

        var cell3 = row.insertCell();
        cell3.id = bonus.id + "Preview";
        cell3.textContent = "-";
        cell3.style.padding = '5px';
        cell3.style.textAlign = 'center';
        
        var select = document.createElement('select');
        select.id = bonus.id;

        bonus.options.forEach(function(opt){
            var option = document.createElement('option');
            option.value = opt.value;
            option.textContent = opt.name;
            select.appendChild(option);
        });

        // Disable pet scroll by default if petOnly
        if (bonus.petOnly) {
            select.disabled = true;
            select.style.opacity = 0.5;
        }

        cell2.appendChild(select);

        select.addEventListener('change', function() {
            document.getElementById("calcDropBtn").click();
        });
    });

    // Searchable item selector
    var baseDiv = document.createElement('div');
    baseDiv.style.margin = '10px 0';
    baseDiv.innerHTML =
        'Item: <input list="dropItems" id="itemSearch" placeholder="Search item..." style="width:280px;"> ' +
        'Base Rate: <input type="number" id="baseRate" value="1000" style="width:80px;">' +
        '<datalist id="dropItems">' +
        '<option data-rate="256" value="Zaryte Crossbow (1/256)">' +
        '<option data-rate="350" value="Torva Full Helm (1/350)">' +
        '<option data-rate="2560" value="Voidwaker gem (1/2560)">' +
        '<option data-rate="2560" value="Voidwaker hilt (1/2560)">' + 
        '<option data-rate="2560" value="Voidwaker blade (1/2560)">' + 
        '<option data-rate="128" value="Ancient godsword (1/128)">' + 
        '<option data-rate="64" value="Zaryte vambraces (1/64)">' + 
        '<option data-rate="10240" value="Elysian sigil (1/10240)">' + 
        '<option data-rate="1024" value="Smouldering heart (1/1024)">' + 
        '<option data-rate="75" value="TokHaar-kal (1/75)">' +
        '<option data-rate="2560" value="Enchanted Collector\'s Ring (6%) (1/2560)">' +
        '<option data-rate="512" value="Nexling (1/512)">' +
        '<option data-rate="150" value="Tzrek-jad (1/150)">' +
        '<option data-rate="150" value="Skotos (1/150)">' +
        '<option data-rate="1024" value="Pet Lil Gemstone Crab (1/1024)">' +
        '<option data-rate="750" value="Pet Dark core (1/750)">' +
        '<option data-rate="1500" value="Pet Tiny Tormentor (1/1500)">' +
        '<option data-rate="5000" value="Pet Revenant dragon (1/5000)">' +
        '<option data-rate="500" value="Callisto cub (1/500)">' +
        '<option data-rate="500" value="Venenatis spiderling (1/500)">' +
        '<option data-rate="500" value="Vet\'ion jr (1/500)">' +
        '<option data-rate="1500" value="Scorpia\'s offspring (1/1500)">' +
        '<option data-rate="5000" value="Pet Royal Revenant dragon (1/5000)">' +
        '<option data-rate="512" value="Pet Divine Glod (1/512)">' +
        '<option data-rate="4000" value="Divine Third Age Warrior (1/4000)">' +
        '<option data-rate="750" value="Pet Divine dark core (1/750)">' +
        '<option data-rate="1500" value="Pet Divine Chaos elemental (1/1500)">' +
        '<option data-rate="500" value="Pet Divine Venenatis spiderling (1/500)">' +
        '<option data-rate="500" value="Pet Divine Callisto cub (1/500)">' +
        '<option data-rate="500" value="Divine Vet\'ion jr.  (1/500)">' +
        '<option data-rate="512" value="Divine Nexling (1/512)">' +
        '<option data-rate="1500" value="Prince Divine Dragon (1/1500)">' +
        '<option data-rate="2000" value="Pet Divine Demonic Gorilla (1/2000)">' +
        '<option data-rate="1500" value="Pet Tiny Divine Tormentor (1/1500)">' +
        '<option data-rate="1500" value="Prince black dragon (1/1500)">' +
        '<option data-rate="2250" value="Pet chaos elemental (Chaos Fanatic) (1/2250)">' +
        '<option data-rate="1500" value="Pet chaos elemental (Chaos Elemental) (1/1500)">' +
        '<option data-rate="100" value="Guardian of Votes (1/100)">' +
        '<option data-rate="2000" value="Pet Demonic Gorilla (1/2000)">' +
        '<option data-rate="1500" value="Pet snakeling (1/1500)">' +
        '<option data-rate="1500" value="Pet kraken (1/1500)">' +
        '<option data-rate="7000" value="Pet aquanite (2026) (1/7000)">' +
        '<option data-rate="5000" value="Summer ring (2026) (1/5000)">' +
        '</datalist>';
    container.insertBefore(baseDiv, table);

    // Wrap input for clear button
    var itemInput = document.getElementById("itemSearch");
    var wrapper = document.createElement('div');
    wrapper.style.position = 'relative';
    wrapper.style.display = 'inline-block';
    itemInput.parentNode.insertBefore(wrapper, itemInput);
    wrapper.appendChild(itemInput);

    var clearBtn = document.createElement('span');
    clearBtn.textContent = '✕';
    clearBtn.style.position = 'absolute';
    clearBtn.style.right = '5px';
    clearBtn.style.top = '50%';
    clearBtn.style.transform = 'translateY(-50%)';
    clearBtn.style.cursor = 'pointer';
    clearBtn.style.color = '#888';
    clearBtn.style.fontWeight = 'bold';
    clearBtn.title = 'Clear search';
    wrapper.appendChild(clearBtn);

    clearBtn.addEventListener('click', function() {
        itemInput.value = '';
        document.getElementById('baseRate').value = 0;
        document.getElementById('finalDrop').textContent = 0;
        bonuses.forEach(function(bonus) {
            document.getElementById(bonus.id + "Preview").textContent = '-';
            var sel = document.getElementById(bonus.id);
            if(sel.tagName === 'SELECT') sel.value = 0;
        });
    });

    // Auto-fill base rate and handle Skull & Pet Scroll enabling
    itemInput.addEventListener('input', function() {
        var options = document.getElementById("dropItems").options;
        var val = itemInput.value;

        for (var i = 0; i < options.length; i++) {
            if (options[i].value === val) {
                var rate = options[i].getAttribute("data-rate");
                document.getElementById("baseRate").value = rate;

                // Skull Bonus
                var skullSelect = document.getElementById("skullBonus");
                var rawName = val.replace(/\s*\(1\/\d+\)$/, '');
                if (skullDisabledItems.includes(rawName)) {
                    skullSelect.disabled = true;
                    skullSelect.style.opacity = 0.5;
                } else {
                    skullSelect.disabled = false;
                    skullSelect.style.opacity = 1;
                }

                // Pet Scroll
                var petScroll = document.getElementById("petScrollBonus");
                if (petItems.includes(rawName)) {
                    petScroll.disabled = false;
                    petScroll.style.opacity = 1;
                } else {
                    petScroll.disabled = true;
                    petScroll.style.opacity = 0.5;
                    petScroll.value = 0; // reset to None
                }

                document.getElementById("calcDropBtn").click();
                break;
            }
        }
    });

    // Recalculate when any bonus changes
    bonuses.forEach(function(bonus) {
        document.getElementById(bonus.id).addEventListener('change', function() {
            document.getElementById("calcDropBtn").click();
        });
    });

    // Calculation
    document.getElementById("calcDropBtn").onclick = function() {
        var base = parseFloat(document.getElementById("baseRate").value) || 0;
        var finalRate = base;

        bonuses.forEach(function(bonus){
            var val = parseFloat(document.getElementById(bonus.id).value) || 0;
            finalRate *= (1 - val / 100);
            document.getElementById(bonus.id + "Preview").textContent = Math.floor(finalRate);
        });

        document.getElementById("finalDrop").textContent = Math.floor(finalRate);
    };
});