// ==UserScript==
// @name hwmSetsMaster
// @author Tamozhnya1
// @namespace Tamozhnya1
// @description Меню наборов армии, навыков и оружия. Смена фракции.
// @version 12.4
// @include *heroeswm.ru/*
// @include *lordswm.com/*
// @exclude */rightcol.php*
// @exclude */ch_box.php*
// @exclude */chat*
// @exclude */ticker.html*
// @exclude */frames*
// @exclude */brd.php*
// @require https://update.greasyfork.org/scripts/490927/1360667/Tamozhnya1Lib.js
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM.xmlHttpRequest
// @license MIT
// ==/UserScript==
if(!PlayerId) {
return;
}
const Strings = {
"ru": {
Army: "Армия",
Save: "Сохранить",
Add: "Добавить",
AddCurrent: "Добавить текущий",
SetName: "Наименование набора",
Delete: "Удалить",
Talents: "Навыки",
Inventory: "Инвентарь",
RemoveAll: "Снять все",
EnterJpg: "enter0.jpg",
SignInTitle: "Войти",
Castle: "Замок",
Task: "Задание",
Apply: "Применить",
AvailablePoints: "Свободных очков",
AvailableTalentPoints: "Свободных очков от навыка",
IncreaseManyPointsTooltip: "Введите число от ${minValue} до ${maxValue}. Нажмите Tab."
},
"en": {
Army: "Army",
Save: "Save",
Add: "Add",
AddCurrent: "Add current",
SetName: "Set name",
Delete: "Delete",
Talents: "Talents",
Inventory: "Inventory",
RemoveAll: "Un-equip all",
EnterJpg: "enter0_eng.jpg",
SignInTitle: "Sign in",
Castle: "Castle",
Task: "Task",
Apply: "Apply",
AvailablePoints: "Available points",
AvailableTalentPoints: "Available talent points",
IncreaseManyPointsTooltip: "Enter number from ${minValue} to ${maxValue}. Press Tab."
}
};
const LocalizedString = Strings[lang];
let Fraction;
getFraction();
//const homeArtsPanelSelector = doc => isNewPersonPage ? doc.querySelector("div#inv_doll_stats") : getParent(doc.querySelector("div.arts_info.shop_art_info"), "table");
const homeArtsPanelSelector = doc => isNewPersonPage ? doc.querySelector("div#inv_doll_stats") : doc.querySelector("body > center table.wb > tbody > tr:nth-child(3) > td > table:nth-child(2)");
const homeStatsPanelSelector = doc => isNewPersonPage ? doc.getElementById("home_css_stats_wrap_div") : getParent(doc.querySelector("img[src*='attr_attack']"), "table", 2);
const homeArmyPanelSelector = doc => isNewPersonPage ? doc.querySelector("div.home_pers_army") : doc.querySelector("center > div > div.cre_creature72").parentNode;
const playerInfoArtsPanelSelector = doc => getParent(doc.querySelector("div[class^='slot']"), "div");
const playerInfoStatsPanelSelector = doc => getParent(doc.querySelector("img[src*='attr_attack']"), "table");
const playerInfoArmyPanelSelector = doc => doc.querySelector("center > div > div.cre_creature72").parentNode;
const playerInfoPerksPanelSelector = doc => getParent(doc.querySelector("a[href^='showperkinfo.php']"), "table", 2);
const mapHuntButtonsPanelSelector = doc => doc.querySelector("div#neut_right_block div.map_buttons_container");
const mapHuntButtons2PanelSelector = doc => doc.querySelector("div#neut_right_block2 div.map_buttons_container");
const mapMercenaryTaskPanelSelector = doc => getParent(doc.querySelector("div#map_right_block_inside > table.wbwhite.rounded_table.map_table_margin center a[href='mercenary_guild.php']"), "center");
const inventoryStatsPanelSelector = doc => doc.querySelector("div.inventory_stats");
const resourcesPath = `${location.protocol}//${location.host.replace("www", "dcdn")}`;
/************************************************************************************************************/
const weaponSetsPreferences = {
menuTitle: LocalizedString.Inventory,
menuImage: `${resourcesPath}/i/combat/btn_inventory.png?v=7`,
setReferencePage: "inventory.php",
sets: new Array(),
menuItems: {},
currentMenuItem: undefined,
initSetsApplyAction: function() {
this.sets.length = 0;
this.sets.push({ number: 0, name: LocalizedString.RemoveAll, method: "GET", url: "/inventory.php?all_off=100" });
const weaponSets = JSON.parse(getPlayerValue("WeaponSets", "{}"));
for(const setNumber in weaponSets) {
this.sets.push({ number: setNumber, name: weaponSets[setNumber], method: "GET", url: `/inventory.php?all_on=${setNumber}` });
}
},
name: "WeaponSet",
getCurrentSetName: function() { return "WeaponSet"; },
onPageLoad: function() {
if(/inventory.php/.test(location.href)) {
const undressDiv = document.querySelector("div[id ='undress_all_div']");
addSetChangerListener(undressDiv, this, 0);
const setDivs = document.querySelectorAll("div[set_div_id]"); // Если setDivs.length = 0, то ничего не делаем - мы в заявке на бой
if(setDivs.length > 0) {
const weaponSets = {};
for(const setDiv of setDivs) {
const setNumber = setDiv.getAttribute("set_div_id");
if(setDiv.hasAttribute("onclick")) {
weaponSets[setNumber] = setDiv.innerText;
addSetChangerListener(setDiv, this, setNumber);
}
}
setPlayerValue("WeaponSets", JSON.stringify(weaponSets));
}
}
this.findSetChangersAndAddListener();
},
findSetChangersAndAddListener: function() {
let setRefs = document.querySelectorAll("a[href^='inventory.php?all_off=100']");
for(const setRef of setRefs) {
addSetChangerListener(setRef, this, 0);
}
setRefs = document.querySelectorAll("a[href*='inventory.php?all_on=']");
for(const weaponSetReference of setRefs) {
let setNumber = weaponSetReference.getAttribute("href").split("all_on=")[1];
addSetChangerListener(weaponSetReference, this, setNumber);
}
}
};
/***********************************************************************************************************/
const skillSetsPreferences = {
menuTitle: LocalizedString.Talents,
menuImage: `${resourcesPath}/i/combat/btn_skills_v3.png?v=7`,
setReferencePage: "skillwheel.php",
sets: new Array(),
menuItems: {},
currentMenuItem: undefined,
onPageLoad: function() {
const setRefs = document.querySelectorAll("a[href^='skillwheel.php?setuserperk']"); // skillwheel.php?setuserperk=1&prace=4&buildid=5 // skillwheel.php?rand=1&setstats=1¶m0=20¶m1=8¶m2=0¶m3=2
const pageSets = {};
for(const setRef of setRefs) {
pageSets[setRef.innerHTML] = getUrlParamValue(setRef.href, "buildid");
addSetChangerListener(setRef, this, parseInt(getUrlParamValue(setRef.href, "buildid")));
}
setPlayerFractionValue("SkillSets", JSON.stringify(pageSets));
},
initSetsApplyAction: function () {
const skillSets = JSON.parse(getPlayerFractionValue("SkillSets", "{}"));
this.sets = Object.keys(skillSets).map(x => { return { number: parseInt(skillSets[x]), name: x, method: "GET", url: `/skillwheel.php?setuserperk=1&prace=${Fraction}&buildid=${skillSets[x]}` }; });
},
name: "SkillSet",
getCurrentSetName: function() { return getFractionKey("SkillSet"); },
};
/************************************************************************************************************/
const armySetsPreferences = {
menuTitle: LocalizedString.Army,
menuImage: `${resourcesPath}/i/castle_im/btn_recruit.png`,
setReferencePage: "army.php",
sets: new Array(),
menuItems: {},
currentMenuItem: undefined,
setsTable: null,
name: "ArmySet",
getCurrentSetName: function() { return getFractionKey("ArmySet"); },
initSetsApplyAction: function () {
const armySetsData = JSON.parse(getPlayerFractionValue("ArmySets", "{}"));
const armySets = Object.keys(armySetsData).map(x => { const data = armySetsData[x].split("|"); return { Id: x, Name: data[0], Army: data.slice(1).map(y => Number(y)) } });
this.sets = armySets.map(x => { return { number: parseInt(x.Id), name: x.Name, title: x.Army.join("+"), method: "POST", url: "/army_apply.php", data: "set_id=7&" + x.Army.map((x, i) => `countv${i + 1}=${x}`).join("&") }; });
if(/\/army.php/.test(location.href)) {
this.drawSetsTable(armySets);
}
},
drawSetsTable: function(armySets) {
const isInit = this.setsTable ? false : true;
let container;
if(isInit) {
const hwm_for_zoom = document.getElementById("hwm_for_zoom") || document.getElementById("hwm_no_zoom");
container = document.body;
if(!isMobileInterface) {
container = addElement("center", null, hwm_for_zoom);
}
this.setsTable = addElement("table", { class: "smithTable", style: `${isMobileInterface ? "margin-left: px;" : ""}` }, container);
} else {
this.setsTable.innerHTML = "";
container = this.setsTable.parentNode;
}
const cellWidths = [100, 60, 60, 60, 60, 60, 60, 60, 10, 10];
for(const cellWidth of cellWidths) {
this.setsTable.innerHTML += `<col style="width: ${cellWidth}px;" />`;
}
this.drawTableHeader();
for(const armySet of armySets) {
this.drawSetRow(armySet);
}
if(isInit) {
const saveButton = addElement("input", { type: "button", value: LocalizedString.Save, class: "button-62", style: isMobileInterface ? "margin: 0 0 0 50px;" : "" }, container);
saveButton.addEventListener("click", this.saveSets);
const addCurrentButton = addElement("input", { type: "button", value: LocalizedString.AddCurrent, class: "button-62" }, container);
addCurrentButton.addEventListener("click", function() { armySetsPreferences.drawSetRow(); });
}
},
drawTableHeader: function () {
if(!this.setsTable) {
return;
}
const units = win.obj;
//console.log(units)
const tr = addElement("tr", null, this.setsTable);
addElement("th", { innerHTML: LocalizedString.SetName.replace(/ /g, "<br>").replace(/-/g, "-<br>") }, tr);
for(let i = 1; i <= 7; i++) {
addElement("th", { innerHTML: (units[i]?.name || "").replace(/ /g, "<br>").replace(/-/g, "-<br>"), onClick: `ChangeSlider(event, ${i}, 0);` }, tr);
}
addElement("th", { style: "width: 30px;" }, tr);
addElement("th", { style: "width: 30px;" }, tr);
},
drawSetRow: function(armySet) {
const isNew = armySet ? false : true;
const units = win.obj;
//console.log(`armySet: ${armySet}, units: ${units}`);
//console.log(units.slice(1));
armySet = armySet || { Id: (new Date()).getTime(), Name: "", Army: [units[1], units[2], units[3], units[4], units[5], units[6], units[7]].map(x => x?.nownumberd || 0) };
if(!this.setsTable) {
return;
}
const tr = addElement("tr", { setId: armySet.Id }, this.setsTable);
let td = addElement("td", {}, tr);
let input = addElement("input", { value: armySet.Name, onfocus: `this.select();`, style: "width: 100%;" }, td);
for(let i = 0; i < armySet.Army.length; i++) {
td = addElement("td", {}, tr);
input = addElement("input", { value: armySet.Army[i], onfocus: `ChangeSlider(event, ${i + 1}, 0); this.select();`, type: "number", style: "min-width: 47px; width: 100%; text-align: right;" }, td);
}
td = addElement("td", {}, tr);
let delButton = addElement("input", { type: "button", value: "x", class: "button-62", style: "width: 100%;", title: LocalizedString.Delete }, td);
delButton.addEventListener("click", this.deleteSet);
td = addElement("td", {}, tr);
if(!isNew) {
let applyButton = addElement("input", { type : "button", value : "v", class: "button-62", style: "width: 100%;", title : LocalizedString.Apply }, td);
applyButton.addEventListener("click", function() {
armySetsPreferences.saveSets();
const data = armySet.Army.reduce((x, y, i) => `${x}&countv${i + 1}=${y}`, "set_id=7");
//console.log(data);
applySet(null, armySetsPreferences, {
number: parseInt(armySet.Id),
name: armySet.Name,
title: armySet.Army.join("+"),
method: "POST", url: "/army_apply.php",
data: data
});
});
}
},
saveSets: function () {
const rows = Array.from(armySetsPreferences.setsTable.rows).slice(1);
const armySetsData = rows.reduce((t, x) => ({ ...t, [x.getAttribute("setId")]: Array.from(x.cells).slice(0, 8).map(y => y.firstChild.value).join("|") }), {});
setPlayerFractionValue("ArmySets", JSON.stringify(armySetsData));
},
deleteSet: function () {
const table = this.parentNode.parentNode.parentNode;
const row = this.parentNode.parentNode;
table.removeChild(row);
},
};
/************************************************************************************************************/
const fractionsPreferences = {
menuTitle: LocalizedString.Castle,
menuImage: `${resourcesPath}/i/castle_im/btn_fraction.png`,
setReferencePage: "castle.php",
sets: [],
menuItems: {},
currentMenuItem: undefined,
initSetsApplyAction: function() {
const fractions = JSON.parse(getPlayerValue("Fractions", "{}"));
this.sets = Object.keys(fractions).map(x => { return { number: fractions[x], name: x, method: "GET", url: `/castle.php?change_clr_to=${fractions[x]}&sign=${getPlayerValue("Sign")}` }; });
},
name: "Fraction",
getCurrentSetName: function() { return "Fraction"; },
onPageLoad: async function () {
await this.initCastlesList();
this.findSetChangersAndAddListener();
},
initCastlesList: async function () {
if(location.pathname == '/castle.php' || !getPlayerValue("Fractions")) {
const doc = location.pathname == '/castle.php' ? document : await getRequest("/castle.php");
const fractions = Array.from(doc.querySelectorAll("div.castle_faction_div_inside")).reduce((t, x) => ({...t, [x.getAttribute("hint")]: getUrlParamValue(x.firstChild.href, "show_castle_f") }), {});
setPlayerValue("Fractions", JSON.stringify(fractions));
const changeCastleRef = doc.querySelector("div.castle_yes_no_dialog a[href*='castle.php?change_clr_to']");
if(changeCastleRef) {
setPlayerValue("Sign", getUrlParamValue(changeCastleRef.href, "sign"));
}
}
},
findSetChangersAndAddListener: function() {
const setRefs = document.querySelectorAll("a[href*='castle.php?change_clr_to']");
for(const setRef of setRefs) {
addSetChangerListener(setRef, this, getUrlParamValue(setRef.href, "change_clr_to"));
}
},
setChanged: function(newSetNumber) {
Fraction = newSetNumber;
setPlayerValue("Fraction", Fraction);
createMenu();
}
};
/************************************************************************************************************/
const preferences = [weaponSetsPreferences, skillSetsPreferences, armySetsPreferences, fractionsPreferences];
const visibleMunuItems = [[], [], [], []];
main();
function main() {
if(isHeartOnPage && Fraction) {
addStyle(`
.button-62 {
background: linear-gradient(to bottom right, #E47B8E, #FF9A5A);
border: 0;
border-radius: 5px;
color: #FFFFFF;
cursor: pointer;
display: inline-block;
font-family: -apple-system,system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
font-size: 16px;
font-weight: 500;
outline: transparent;
padding: 0 5px;
text-align: center;
text-decoration: none;
transition: box-shadow .2s ease-in-out;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
white-space: nowrap;
}
.button-62:not([disabled]):focus {
box-shadow: 0 0 .25rem rgba(0, 0, 0, 0.5), -.125rem -.125rem 1rem rgba(239, 71, 101, 0.5), .125rem .125rem 1rem rgba(255, 154, 90, 0.5);
}
.button-62:not([disabled]):hover {
box-shadow: 0 0 .25rem rgba(0, 0, 0, 0.5), -.125rem -.125rem 1rem rgba(239, 71, 101, 0.5), .125rem .125rem 1rem rgba(255, 154, 90, 0.5);
}
.button-62:disabled,button[disabled] {
background: linear-gradient(177.9deg, rgb(58, 62, 88) 3.6%, rgb(119, 127, 148) 105.8%);
}
table.smithTable {
width: 100%;
background: BurlyWood;
border: 5px solid BurlyWood;
border-radius: 5px;
margin-top: 1px;
}
table.smithTable th {
border: 1px none #f5c137;
overflow: hidden;
text-align: center;
font-size: 11px;
}
table.smithTable td {
border: 1px none #f5c137;
overflow: hidden;
text-align: center;
}
table.smithTable tr:nth-child(odd) {
background: Wheat;
}
table.smithTable tr:nth-child(even) {
background: white;
}
.waiting {
cursor: wait;
}
.not-allowed {
cursor: not-allowed;
}
`);
update();
for(const preference of preferences) {
if(preference.onPageLoad) {
preference.onPageLoad();
}
}
createMenu();
window.addEventListener("resize", function() { createMenu(true); });
drowSkillChangers();
if(location.pathname == '/home.php' && isNewPersonPage) {
observe(document.querySelector("div#home_css_stats_wrap_div"), drowSkillChangers);
}
}
}
function update() {
const fractionNumbers = [1, 101, 2, 102, 3, 103, 4, 104, 5, 105, 205, 6, 106, 7, 107, 8, 108, 9, 10];
for(const fractionNumber of fractionNumbers) {
//deletePlayerFractionValue("SkillSets", fractionNumber);
const skillSetsOld = getValue(`SkillSets${PlayerId}Fraction${fractionNumber}`);
const skillSets = getPlayerFractionValue("SkillSets", undefined, fractionNumber);
// if(fractionNumber == 8) {
// console.log(`fractionNumber: ${fractionNumber}, skillSetsOld: ${skillSetsOld}, skillSets: ${skillSets}, CurrentSkillSet: ${getValue(`CurrentSkillSet${PlayerId}Fraction${fractionNumber}`)}`);
// }
if(skillSetsOld && !skillSets) {
setPlayerFractionValue("SkillSets", skillSetsOld, fractionNumber);
setPlayerFractionValue("SkillSet", getValue(`CurrentSkillSet${PlayerId}Fraction${fractionNumber}`), fractionNumber);
}
//deletePlayerFractionValue("ArmySets", fractionNumber);
const armySetsOld = getValue(`ArmySets${PlayerId}Fraction${fractionNumber}`);
const armySets = getPlayerFractionValue("ArmySets", undefined, fractionNumber);
// if(fractionNumber == 8) {
// console.log(`fractionNumber: ${fractionNumber}, armySetsOld: ${armySetsOld}, armySets: ${armySets}, ArmySet: ${getValue(`ArmySet${PlayerId}Fraction${fractionNumber}`)}`);
// }
if(armySetsOld && !armySets) {
setPlayerFractionValue("ArmySets", armySetsOld, fractionNumber);
setPlayerFractionValue("ArmySet", getValue(`ArmySet${PlayerId}Fraction${fractionNumber}`), fractionNumber);
}
// if(fractionNumber == 8) {
// console.log(`ArmySet: ${getPlayerFractionValue("ArmySet", undefined, fractionNumber)}`);
// }
}
}
function getTextWidth(text, font) {
const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas")); // re-use canvas object for better performance
const context = canvas.getContext("2d");
context.font = font;
const metrics = context.measureText(text);
return metrics.width;
}
function getCssStyle(element, prop) { return window.getComputedStyle(element, null).getPropertyValue(prop); }
function getCanvasFont(el = document.body) {
const fontWeight = getCssStyle(el, 'font-weight') || 'normal';
const fontSize = getCssStyle(el, 'font-size') || '16px';
const fontFamily = getCssStyle(el, 'font-family') || 'Times New Roman';
return `${fontWeight} ${fontSize} ${fontFamily}`;
}
function getOrCreateAndResizeDropdown(branchIndex, baseElement, style, toRight = false) {
const dropdownId = `${baseElement.id}Dropdown`;
let dropdown = document.getElementById(dropdownId);
if(!dropdown) {
dropdown = addElement("div", { id: dropdownId, style: `position: absolute; box-shadow: 3px 3px 5px #333;` + (style || "") }, document.body);
if(isMobileDevice) {
baseElement.addEventListener("click", function() {
dropdown.style.display = dropdown.style.display == "none" ? "block" : "none";
if(dropdown.style.display == "block") {
const dropdowns = document.querySelectorAll("div[id$=Dropdown]");
for(const dropdown of dropdowns) {
if(dropdown.id != dropdownId) {
dropdown.style.display = "none";
}
}
}
});
} else {
let hideTimer;
const dropdownTimeout = 100;
baseElement.addEventListener("mouseenter", function() { clearTimeout(hideTimer); if(dropdown.style.display == "none") { setTimeout(function() {
dropdown.style.display = "block";
baseElement.setAttribute("menuShown", "");
}, dropdownTimeout); } });
baseElement.addEventListener("mouseleave", function() { hideTimer = setTimeout(function() {
dropdown.style.display = "none";
baseElement.removeAttribute("menuShown");
}, dropdownTimeout); });
dropdown.addEventListener("mouseenter", function() {
clearTimeout(hideTimer);
//console.log(`mouseenter dropdownId: ${dropdownId}`);
});
dropdown.addEventListener("mouseleave", function() {
//console.log(`mouseleave dropdownId: ${dropdownId}`);
const menuShown = dropdown.querySelector("[menuShown]");
//console.log(menuShown)
if(menuShown) {
return;
}
hideTimer = setTimeout(function() {
dropdown.style.display = "none";
baseElement.removeAttribute("menuShown");
}, dropdownTimeout);
});
}
}
const baseElementRect = baseElement.getBoundingClientRect();
dropdown.style.top = `${baseElementRect.bottom + window.scrollY + 1}px`;
dropdown.style.left = `${toRight ? baseElementRect.right : baseElementRect.left}px`;
return dropdown;
}
function createMenu(isResize) {
const menuPanel = document.querySelector("div#hwm_header") || document.querySelector("#main_top_table") || document.querySelector("body > table");
if(!menuPanel) {
armySetsPreferences.initSetsApplyAction();
return;
}
const setsMenuPosition = getPlayerBool("ShowMenyAtRight") ? "right" : "left"; //const setsMenuPosition = isNewInterface && isMobileDevice || getPlayerBool("ShowMenyAtRight") ? "right" : "left";
const homeRef = menuPanel.querySelector("a[href='home.php']");
const framesRef = menuPanel.querySelector("a[href='frames.php']");
const menuAnchor = setsMenuPosition == "left" ? (isNewInterface ? homeRef.parentNode : getParent(homeRef, "td", 3)) : (isNewInterface ? framesRef.parentNode : getParent(framesRef, "td", 3));
if(!menuAnchor) {
return;
}
const superSets = JSON.parse(getPlayerValue("SuperSets", "[]"));
const anchorRect = menuAnchor.getBoundingClientRect();
//console.log(anchorRect);
const borderWidth = isNewInterface ? 1 : 2;
const menuItemHeight = anchorRect.height - borderWidth * 2;
const menuItemLineHeight = menuItemHeight - borderWidth;
const menuItemTop = anchorRect.top + window.scrollY;
const foreColor = "#f5c137";
const backgroundColor = isNewInterface ? "linear-gradient(to top, #09203f 0%, #537895 100%)" : (document.querySelector("img[src*='i/top_ny']") ? "#003399" : "#6b6b69");
const zIndex = location.pathname == "/photo_pl_photos.php" ? "0" : "100";
let currentMenuItemLeft = setsMenuPosition == "left" ? (anchorRect.left - borderWidth - 1) : (anchorRect.right + borderWidth + 1);
let previousWidth = 0;
for(let i = preferences.length - 1; i >= 0; i--) {
const currentPreferences = preferences[i];
const mainMenuItemId = `SetsMenuItem${i}`;
let mainMenuItem = document.getElementById(mainMenuItemId);
let selectedValueHidden = document.getElementById(`hwmSetsMaster${currentPreferences.name}SelectedValue`);
if(!mainMenuItem) {
const menuHeaderStyle = `min-width: ${menuItemHeight}px; font-size: 9pt; position: absolute; border-radius: 5px; background: ${backgroundColor}; color: ${foreColor}; border: ${borderWidth}px solid ${foreColor}; padding: 0 3px 0 3px; font-weight: bold; text-align: center; z-index: ${zIndex};`;
mainMenuItem = addElement("div", { id: mainMenuItemId, style: menuHeaderStyle }, document.body);
let itemContent = currentPreferences.menuTitle;
let itemTitle = "";
if(currentPreferences.menuImage && isNewInterface) {
itemTitle = currentPreferences.menuTitle;
itemContent = `<img src="${currentPreferences.menuImage}" alt="${itemTitle}" style="height: 90%; margin-top: 2px; border-radius: 50%;">`;
}
let itemChild;
if(isMobileDevice) {
itemChild = addElement("span", { innerHTML: itemContent, style: `color: ${foreColor}; text-decoration: none;` }, mainMenuItem);
} else {
itemChild = addElement("a", { innerHTML: itemContent, href: currentPreferences.setReferencePage, style: `color: ${foreColor}; text-decoration: none;` }, mainMenuItem);
}
if(itemTitle != "") {
itemChild.title = itemTitle;
}
selectedValueHidden = addElement("div", { id: `hwmSetsMaster${currentPreferences.name}SelectedValue`, hidden: "hidden" }, mainMenuItem);
if(i == 3) {
createBuildButton();
}
visibleMunuItems[i] = [mainMenuItem];
}
mainMenuItem.style.height = `${menuItemHeight}px`;
mainMenuItem.style.lineHeight = `${menuItemLineHeight}px`;
mainMenuItem.style.top = `${menuItemTop}px`;
const mainMenuItemRect = mainMenuItem.getBoundingClientRect();
currentMenuItemLeft = currentMenuItemLeft + (setsMenuPosition == "left" ? (- mainMenuItemRect.width) : previousWidth);
previousWidth = mainMenuItemRect.width;
mainMenuItem.style.left = `${currentMenuItemLeft}px`;
const menuContent = getOrCreateAndResizeDropdown(i, mainMenuItem, ` z-index: ${zIndex}; list-style-position: inside; color: ${foreColor}; padding: 2px 3px 2px 3px; white-space: nowrap; background: ${backgroundColor};`);
if(isResize) {
continue;
}
currentPreferences.initSetsApplyAction();
menuContent.style.display = "block"; // Перед заполнением покажем див для правильного определения его размеров (нужно, если он установлен в none)
menuContent.innerHTML = '';
const currentSetNumber = getPlayerValue(currentPreferences.getCurrentSetName(), -1);
let maxClientWidth = menuContent.clientWidth;
for(const currentSet of currentPreferences.sets) {
const dropDownMenuItem = addElement("li", { type: "disc", style: "text-align: left;" }, menuContent);
const currentSetReference = addElement("b", { id: `${currentPreferences.getCurrentSetName()}SetReference${currentSet.number}`, innerHTML: currentSet.name, title: currentSet.title || "", style: `color: ${foreColor}; cursor: pointer;` }, dropDownMenuItem);
if(currentSet.url) {
currentSetReference.addEventListener("click", function() { applySet(currentSetReference, currentPreferences, currentSet); });
}
if(currentSet.number == currentSetNumber) {
selectedValueHidden.innerHTML = currentSet.number;
markCurrent(currentSetReference, currentPreferences, currentSet.number);
}
currentPreferences.menuItems[currentSet.number] = currentSetReference;
if(i == 3) {
const fractionBuilds = superSets.filter(x => x.Fraction == currentSet.number);
if(fractionBuilds.length > 0) {
const superDropdown = getOrCreateAndResizeDropdown(i, currentSetReference, ` z-index: ${Number(zIndex) + 1}; list-style-position: inside; color: ${foreColor}; padding: 2px 3px 2px 3px; white-space: nowrap; background: ${backgroundColor};`, true);
for(const build of fractionBuilds) {
const superDropdownMenuItem = addElement("li", { type: "disc", style: "text-align: left;" }, superDropdown);
const html = `${build.Name} <span id="deleteSuperSet${build.Id}Button" title='${isEn ? "Delete" : "Удалить"}' style="cursor: pointer; display: inline; color: yellow;">×</span>`
const superDropdownText = addElement("b", { name: "superDropdownText", innerHTML: html, style: `color: ${foreColor}; cursor: pointer;` }, superDropdownMenuItem);
document.getElementById(`deleteSuperSet${build.Id}Button`).addEventListener("click", function(e) { e.stopPropagation(); deleteSuperSet(build.Id, superDropdownMenuItem); });
superDropdownMenuItem.addEventListener("click", function() { applyBuild(superDropdownText, build); });
if(build.Id == getPlayerValue("SuperSet")) {
superDropdownText.style.color = '#0f0';
}
}
superDropdown.style.display = "none";
}
}
let currentWidth = getTextWidth(currentSet.name, getCanvasFont(currentSetReference));
if(maxClientWidth < currentWidth) {
maxClientWidth = currentWidth;
}
}
if(i == 3) {
const showAddSuperSetButtonLable = addElement("label", { for: "showAddSuperSetButtonCheckbox", innerText: (isEn ? 'Show button "Create super set"' : 'Показать кнопку "Создать билд"') + "\t" }, menuContent);
const showAddSuperSetButtonCheckbox = addElement("input", { id: "showAddSuperSetButtonCheckbox", type: "checkbox" }, menuContent);
showAddSuperSetButtonCheckbox.checked = getPlayerBool("ShowAddSuperSetButton", true);
showAddSuperSetButtonCheckbox.addEventListener("change", function() { setPlayerValue("ShowAddSuperSetButton", this.checked); }, false);
addElement("br", { }, menuContent);
const showMenyAtRightLable = addElement("label", { for: "showMenyAtRightCheckbox", innerText: (isEn ? 'Show menu at right' : 'Показать меню справа') + "\t" }, menuContent);
const showMenyAtRightCheckbox = addElement("input", { id: "showMenyAtRightCheckbox", type: "checkbox" }, menuContent);
showMenyAtRightCheckbox.checked = getPlayerBool("ShowMenyAtRight");
showMenyAtRightCheckbox.addEventListener("change", function() { setPlayerValue("ShowMenyAtRight", this.checked); }, false);
}
menuContent.style.minWidth = `${(maxClientWidth + 25)}px`;
menuContent.style.display = "none";
}
}
function createBuildButton() {
if(!getPlayerBool("ShowAddSuperSetButton", true)) {
return;
}
const fractionsMainMenuItem = document.getElementById(`SetsMenuItem3`);
let addBuildButton = document.getElementById("addBuildButton");
if(addBuildButton) {
return;
}
if(isNewInterface) {
addBuildButton = addElement("div", { id: "addBuildButton", class: "position_tr", innerHTML: `<img class="NotificationIcon" src="${resourcesPath}/i/new_top/_panelBattles.png" style="width: 16px; height: 16px;" title="${isEn ? "Create build" : "Создать билд"}" >` }, fractionsMainMenuItem);
} else {
addBuildButton = addElement("a", { id: "addBuildButton", href: "javascript:void(0);", style: "text-decoration: none; vertical-align: bottom;", innerHTML: `<img src="${resourcesPath}/i/new_top/_panelBattles.png" style="width: 16px; height: 16px; border-radius: 50%;" title="${isEn ? "Create build" : "Создать билд"}" >` }, fractionsMainMenuItem);
}
addBuildButton.addEventListener("click", function(e) { e.stopPropagation(); addBuild(); });
}
function addBuild() {
const superSetName = prompt(isEn ? "Enter build name" : "Введите название билда");
if(superSetName) {
//deletePlayerValue("SuperSets");
const superSets = JSON.parse(getPlayerValue("SuperSets", "[]"));
superSets.push({
Id: Date.now(),
Name: superSetName,
Fraction: Fraction,
WeaponSet: getPlayerValue(weaponSetsPreferences.getCurrentSetName(), -1),
SkillSet: getPlayerValue(skillSetsPreferences.getCurrentSetName(), -1),
ArmySet: getPlayerValue(armySetsPreferences.getCurrentSetName(), -1)
});
setPlayerValue("SuperSets", JSON.stringify(superSets));
}
}
function deleteSuperSet(id, menuItem) {
const superSets = JSON.parse(getPlayerValue("SuperSets", "[]"));
const deletingIndex = superSets.findIndex(x => x.Id == id);
if(deletingIndex > -1) {
superSets.splice(deletingIndex, 1);
setPlayerValue("SuperSets", JSON.stringify(superSets));
if(menuItem) {
menuItem.remove();
}
}
}
async function applyBuild(superDropdownText, build) {
const sets = [weaponSetsPreferences.name, skillSetsPreferences.name, armySetsPreferences.name];
const originalText = superDropdownText ? superDropdownText.innerHTML : "";
if(superDropdownText) {
superDropdownText.innerHTML += " " + getWheelImage();
}
if(build.Fraction != Fraction) {
await applySet(document.getElementById(`${fractionsPreferences.getCurrentSetName()}SetReference${build.Fraction}`), fractionsPreferences, fractionsPreferences.sets.find(x => x.number == build.Fraction), false);
sets.push(fractionsPreferences.name);
}
await applySet(document.getElementById(`${weaponSetsPreferences.getCurrentSetName()}SetReference${build.WeaponSet}`), weaponSetsPreferences, weaponSetsPreferences.sets.find(x => x.number == build.WeaponSet), false);
await applySet(document.getElementById(`${skillSetsPreferences.getCurrentSetName()}SetReference${build.SkillSet}`), skillSetsPreferences, skillSetsPreferences.sets.find(x => x.number == build.SkillSet), false);
await applySet(document.getElementById(`${armySetsPreferences.getCurrentSetName()}SetReference${build.ArmySet}`), armySetsPreferences, armySetsPreferences.sets.find(x => x.number == build.ArmySet), false);
await updatePanels(sets);
setPlayerValue("SuperSet", build.Id);
if(superDropdownText) {
Array.from(document.querySelectorAll("b[name=superDropdownText]")).forEach(x => x.style.color = "#f5c137");
superDropdownText.innerHTML = originalText;
superDropdownText.style.color = '#0f0';
}
}
function markCurrent(selectedMenuItem, currentPreferences, currentSetNumber) {
setPlayerValue(currentPreferences.getCurrentSetName(), currentSetNumber);
if(selectedMenuItem) {
selectedMenuItem.style.color = '#0f0';
if(currentPreferences.currentMenuItem && currentPreferences.currentMenuItem != selectedMenuItem) {
currentPreferences.currentMenuItem.style.color = "#f5c137";
}
currentPreferences.currentMenuItem = selectedMenuItem;
}
}
function addSetChangerListener(htmlElement, currentPreferences, setNumber) {
htmlElement.addEventListener("click", function() { markCurrent(currentPreferences.menuItems[setNumber], currentPreferences, setNumber); });
}
async function applySet(selectedMenuItem, currentPreferences, currentSet, callPageRefreshFunction = true) {
markCurrent(selectedMenuItem, currentPreferences, currentSet.number);
const originalText = selectedMenuItem ? selectedMenuItem.innerHTML : "";
if(selectedMenuItem) {
selectedMenuItem.innerHTML += " " + getWheelImage();
}
if(currentSet.method == "POST") {
await postRequest(currentSet.url, currentSet.data);
} else {
await getRequest(currentSet.url);
}
if(selectedMenuItem) {
selectedMenuItem.innerHTML = originalText;
if(isMobileDevice) {
selectedMenuItem.parentNode.parentNode.style.display = "none";
}
}
const selectedValueDiv = document.getElementById(`hwmSetsMaster${currentPreferences.name}SelectedValue`);
if(selectedValueDiv) {
selectedValueDiv.innerHTML = currentSet.number;
}
if(typeof(currentPreferences.setChanged) == "function") {
await currentPreferences.setChanged(currentSet.number);
}
if(callPageRefreshFunction) {
updatePanels([currentPreferences.name]);
}
}
function drowSkillChangers() {
if(location.pathname=='/home.php' && !document.querySelector(`#increaseattackAmountInput`)) {
let skillsCount = 0;
let re = new RegExp(isNewPersonPage ? `>${LocalizedString.AvailablePoints}:\\s(\\d+)<` : `<b>${LocalizedString.AvailablePoints}:</b>\\s(\\d+)`);
const skillsExec = re.exec(document.body.innerHTML);
if(skillsExec) {
skillsCount += parseInt(skillsExec[1]);
}
re = new RegExp(isNewPersonPage ? `>${LocalizedString.AvailableTalentPoints}:\\s(\\d+)<` : `<b>${LocalizedString.AvailableTalentPoints}:</b>\\s(\\d+)`);
const perksSkillsExec = re.exec(document.body.innerHTML);
if(perksSkillsExec) {
skillsCount += parseInt(perksSkillsExec[1]);
}
//console.log(`skillsCount: ${skillsCount}`);
if(skillsCount == 0) {
return;
}
const skillValueContainers = [];
if(isNewPersonPage) {
const container = document.querySelector("div#home_css_stats_wrap_div");
const inv_stat_dataDivs = container.querySelectorAll("div.inv_stat_data.home_stat_data.show_hint");
for(const inv_stat_dataDiv of inv_stat_dataDivs) {
const increaseButton = inv_stat_dataDiv.querySelector("div.home_button2.btn_hover2");
if(!increaseButton) {
continue;
}
const skillValueContainer = inv_stat_dataDiv.querySelector("div.inv_stat_text.home_stat_text");
skillValueContainers.push(skillValueContainer);
}
} else {
const increaseRefs = document.querySelectorAll("a[href^='home.php?increase=']"); //home.php?increase=defence
for(const increaseRef of increaseRefs) {
const sklilIncreaseCell = getParent(increaseRef, "td");
const skillValueContainer = sklilIncreaseCell.previousSibling;
skillValueContainers.push(skillValueContainer);
}
}
const skillNames = ["attack", "defence", "power", "knowledge"];
let i = 0;
for(const skillValueContainer of skillValueContainers) {
const skillValue = Number((skillValueContainer.querySelector("b") || skillValueContainer).innerText);
skillValueContainer.innerHTML = "";
const skill = skillNames[i];
const increaseAmountInput = addElement("input", { id: `increase${skill}AmountInput`, name: "increaseAmountInput", value: skillValue, type: "number", min: skillValue, max: skillValue + skillsCount, size: 4, onfocus: "this.select();", title: LocalizedString.IncreaseManyPointsTooltip.replace("${minValue}", skillValue + 1).replace("${maxValue}", skillValue + skillsCount) }, skillValueContainer);
increaseAmountInput.addEventListener("change", function() { const targetValue = Number(increaseAmountInput.value); if(targetValue > skillValue && targetValue <= skillValue + skillsCount) { changeSkill(increaseAmountInput, isNewPersonPage, skill, skillValue, targetValue); } });
i++;
}
}
}
async function changeSkill(increaseAmountInput, isNewPersonPage, skill, currentValue, targetValue) {
while(currentValue < targetValue) {
const url = `/home.php?increase=${skill}` + (isNewPersonPage ? `&info=1&js_output=1&rand=${Math.random() * 1000000}` : "");
const txt = await getRequestText(url, isNewPersonPage ? "text/html; charset=UTF-8" : "text/html; charset=windows-1251");
currentValue++;
if(isNewPersonPage) {
if (txt.substring(0, 7) != 'HCSS_OK') {
window.location = '/home.php?info';
return;
}
const data = txt.split('@');
const home_css_stats_wrap_div = document.getElementById('home_css_stats_wrap_div');
if(data && data[1] && home_css_stats_wrap_div) {
home_css_stats_wrap_div.innerHTML = data[1];
if(data.length > 2 && document.getElementById('home_css_mana_count')) {
document.getElementById('home_css_mana_count').innerHTML = parseInt(data[2]);
}
if(typeof win.hwm_hints_init === 'function') win.hwm_hints_init();
}
} else {
increaseAmountInput.value = currentValue;
}
}
if(!isNewPersonPage) {
location.reload();
}
}
function getWheelImage() { return `<img border="0" align="absmiddle" height="11" src="${resourcesPath}/css/loading.gif">`; }
function getFraction() {
let currentFractionNumber;
if(location.pathname == '/home.php') {
// for new home page
let currentFractionIconContainer = document.querySelector("div.home_css_pl_fract.show_hint");
if(!currentFractionIconContainer) {
currentFractionIconContainer = document.querySelector("a[href^='castle.php?change_faction_dialog']");
}
if(currentFractionIconContainer) {
const currentFractionIconImg = currentFractionIconContainer.querySelector("img");
currentFractionNumber = currentFractionIconImg.src.split("i/f/r")[1].split(".png")[0];
}
} else if(location.pathname=='/pl_info.php' && getUrlParamValue(location.href, "id") == PlayerId) {
const fractionImage = document.querySelector("img[src*='i/f/r']");
const regExp = new RegExp('\\/i\\/f\\/r(\\d+)\\.png');
const regExpExec = regExp.exec(fractionImage.src);
if(regExpExec) {
currentFractionNumber = regExpExec[1];
}
} else if(location.pathname=='/castle.php') {
const selectedFractionImg = document.querySelector("div.castle_faction_div_inside2 img");
const selectedFractionImgName = selectedFractionImg.getAttribute("src");
const selectedFractionNumber = selectedFractionImgName.split("kukla_png/kukla")[1].split(".")[0]; //dcdn.heroeswm.ru/i/kukla_png/kukla5.png
const fractionsDiv = document.querySelector("div[id='faction_list']");
if(fractionsDiv.getAttribute("style").includes("display:none;")) {
currentFractionNumber = selectedFractionNumber;
}
}
if(currentFractionNumber) {
setPlayerValue("Fraction", currentFractionNumber);
}
Fraction = parseInt(getPlayerValue("Fraction"));
}
async function updatePanels(sets) {
let pageReloadNeeded = false;
let panels = [];
if(sets.includes(weaponSetsPreferences.name) && ["/home.php", "/inventory.php", "/pl_info.php", "/map.php"].includes(location.pathname)) {
pageReloadNeeded = true;
if(location.pathname == '/home.php') {
pushNew(panels, homeArtsPanelSelector);
pushNew(panels, homeStatsPanelSelector);
pageReloadNeeded = false;
}
if(location.pathname == '/pl_info.php') {
if(getUrlParamValue(location.href, "id") == PlayerId) {
pushNew(panels, playerInfoArtsPanelSelector);
pushNew(panels, playerInfoStatsPanelSelector);
}
pageReloadNeeded = false;
}
if(location.pathname == '/map.php') {
pushNew(panels, mapHuntButtons2PanelSelector);
pushNew(panels, mapMercenaryTaskPanelSelector);
pageReloadNeeded = false;
}
}
if(sets.includes(skillSetsPreferences.name) && ["/skillwheel.php", "/pl_info.php", "/home.php", "/inventory.php"].includes(location.pathname)) {
pageReloadNeeded = true;
if(location.pathname == '/home.php') {
pushNew(panels, homeStatsPanelSelector);
pageReloadNeeded = false;
}
if(location.pathname == '/pl_info.php') {
if(getUrlParamValue(location.href, "id") == PlayerId) {
pushNew(panels, playerInfoStatsPanelSelector);
pushNew(panels, playerInfoPerksPanelSelector);
}
pageReloadNeeded = false;
}
if(location.pathname == '/inventory.php') {
pushNew(panels, inventoryStatsPanelSelector);
pageReloadNeeded = false;
}
}
if(sets.includes(armySetsPreferences.name) && ["/home.php", "/army.php", "/pl_info.php"].includes(location.pathname)) {
pageReloadNeeded = true;
if(location.pathname == '/home.php') {
pushNew(panels, homeArmyPanelSelector);
pageReloadNeeded = false;
}
if(location.pathname == '/pl_info.php') {
if(getUrlParamValue(location.href, "id") == PlayerId) {
pushNew(panels, playerInfoArmyPanelSelector);
}
pageReloadNeeded = false;
}
}
if(sets.includes(fractionsPreferences.name) && ["/home.php", "/army.php", "/pl_info.php", "/castle.php", "/inventory.php", "/skillwheel.php"].includes(location.pathname)) {
pageReloadNeeded = true;
}
if(pageReloadNeeded) {
if(location.pathname == "/army.php") {
location = "/army.php";
} else {
window.location.reload();
}
} else {
await refreshUpdatePanels(panels);
}
}
// API
function getPlayerFractionValue(key, defaultValue, fraction = Fraction) { return getPlayerValue(getFractionKey(key, fraction), defaultValue); };
function setPlayerFractionValue(key, value, fraction = Fraction) { setPlayerValue(getFractionKey(key, fraction), value); };
function deletePlayerFractionValue(key, fraction = Fraction) { return deletePlayerValue(getFractionKey(key, fraction)); };
function getFractionKey(key, fraction = Fraction) { return `${key}${fraction}f`; }