// ==UserScript==
// @name Manarion
// @namespace http://tampermonkey.net/
// @version 2029-04-25
// @description Display calculated values
// @author Rook
// @match https://manarion.com
// @icon https://www.google.com/s2/favicons?sz=64&domain=manarion.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
const debug = false;
const actionsPerMin = 20;//Every 3 seconds
const timeFormatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: true
});
const grid = document.querySelector('#root > div > div.flex > div.border-primary > div.grid');
let manaDustGain = undefined;
let manaDustForSpellpower = undefined;
let manaDustForWard = undefined;
addEventListener("load", setInterval(main, 3000))
function main() {
timeToLevel();
research();
timeToQuest();
function timeToQuest(){
const questElement = document.querySelector("#root > div > div.flex > div.border-primary > div.grid.grid-cols-4 > div:nth-child(1) > div > p")
const questText = questElement.textContent;//Defeat 21/333 enemies.
const questNums = questText.match(/\d+/g);
const questProgress = questNums[0];
const questGoal = questNums[1];
const minsToQuest = Math.round((questGoal - questProgress) / actionsPerMin, 1);
if(minsToQuest<=0){
document.title = "Manarion QUEST";
}
etaUntil("Quest", minsToQuest);
}
function timeToLevel() {
const xpGainTextElement = document.querySelector('#root > div > div.flex > main > div > div:nth-child(3) > p.text-green-400');
if(xpGainTextElement){
if(debug){
console.log("On the Battle Page");
}
manaDustGain = detectFloat(document.querySelector('#root > div > div.flex > main > div > div:nth-child(4) > ul > li > span:nth-child(1)').title);
const xpGainText = xpGainTextElement.textContent;
const xpGain = detectInt(xpGainText);
const xp = parseInt(document.querySelector('#root > div > div.flex > div.border-primary > div.grid > div:nth-child(4) > span.break-all > span:nth-child(1)').title.replace(/,/g, ""));
const xpGoal = parseInt(document.querySelector('#root > div > div.flex > div.border-primary > div.grid > div:nth-child(4) > span.break-all > span:nth-child(2)').title.replace(/,/g, ""));
const xpDiff = xpGoal - xp;
const minsToLevel = Math.round(xpDiff / (actionsPerMin * xpGain), 1);
if(debug){
console.log(xpGainText);
console.log("XpGain: " + xpGain);
console.log("Current XP: " + xp);
console.log("XP Goal: " + xpGoal);
console.log("XP Diff: " + xpDiff);
console.log("MinsToLevel: " + minsToLevel);
console.log("ManaDustGain: " + manaDustGain);
}
perHour("XP",xpGain);
perHour("MD",manaDustGain);
etaUntil("Level", minsToLevel);
}
}
function research(){
const onResearchPage = document.querySelector('div.space-y-5');
if(onResearchPage){
if(debug){
console.log("On the Research page");
}
const manaDust = parseInt(document.querySelector("#root > div > div.flex > div.border-primary > div.grid > div:nth-child(6) > span:nth-child(2) > span").title.replace(/,/g, ""));
const manaDustForSpellpowerElement = document.querySelector("div.space-y-5 > div:nth-child(1) > div:nth-child(2) > div:nth-child(2) > div:nth-child(1) > div:nth-child(4) > span:nth-child(1)");
if(manaDustForSpellpowerElement){
if(debug){
console.log("Spellpower");
}
manaDustForSpellpower = parseInt(manaDustForSpellpowerElement.title.replace(/,/g, ""));
manaDustForSpellpower -= manaDust;
const minsToSpellpower = Math.round(manaDustForSpellpower / (actionsPerMin * manaDustGain), 1);
etaUntil("Spellpower", minsToSpellpower);
}
const manaDustForWardElement = document.querySelector("div.space-y-5 > div:nth-child(1) > div:nth-child(2) > div:nth-child(2) > div:nth-child(2) > div:nth-child(4) > span:nth-child(1)");
if(manaDustForWardElement){
if(debug){
console.log("Ward");
}
manaDustForWard = parseInt(manaDustForWardElement.title.replace(/,/g, ""));
manaDustForWard -= manaDust;
const minsToWard = Math.round(manaDustForWard / (actionsPerMin * manaDustGain),1);
etaUntil("Ward", minsToWard);
}
}
}
function perHour(name, value){
addGridRow(grid, name + "/Hour", formatNumberWithCommas(value * actionsPerMin * 60));
}
function etaUntil(event, minutes){
if(minutes > 0){
addGridRow(grid,"Next " + event,"(" + etaPhrase(minutes) + ") " + timeStamp(timePlusMinutes(minutes)));
}
else
{
addGridRow(grid,"Next " + event,"Ready");
}
}
function etaPhrase(minutes){
let min = minutes;
let days = Math.floor(min / (60 * 24));
min = min - (days * (60 * 24));
let hours = Math.floor((min / 60));
min = min - (hours * 60);
let result = "";
if (days>0)
{
result += days + "d:";
}
if (hours>0)
{
result += hours + "h:";
}
if (min>0)
{
result += min + "m";
}
return result;
}
function timePlusMinutes(minutesToAdd) {
let now = new Date();
let currentMinutes = now.getMinutes();
let newTime = now;
newTime.setMinutes(currentMinutes + minutesToAdd);
return newTime;
}
function timeStamp(time){
return timeFormatter.format(time);
}
function formatNumberWithCommas(number) {
return number.toLocaleString('en-US');
}
function detectInt(str) {
const regex = /\d+/;
const match = str.replace(/,/g, "").match(regex);
return match ? parseInt(match[0], 10) : null;
}
function detectFloat(str) {
const regex = /\d+/;
const match = str.replace(/,/g, "").match(regex);
return match ? parseFloat(match[0]) : null;
}
function addGridRow(grid, label, value) {
const oldDiv = document.getElementById(label);
const spanId = label.toLowerCase().replace(" ", "-");
if(oldDiv){
//If it already exists, just update the existing content
const span = document.getElementById(spanId);
span.textContent = value;
span.title = value;
return;
}
const newDiv = document.createElement('div');
newDiv.setAttribute('id', label);
newDiv.classList.add("col-span-2", "flex", "justify-between");
const labelSpan = document.createElement('span');
labelSpan.textContent = label;
const valueSpan = document.createElement('span');
valueSpan.setAttribute('id', spanId);
valueSpan.textContent = value;
valueSpan.title = value;
const wrapper = document.createElement('span');
wrapper.appendChild(valueSpan);
newDiv.appendChild(labelSpan);
newDiv.appendChild(wrapper);
grid.appendChild(newDiv);
}
}
})();