// ==UserScript==
// @name functional market for dh3
// @namespace http://tampermonkey.net/
// @version 1.0
// @description lol4
// @author shtos
// @match dh3.diamondhunt.co
// @grant none
// ==/UserScript==
(function() {
'use strict';
// setup on login
const oldPopulate = window.populateMarketTable
var marketSettings = handleStorage('load')
marketSettings.items = []
marketSettings.categories = {}
marketSettings.normalSearchActive = false
marketSettings.presetActive = false
marketSettings.customPresets.forEach((preset)=>preset.active = false)
handleStorage(0, marketSettings)
const heatPerLog = {logs: 1, oakLogs: 2, willowLogs: 3, bambooLogs: 4, mapleLogs: 5, lavaLogs: 6, pineLogs: 7, stardustLogs: 8}
const BONES = {bones: 1, ashes: 2, iceBones: 3}
// wrapper around old populateMarketTable function
window.populateMarketTable = function(){
oldPopulate()
createElements()
calculatePrice()
checkIfCheapest()
filterItems()
}
// resizing and adding item count to tradables dialogue
document.querySelectorAll('[id*=market-slot-] > div').forEach((slot) => {
slot.firstElementChild.onclick = () => {
addItemSlotButton(slot.parentElement.id.split('-')[3]);
nicerDialogue();
};
});
function nicerDialogue() {
document.querySelector('#dialogue-tradables').style.maxWidth = '76%';
document.querySelector('#dialogue-tradables').style.marginTop = '150px';
document.querySelector('#dialogue-tradables').style.marginLeft = '-22%';
Array.from(document.querySelector('#dialogue-tradables-section').children).forEach((section) => {
section.style.padding = '5px';
section.style.margin = '3px';
Array.from(section.children).forEach((subsection) => {
subsection.style.position = 'relative';
let img = subsection.firstElementChild.src;
let item = img.substring(img.indexOf('images/') + 7, img.indexOf('.png'));
let span = document.createElement('span');
span.textContent = window[`var_${item}`] || 0;
span.style = `font-size: 10pt;color: white; position: absolute; left: 0px; bottom: 0px;text-shadow:-1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;`;
subsection.appendChild(span);
});
});
}
// creating buttons in market tab
function addMarketButtons(){
// checking if global_global_TradablesData has any data in it
if (window.global_TradablesData.length > 0){
let categories = new Set(window.global_TradablesData.map(item => item.category))
categories.forEach((category, index) => {
let picture
// filtering items per category set by smitty
window.global_TradablesData.filter(item => { return item.category === category }).forEach((filtered, i) => {
if (typeof marketSettings.categories[category] === 'undefined'){
marketSettings.categories[category] = {
items: [],
active: false
}
}
marketSettings.categories[category].items.push(filtered.itemName.replace(/([A-Z])/g, ' $1').trim().toLowerCase())
// grabbing first item for preset image
if (i === 0){ picture = filtered.itemName }
})
let button = document.createElement('button')
button.style.background = '#393e46'
button.style.border = '1px solid #eeeeee'
button.style.marginLeft = '1px'
button.style.marginBottom = '1px'
if (category === 'misc'){
marketSettings.categories[category].items[2] = 'stardust x 1000'
}
button.id = 'market-category-' + category
button.onclick = () => {
if (!marketSettings.normalSearchActive){
if (!marketSettings.items.includes(marketSettings.categories[category].items[0])){
handleFilter(button, marketSettings.categories[category].items, 'add')
}else{
handleFilter(button, marketSettings.categories[category].items, 'remove')
}
marketSettings.categories[category].active = !marketSettings.categories[category].active
if (marketSettings.items.length !== 0){
marketSettings.presetActive = true
}else{
marketSettings.presetActive = false
}
handleStorage(0, marketSettings)
filterItems()
}
}
button.innerHTML = `<img src="images/${picture}.png" style="height:32px;width:32px"/>`
document.getElementById('market-sort-buttons-wrapper').appendChild(button)
})
window.global_TradablesData.forEach((data, index) => {
// making exception for stardust pack, because theyre named differently for some reason :shrug:
let name
if (data.itemName == 'stardust1000'){
name = 'stardust x 1000'
}else{
name = data.itemName.replace(/([A-Z])/g, ' $1').trim().toLowerCase()
}
let button = document.createElement('button')
button.id = 'market-button-' + camelize(name)
button.style.background = '#393e46'
button.style.border = '1px solid #eeeeee'
button.style.marginLeft = '1px'
button.style.marginBottom = '1px'
button.oncontextmenu = (event) => { event.preventDefault(); window.addItemSlotButtonSelectItemChangeLimits(index) }
button.onclick = ()=>{
// checking if array already has selected item
let check = marketSettings.items.filter(item => item === name)
// adding selecting item to filter list
if (!marketSettings.presetActive){
if (check.length === 0){
handleFilter(button, name, 'add')
}else{
handleFilter(button, name, 'remove')
}
if (marketSettings.items.length === 0){
marketSettings.normalSearchActive = false
}else{
marketSettings.normalSearchActive = true
}
handleStorage(0, marketSettings)
filterItems()
}
}
// adding image of item to a button
button.innerHTML = `<img src="images/${data.itemName}.png" style="height:32px;width:32px"/>`
document.getElementById('market-buttons-xd').appendChild(button)
})
}else{
setTimeout(addMarketButtons, 500)
}
}
// filtering items 'logic'
function filterItems(){
// reseting display of items
document.querySelectorAll('#market-table > tbody')[0].childNodes.forEach(listing => {
listing.style.display = 'none'})
// filtering items to only show selected ones
if (marketSettings.items.length !== 0){
marketSettings.items.forEach(item => {
Array.from(document.querySelectorAll('#market-table > tbody')[0].childNodes).filter(listing => {
return listing.childNodes[0].childNodes[0].textContent.toLowerCase() === item
}).forEach((filtered, index)=>{
// showing only x cheapest listings
index < marketSettings.numberOfItems ? filtered.style.display = '' : null
})
})
}else{
// if there is no items in filterList, show everything
document.querySelectorAll('#market-table > tbody')[0].childNodes.forEach(listing =>{
listing.style.display = ''})
}
checkIfCheapest()
}
function handleFilter(button, stuff, action) {
if (action == 'add') {
if (marketSettings.multiFilter) {
if (Array.isArray(stuff)) {
marketSettings.items = [ ...marketSettings.items, ...stuff ];
} else {
marketSettings.items.push(stuff);
}
} else {
if (Array.isArray(stuff)) {
marketSettings.items = [ ...stuff ];
} else {
marketSettings.items = [];
marketSettings.items[0] = stuff;
}
}
} else if (action == 'remove') {
if (Array.isArray(stuff)) {
let temp = marketSettings.items.filter((item) => !stuff.includes(item) )
marketSettings.items = [...temp]
} else {
marketSettings.items = marketSettings.items.filter((item) => item !== stuff )
}
}
colorButtons(button);
}
function colorButtons(button) {
if (button == 'reset'){
document.querySelectorAll('#market-preset-wrapper > div').forEach((div,index) => {
div.querySelectorAll('button')[1].style.background = '#E16B62'
marketSettings.customPresets[index].active = false
})
document.querySelectorAll('#market-table > tbody')[0].childNodes.forEach(listing => {
listing.style.display = ''})
document.querySelectorAll('#market-sort-buttons-wrapper > button').forEach((button, index)=>{ button.style.background = '#393e46' })
document.querySelectorAll('#market-buttons-xd > button').forEach((button, index)=>{index > 0 ? button.style.background = '#393e46' : null})
for (let category in marketSettings.categories){
marketSettings.categories[category].active = false
}
}else if (button.id.includes('category')) {
let category = button.id.split('-')[2];
if (!marketSettings.categories[category].active) {
color(button, 'category', category, '#eeeeee');
} else {
color(button, 'category', category, '#393e46');
}
}else if (button.id.includes('custom')){
let index = button.id.split('-')[2]
if (!marketSettings.customPresets[index].active){
color(button, 'custom', index, '#eeeeee', '#83EA6C');
}else{
color(button, 'custom', index, '#393e46', '#E16B62');
}
}
document.querySelectorAll('#market-buttons-xd > button').forEach((button, index)=>{index > 0 ? button.style.background = '#393e46' : null})
marketSettings.items.forEach((name)=>{
document.querySelector('#market-button-' + camelize(name)).style.background = '#eeeeee'
})
}
function color(button, type, thing, color, secondaryColor) {
if (!marketSettings.multiFilter){
document.querySelectorAll('#market-preset-wrapper > div').forEach((div,index) => {
div.querySelectorAll('button')[1].style.background = '#E16B62'
if (div.querySelectorAll('button')[1].id != button.id){
marketSettings.customPresets[index].active = false
}
})
document.querySelectorAll('#market-sort-buttons-wrapper > button').forEach((button, index)=>{ button.style.background = '#393e46' })
for (let category in marketSettings.categories){
if (!button.id.includes(category)){
marketSettings.categories[category].active = false
}
}
}
if (type == 'category') {
button.style.background = color;
}else if (type == 'custom' ){
button.style.background = secondaryColor;
}
}
// creating main cointainers for items
function createElements(){
// checking if wrapper element doesnt exist)
if (!$('#market-buttons-bigger-wrapper').length){
$('#market-buttons-section').after(`<div id="market-buttons-bigger-wrapper" style="display: flex; align-items: center; margin-top: 25px;flex-direction: row; justify-content: center;"></div>`)
$('#navigation-right-market').append(`<div id="scroll-market-button" style="position:fixed; top: 90vh; left: 1.3vw;background:#c99024; border:1px solid black; border-radius:50%;cursor:pointer;"><img src="https://img.icons8.com/windows/32/000000/home.png"></div>`)
$('#market-buttons-bigger-wrapper').append(`<div id="market-preset-wrapper" style="margin-right: 20px">
<div id="market-preset-0" style="display: flex; flex-direction: row">
<button>Save</button>
<input style="width: 100px">
<button style="background: #E16B62">Set</button>
</div>
<div id="market-preset-1" style="display: flex; flex-direction: row">
<button>Save</button>
<input style="width: 100px">
<button style="background: #E16B62">Set</button>
</div><div id="market-preset-2" style="display: flex; flex-direction: row">
<button>Save</button>
<input style="width: 100px">
<button style="background: #E16B62">Set</button>
</div><div id="market-preset-3" style="display: flex; flex-direction: row">
<button>Save</button>
<input style="width: 100px">
<button style="background: #E16B62">Set</button>
</div><div id="market-preset-4" style="display: flex; flex-direction: row">
<button>Save</button>
<input style="width: 100px">
<button style="background: #E16B62">Set</button>
</div></div>`)
$('#market-buttons-bigger-wrapper').append(`<div id="market-buttons-wrapper" style="display: flex; align-items: center; margin-top: 25px;flex-direction: column;"></div>`)
$('#market-buttons-wrapper').append(`<div id="market-buttons-settings" style="background: #222831; border-radius: 3px; margin-bottom: 3px "></div>`)
$('#market-buttons-settings').append(`<span style="margin-right: 5px">Number of items to show: </span><input id="market-buttons-amount" style="width: 25px; margin-right: 5px" min="1" max="99">
<span style="margin-right: 5px">Filter multiple items: </span><input id="filter-check" type="checkbox">
<span id="min-check-span" style="margin-right: 5px">Show only listings priced at min: </span><input id="min-check" type="checkbox">
`)
$('#market-buttons-bigger-wrapper').append('<div id="market-sort-buttons-wrapper" style="width: 210px; display: flex; align-items: center; margin-top: 25px;flex-direction: row; flex-wrap:wrap;"></div>')
document.querySelectorAll('#market-preset-wrapper > div').forEach((div,index)=>{
let saveButton = div.children[0]
let input = div.children[1]
let setButton = div.children[2]
saveButton.onclick = () =>{
marketSettings.customPresets[index].name = input.value
marketSettings.customPresets[index].items = [...marketSettings.items]
handleStorage(0, marketSettings)
}
input.value = marketSettings.customPresets[index].name
setButton.id = 'set-custom-' + index
setButton.onclick = () =>{
if (!marketSettings.presetActive){
if (!marketSettings.customPresets[index].active){
handleFilter(setButton, marketSettings.customPresets[index].items, 'add')
}else{
handleFilter(setButton, marketSettings.customPresets[index].items, 'remove')
}
marketSettings.customPresets[index].active = !marketSettings.customPresets[index].active
if (marketSettings.items.length === 0){
marketSettings.normalSearchActive = false
}else{
marketSettings.normalSearchActive = true
}
handleStorage(0, marketSettings)
filterItems()
}
}
})
document.getElementById('scroll-market-button').onclick = () => {window.scrollTo({
top: 500,
left: 0,
behavior: 'smooth'
})}
document.getElementById('market-buttons-amount').value = marketSettings.numberOfItems
document.getElementById('market-buttons-amount').onkeyup = (event) => {
marketSettings.numberOfItems = event.target.value
filterItems()
handleStorage(0, marketSettings)
}
document.getElementById('filter-check').checked = marketSettings.multiFilter ? true : false
document.getElementById('filter-check').onclick = (event) => {
if(event.target.checked){
marketSettings.multiFilter = true
handleStorage(0, marketSettings)
}else{
marketSettings.multiFilter = false
if (marketSettings.items.length > 0){
marketSettings.items = []
filterItems()
colorButtons('reset')
}
handleStorage(0, marketSettings)
}
}
if (window.var_username == 'shtos' || window.var_username == 'pickle rick'){
document.getElementById('min-check').style.display = ''
document.getElementById('min-check-span').style.display = ''
}else{
document.getElementById('min-check').style.display = 'none'
document.getElementById('min-check-span').style.display = 'none'
}
document.getElementById('min-check').checked = marketSettings.hideNonMin ? true : false
document.getElementById('min-check').onclick = (event) => {
if(event.target.checked){
marketSettings.hideNonMin = true
filterItems()
checkIfCheapest()
handleStorage(0, marketSettings)
}else{
marketSettings.hideNonMin = false
filterItems()
checkIfCheapest()
handleStorage(0, marketSettings)
}
}
$('#market-buttons-wrapper').append(`<div id="market-buttons-xd" style="width: 45vw; display: flex; justify-center:center; flex-wrap: wrap"></div>`)
let button = document.createElement('button')
button.innerHTML = `<img src="/images/back.png" style="height:32px;width:32px"/>`
button.style.border = '1px solid #eeeeee'
button.style.marginLeft = '1px'
button.style.marginBottom = '1px'
// adding clear button
button.onclick = ()=> {
marketSettings.items = []
marketSettings.presetActive = false
marketSettings.normalSearchActive = false
handleStorage(0, marketSettings)
colorButtons('reset')
document.getElementById('min-check').checked = false
}
$('#market-buttons-xd').append(button)
}
// checking if market buttons exist
if (document.querySelectorAll('#market-buttons-xd > button').length < 2){
addMarketButtons()
}
}
function calculatePrice(){
Array.from(document.querySelectorAll('#market-table > tbody')[0].childNodes).filter(listing => {
let name = camelize(listing.childNodes[0].childNodes[0].textContent)
let price = parseInt(listing.childNodes[3].textContent.replace(/,/g, ''))
let category = listing.childNodes[4].textContent.toLowerCase()
if (category === 'bonemeal'){
let i = document.createElement('i')
i.style = 'color: gray; margin-left: 4px'
i.textContent += (price / BONES[name]).toFixed(2)
listing.childNodes[3].appendChild(i)
}
if (category === 'raw fish'){
let i = document.createElement('i')
i.style = 'color: gray; margin-left: 4px'
i.textContent += (price / window.global_foodMap.find(e=>e.rawFoodName === name).energy).toFixed(2)
listing.childNodes[3].appendChild(i)
}
if (category === 'cooked fish' || category === 'food'){
let i = document.createElement('i')
i.style = 'color: gray; margin-left: 4px'
i.textContent += (price / window.global_foodMap.find(e=>e.cookedFoodName === name).energy).toFixed(2)
listing.childNodes[3].appendChild(i)
}
if (category === 'logs'){
let i = document.createElement('i')
i.style = 'color: gray; margin-left: 4px'
i.textContent += (price / heatPerLog[name]).toFixed(2)
listing.childNodes[3].appendChild(i)
}
if (category === 'armour'){
let i = document.createElement('i')
i.style = 'color: gray; margin-left: 4px'
if (name == 'snakeskin'){
i.textContent += calcSushi(name, price)
}else if (name == 'batSkin'){
i.textContent += calcSushi(name, price)
}
listing.childNodes[3].appendChild(i)
}
if (category === 'seeds'){
let i = document.createElement('i')
i.style = 'color: gray; margin-left: 4px'
let research = window.var_researcherFarming > 2 ? 1.05 : 1
if (name == 'redMushroomSeeds'){
//15*1.05
i.textContent += (price / (15 * research)).toFixed(2)
}
else if(name.includes('Leaf')){
//3.5*1.05 fixed2
i.textContent += (price / (3.5 * research)).toFixed(2)
}
listing.childNodes[3].appendChild(i)
}
})
}
function calcSushi(name, price){
let oven = Object.keys(window).filter(oven => oven.includes('Oven') && oven.includes('var') && !oven.includes('Total') && !oven.includes('Bought')).filter(oven => window[oven] == 1)[0]
typeof oven === 'undefined' ? oven = 'bronzeOven' : oven = oven.substring(4)
let successRate = {bronzeOven: 0.5, ironOven: 0.6, silverOven: 0.7, goldOven: 0.8, promethiumOven: 0.9}
if (window.var_researcherCooking > 1){
successRate[oven] += (1 - successRate[oven])*0.25
}
if (window.var_researcherCooking > 2){
successRate[oven] += 0.0375
}
successRate[oven] = successRate[oven].toFixed(4)
let ratio
switch (name){
case 'snakeskin':
ratio = 25
break
case 'batSkin':
ratio = 75
break
}
return (price / ratio * parseFloat(successRate[oven])).toFixed(2)
}
function checkIfCheapest(i, element, value){
if (window.global_TradablesData.length > 0){
document.querySelectorAll('#market-table > tbody')[0].childNodes.forEach(listing =>{
let name = listing.childNodes[0].childNodes[0].textContent.toLowerCase() == 'stardust x 1000' ? 'stardust1000' : camelize(listing.childNodes[0].childNodes[0].textContent)
let price = parseInt(listing.childNodes[3].childNodes[0].textContent.replace(/,/g, ''))
if (name !== 'stardust'){
if (price == window.global_TradablesData.find(e=>e.itemName===name).lowerLimit){
listing.style.background = 'rgba(63, 191, 63, 0.5)'
}else if(marketSettings.hideNonMin){
listing.style.display = 'none'
}
}else if (marketSettings.hideNonMin && name == 'stardust'){
listing.style.display = 'none'
}
})
}else{
setTimeout(checkIfCheapest, 1000)
}
}
function camelize(str) {
return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());
}
function decamelize(str, separator){
separator = typeof separator === 'undefined' ? ' ' : separator;
return str
.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2')
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2')
.toLowerCase()
.replace(/^\w/, c => c.toLowerCase());
}
function handleStorage(key, config){
if (key === 'load'){
return localStorage.getItem('market-storage-settings-new') === null ? {customPresets: [{name: '', items: [], active: false},{name: '', items: [], active: false},{name: '', items: [], active: false},{name: '', items: [], active: false},{name: '', items: [], active: false},], presets: [], presetActive: false, normalSearchActive: false, items: [], numberOfItems: 20, multiFilter: false, hideNonMin: false} : JSON.parse(localStorage.getItem('market-storage-settings-new'))
}else{
return localStorage.setItem('market-storage-settings-new', JSON.stringify(config))
}
}
})();