您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Цена боя и оптимальный слом на рынке
当前为
// ==UserScript== // @name hwmOptimalRepairAtMarket // @author Tamozhnya1 // @namespace Tamozhnya1 // @description Цена боя и оптимальный слом на рынке // @version 17.0 // @include *heroeswm.ru/* // @include *lordswm.com/* // @grant GM_deleteValue // @grant GM_getValue // @grant GM_setValue // @grant GM.xmlHttpRequest // @grant GM.notification // @license MIT // ==/UserScript== const playerIdMatch = document.cookie.match(/pl_id=(\d+)/); if(playerIdMatch) { var PlayerId = playerIdMatch[1]; } const stopwatchStartTime = Date.now(); function millisecondsIntervalToString(interval) { let diff = interval; const days = Math.floor(diff / 1000 / 60 / 60 / 24); diff -= days * 1000 * 60 * 60 * 24; const hours = Math.floor(diff / 1000 / 60 / 60); diff -= hours * 1000 * 60 * 60; const mimutes = Math.floor(diff / 1000 / 60); diff -= mimutes * 1000 * 60; const seconds = Math.floor(diff / 1000); diff -= seconds * 1000; const formatedTime = (days > 0 ? days + " " : "") + (hours > 0 ? hours + ":" : "") + mimutes.toString().padStart(2, "0") + ':' + seconds.toString().padStart(2, "0") + "." + diff.toString().padStart(3, "0"); return formatedTime; } const isHeartOnPage = (document.querySelector("canvas#heart") || document.querySelector("div#heart_js_mobile")) ? true : false; const mooving = location.pathname == '/map.php' && !document.getElementById("map_right_block"); const isNewInterface = document.querySelector("div#hwm_header") ? true : false; const isMobileInterface = document.querySelector("div#btnMenuGlobal") ? true : false; const isNewPersonPage = document.querySelector("div#hwm_no_zoom") ? true : false; const LotType = { Purchase: 1, Auction: 2 }; const LastBestLotDataName = "LastBestLotData_"; const OptimalRepairAtMarketSmithLevelName = "OptimalRepairAtMarketSmithLevel"; const SmithRewardPercentName = "SmithRewardPercent"; const ShopArtFactoryPriceName = "ShopArtFactoryPrice_"; const ShopArtShopPriceName = "ShopArtShopPrice_"; const ArtPriceSettingsName = "ArtPriceSettings"; const GoldPng32 = "i/r/32/gold.png"; const GoldPng48 = "i/r/48/gold.png"; const locations = { 1: [50,50,"Empire Capital","EmC","Столица Империи"], 2: [51,50,"East River","EsR","Восточная Река"], 3: [50,49,"Tiger Lake","TgL","Тигриное Озеро"], 4: [51,49,"Rogues' Wood","RgW","Лес Разбойников"], 5: [50,51,"Wolf Dale","WoD","Долина Волков"], 6: [50,48,"Peaceful Camp","PcC","Мирный Лагерь"], 7: [49,51,"Lizard Lowland","LzL","Равнина Ящеров"], 8: [49,50,"Green Wood","GrW","Зеленый Лес"], 9: [49,48,"Eagle Nest","EgN","Орлиное Гнездо"], 10: [50,52,"Portal Ruins","PoR","Руины Портала"], 11: [51,51,"Dragons' Caves","DrC","Пещеры Драконов"], 12: [49,49,"Shining Spring","ShS","Сияющий Родник"], 13: [48,49,"Sunny City","SnC","Солнечный Город"], 14: [52,50,"Magma Mines","MgM","Магма Шахты"], 15: [52,49,"Bear Mountain","BrM","Медвежья Гора"], 16: [52,48,"Fairy Trees","FrT","Магический Лес"], 17: [53,50,"Harbour City","HrC","Портовый Город"], 18: [53,49,"Mythril Coast","MfC","Мифриловый Берег"], 19: [51,52,"Great Wall","GtW","Великая Стена"], 20: [51,53,"Titans' Valley","TiV","Равнина Титанов"], 21: [52,53,"Fishing Village","FsV","Рыбачье село"], 22: [52,54,"Kingdom Castle","KiC","Замок Королевства"], 23: [48,48,"Ungovernable Steppe","UnS","Непокорная Степь"], 24: [51,48,"Crystal Garden","CrG","Кристальный Сад"], 25: [53,52,"East Island","EsI","Восточный Остров"], 26: [49,52,"The Wilderness","ThW","Дикие земли"], 27: [48,50,"Sublime Arbor","SbA","Великое Древо"] }; let playerLocationNumber = getPlayerLocationNumber(); const windowObject = window.wrappedJSObject || unsafeWindow; if(windowObject.sign) { GM_setValue("PlayerSign", windowObject.sign); } const PlayerSign = GM_getValue("PlayerSign"); var CombatCostBestDeviation = parseInt(GM_getValue("CombatCostBestDeviation", 1)); // percent var CombatCostGoodDeviation = parseInt(GM_getValue("CombatCostGoodDeviation", 10)); // percent let CombatCostBestDeviationColor = GM_getValue("CombatCostBestDeviationColor", "#becb10"); let CombatCostGoodDeviationColor = GM_getValue("CombatCostGoodDeviationColor", "#90EE90"); var SmithLevel = parseInt(GM_getValue(OptimalRepairAtMarketSmithLevelName, 9)); const SortType = { Text: 1, Number: 2 }; const InventoryArtMenuDirections = { Horizontal: 1, Vertical: 2 }; const InventoryArtMenuDirection = InventoryArtMenuDirections.Vertical; var CraftLevels = [0, 1, 2, 4, 6, 9, 12, 15, 19, 24, 30, 37, 45]; var CraftType = { Unknown: 0, Weapon: 1, Armor: 2, Jewelry: 3 }; const ArtifactInfo = { "staff": { Strength: 40, RepairCost: 2527, MarketCategory: "weapon", CraftType: 1 }, "sword18": { Strength: 70, RepairCost: 17755, MarketCategory: "weapon", CraftType: 1 }, "wood_sword": { Strength: 7, RepairCost: 133, MarketCategory: "weapon", CraftType: 1 }, "long_bow": { Strength: 50, RepairCost: 6317, MarketCategory: "weapon", CraftType: 1 }, "dagger_dex": { Strength: 40, RepairCost: 3230, MarketCategory: "weapon", CraftType: 1 }, "dagger": { Strength: 30, RepairCost: 912, MarketCategory: "weapon", CraftType: 1 }, "dagger20": { Strength: 60, RepairCost: 9291, MarketCategory: "weapon", CraftType: 1 }, "dagger16": { Strength: 60, RepairCost: 9120, MarketCategory: "weapon", CraftType: 1 }, "shortbow": { Strength: 20, RepairCost: 342, MarketCategory: "weapon", CraftType: 1 }, "gnome_hammer": { Strength: 25, RepairCost: 294, MarketCategory: "weapon", CraftType: 1 }, "bow14": { Strength: 65, RepairCost: 9946, MarketCategory: "weapon", CraftType: 1 }, "bow17": { Strength: 65, RepairCost: 10108, MarketCategory: "weapon", CraftType: 1 }, "power_sword": { Strength: 80, RepairCost: 9775, MarketCategory: "weapon", CraftType: 1 }, "requital_sword": { Strength: 40, RepairCost: 2527, MarketCategory: "weapon", CraftType: 1 }, "firsword15": { Strength: 70, RepairCost: 17670, MarketCategory: "weapon", CraftType: 1 }, "ssword16": { Strength: 46, RepairCost: 6051, MarketCategory: "weapon", CraftType: 1 }, "ssword8": { Strength: 40, RepairCost: 3838, MarketCategory: "weapon", CraftType: 1 }, "ssword10": { Strength: 45, RepairCost: 4854, MarketCategory: "weapon", CraftType: 1 }, "broad_sword": { Strength: 60, RepairCost: 4721, MarketCategory: "weapon", CraftType: 1 }, "def_sword": { Strength: 40, RepairCost: 1292, MarketCategory: "weapon", CraftType: 1 }, "dagger_myf": { Strength: 60, RepairCost: 8626, MarketCategory: "weapon", CraftType: 1 }, "mif_sword": { Strength: 70, RepairCost: 16957, MarketCategory: "weapon", CraftType: 1 }, "mif_staff": { Strength: 70, RepairCost: 16387, MarketCategory: "weapon", CraftType: 1 }, "ssword13": { Strength: 50, RepairCost: 5985, MarketCategory: "weapon", CraftType: 1 }, "mstaff13": { Strength: 40, RepairCost: 4797, MarketCategory: "weapon", CraftType: 1 }, "mstaff8": { Strength: 30, RepairCost: 2888, MarketCategory: "weapon", CraftType: 1 }, "smstaff16": { Strength: 37, RepairCost: 4883, MarketCategory: "weapon", CraftType: 1 }, "staff18": { Strength: 70, RepairCost: 17746, MarketCategory: "weapon", CraftType: 1 }, "sor_staff": { Strength: 50, RepairCost: 6118, MarketCategory: "weapon", CraftType: 1 }, "ffstaff15": { Strength: 70, RepairCost: 17679, MarketCategory: "weapon", CraftType: 1 }, "mstaff10": { Strength: 35, RepairCost: 3781, MarketCategory: "weapon", CraftType: 1 }, "mm_sword": { Strength: 70, RepairCost: 17195, MarketCategory: "weapon", CraftType: 1 }, "mm_staff": { Strength: 70, RepairCost: 16986, MarketCategory: "weapon", CraftType: 1 }, "composite_bow": { Strength: 55, RepairCost: 8246, MarketCategory: "weapon", CraftType: 1 }, "steel_blade": { Strength: 30, RepairCost: 465, MarketCategory: "weapon", CraftType: 1 }, "large_shield": { Strength: 70, RepairCost: 9576, MarketCategory: "shield", CraftType: 2 }, "hauberk": { Strength: 40, RepairCost: 2289, MarketCategory: "cuirass", CraftType: 2 }, "boots2": { Strength: 35, RepairCost: 1026, MarketCategory: "boots", CraftType: 2 }, "armor15": { Strength: 70, RepairCost: 9310, MarketCategory: "cuirass", CraftType: 2 }, "marmor17": { Strength: 70, RepairCost: 9310, MarketCategory: "cuirass", CraftType: 2 }, "sarmor16": { Strength: 44, RepairCost: 4351, MarketCategory: "cuirass", CraftType: 2 }, "armor17": { Strength: 70, RepairCost: 9490, MarketCategory: "cuirass", CraftType: 2 }, "leather_shiled": { Strength: 18, RepairCost: 266, MarketCategory: "cuirass", CraftType: 2 }, "leatherhat": { Strength: 12, RepairCost: 171, MarketCategory: "helm", CraftType: 2 }, "leatherboots": { Strength: 14, RepairCost: 199, MarketCategory: "boots", CraftType: 2 }, "leatherplate": { Strength: 30, RepairCost: 1358, MarketCategory: "cuirass", CraftType: 2 }, "hunter_boots": { Strength: 30, RepairCost: 912, MarketCategory: "boots", CraftType: 2 }, "leather_helm": { Strength: 30, RepairCost: 627, MarketCategory: "helm", CraftType: 2 }, "wizard_cap": { Strength: 35, RepairCost: 1596, MarketCategory: "helm", CraftType: 2 }, "chain_coif": { Strength: 40, RepairCost: 1539, MarketCategory: "helm", CraftType: 2 }, "xymhelmet15": { Strength: 70, RepairCost: 6612, MarketCategory: "helm", CraftType: 2 }, "mhelmetzh13": { Strength: 70, RepairCost: 6384, MarketCategory: "helm", CraftType: 2 }, "round_shiled": { Strength: 7, RepairCost: 104, MarketCategory: "shield", CraftType: 2 }, "mif_light": { Strength: 70, RepairCost: 6251, MarketCategory: "cuirass", CraftType: 2 }, "mif_lboots": { Strength: 55, RepairCost: 7153, MarketCategory: "boots", CraftType: 2 }, "mif_lhelmet": { Strength: 70, RepairCost: 5244, MarketCategory: "helm", CraftType: 2 }, "sarmor9": { Strength: 40, RepairCost: 2479, MarketCategory: "cuirass", CraftType: 2 }, "miff_plate": { Strength: 75, RepairCost: 9842, MarketCategory: "cuirass", CraftType: 2 }, "sarmor13": { Strength: 50, RepairCost: 4322, MarketCategory: "cuirass", CraftType: 2 }, "boots13": { Strength: 70, RepairCost: 8502, MarketCategory: "boots", CraftType: 2 }, "zxhelmet13": { Strength: 70, RepairCost: 6384, MarketCategory: "helm", CraftType: 2 }, "shield13": { Strength: 70, RepairCost: 10174, MarketCategory: "shield", CraftType: 2 }, "mage_armor": { Strength: 50, RepairCost: 4465, MarketCategory: "cuirass", CraftType: 2 }, "robewz15": { Strength: 70, RepairCost: 9310, MarketCategory: "cuirass", CraftType: 2 }, "wiz_robe": { Strength: 70, RepairCost: 9376, MarketCategory: "cuirass", CraftType: 2 }, "sboots12": { Strength: 35, RepairCost: 2992, MarketCategory: "boots", CraftType: 2 }, "shelm12": { Strength: 40, RepairCost: 2660, MarketCategory: "helm", CraftType: 2 }, "sboots16": { Strength: 30, RepairCost: 3239, MarketCategory: "boots", CraftType: 2 }, "boots15": { Strength: 70, RepairCost: 8559, MarketCategory: "boots", CraftType: 2 }, "boots17": { Strength: 70, RepairCost: 8683, MarketCategory: "boots", CraftType: 2 }, "mboots17": { Strength: 70, RepairCost: 8683, MarketCategory: "boots", CraftType: 2 }, "mboots14": { Strength: 70, RepairCost: 8825, MarketCategory: "boots", CraftType: 2 }, "sboots9": { Strength: 30, RepairCost: 2137, MarketCategory: "boots", CraftType: 2 }, "ciras": { Strength: 70, RepairCost: 4455, MarketCategory: "cuirass", CraftType: 2 }, "steel_helmet": { Strength: 70, RepairCost: 3676, MarketCategory: "helm", CraftType: 2 }, "s_shield": { Strength: 15, RepairCost: 266, MarketCategory: "shield", CraftType: 2 }, "full_plate": { Strength: 75, RepairCost: 9243, MarketCategory: "cuirass", CraftType: 2 }, "steel_boots": { Strength: 70, RepairCost: 5785, MarketCategory: "boots", CraftType: 2 }, "shoe_of_initiative": { Strength: 40, RepairCost: 2384, MarketCategory: "boots", CraftType: 2 }, "wiz_boots": { Strength: 65, RepairCost: 8008, MarketCategory: "boots", CraftType: 2 }, "mif_hboots": { Strength: 65, RepairCost: 7752, MarketCategory: "boots", CraftType: 2 }, "mif_hhelmet": { Strength: 70, RepairCost: 6298, MarketCategory: "helm", CraftType: 2 }, "shelm16": { Strength: 40, RepairCost: 2774, MarketCategory: "helm", CraftType: 2 }, "mage_helm": { Strength: 50, RepairCost: 3277, MarketCategory: "helm", CraftType: 2 }, "shelm8": { Strength: 30, RepairCost: 1197, MarketCategory: "helm", CraftType: 2 }, "myhelmet15": { Strength: 70, RepairCost: 6583, MarketCategory: "helm", CraftType: 2 }, "helmet17": { Strength: 70, RepairCost: 7239, MarketCategory: "helm", CraftType: 2 }, "mhelmet17": { Strength: 70, RepairCost: 7239, MarketCategory: "helm", CraftType: 2 }, "knowledge_hat": { Strength: 25, RepairCost: 978, MarketCategory: "helm", CraftType: 2 }, "dragon_shield": { Strength: 70, RepairCost: 8778, MarketCategory: "shield", CraftType: 2 }, "shield16": { Strength: 70, RepairCost: 10298, MarketCategory: "shield", CraftType: 2 }, "sshield17": { Strength: 35, RepairCost: 4018, MarketCategory: "shield", CraftType: 2 }, "shield19": { Strength: 70, RepairCost: 10469, MarketCategory: "shield", CraftType: 2 }, "sshield5": { Strength: 40, RepairCost: 2888, MarketCategory: "shield", CraftType: 2 }, "sshield11": { Strength: 40, RepairCost: 3876, MarketCategory: "shield", CraftType: 2 }, "defender_shield": { Strength: 40, RepairCost: 1130, MarketCategory: "shield", CraftType: 2 }, "sshield14": { Strength: 38, RepairCost: 3923, MarketCategory: "shield", CraftType: 2 }, "wzzamulet16": { Strength: 65, RepairCost: 10972, MarketCategory: "necklace", CraftType: 3 }, "mmzamulet16": { Strength: 65, RepairCost: 10972, MarketCategory: "necklace", CraftType: 3 }, "smamul17": { Strength: 30, RepairCost: 4389, MarketCategory: "necklace", CraftType: 3 }, "bafamulet15": { Strength: 65, RepairCost: 10811, MarketCategory: "necklace", CraftType: 3 }, "amulet_of_luck": { Strength: 25, RepairCost: 959, MarketCategory: "necklace", CraftType: 3 }, "samul14": { Strength: 30, RepairCost: 4370, MarketCategory: "necklace", CraftType: 3 }, "wzzamulet13": { Strength: 60, RepairCost: 9975, MarketCategory: "necklace", CraftType: 3 }, "warring13": { Strength: 60, RepairCost: 10279, MarketCategory: "ring", CraftType: 3 }, "ring19": { Strength: 65, RepairCost: 11305, MarketCategory: "ring", CraftType: 3 }, "wwwring16": { Strength: 65, RepairCost: 11238, MarketCategory: "ring", CraftType: 3 }, "dring5": { Strength: 40, RepairCost: 3496, MarketCategory: "ring", CraftType: 3 }, "warriorring": { Strength: 40, RepairCost: 6697, MarketCategory: "ring", CraftType: 3 }, "mmmring16": { Strength: 65, RepairCost: 11238, MarketCategory: "ring", CraftType: 3 }, "i_ring": { Strength: 10, RepairCost: 171, MarketCategory: "ring", CraftType: 3 }, "smring10": { Strength: 30, RepairCost: 2859, MarketCategory: "ring", CraftType: 3 }, "dring18": { Strength: 70, RepairCost: 14820, MarketCategory: "ring", CraftType: 3 }, "mring19": { Strength: 65, RepairCost: 11390, MarketCategory: "ring", CraftType: 3 }, "circ_ring": { Strength: 50, RepairCost: 6507, MarketCategory: "ring", CraftType: 3 }, "dring15": { Strength: 70, RepairCost: 14534, MarketCategory: "ring", CraftType: 3 }, "powerring": { Strength: 40, RepairCost: 5187, MarketCategory: "ring", CraftType: 3 }, "bring14": { Strength: 60, RepairCost: 10374, MarketCategory: "ring", CraftType: 3 }, "sring4": { Strength: 15, RepairCost: 579, MarketCategory: "ring", CraftType: 3 }, "doubt_ring": { Strength: 12, RepairCost: 1064, MarketCategory: "ring", CraftType: 3 }, "dring21": { Strength: 70, RepairCost: 15104, MarketCategory: "ring", CraftType: 3 }, "rashness_ring": { Strength: 30, RepairCost: 1928, MarketCategory: "ring", CraftType: 3 }, "darkring": { Strength: 50, RepairCost: 8379, MarketCategory: "ring", CraftType: 3 }, "sring17": { Strength: 30, RepairCost: 2907, MarketCategory: "ring", CraftType: 3 }, "warrior_pendant": { Strength: 50, RepairCost: 8046, MarketCategory: "necklace", CraftType: 3 }, "mamulet19": { Strength: 65, RepairCost: 11039, MarketCategory: "necklace", CraftType: 3 }, "power_pendant": { Strength: 60, RepairCost: 7381, MarketCategory: "necklace", CraftType: 3 }, "amulet19": { Strength: 65, RepairCost: 11039, MarketCategory: "necklace", CraftType: 3 }, "magic_amulet": { Strength: 50, RepairCost: 8379, MarketCategory: "necklace", CraftType: 3 }, "cloack17": { Strength: 65, RepairCost: 9975, MarketCategory: "cloack", CraftType: 3 }, "cloackwz15": { Strength: 65, RepairCost: 9614, MarketCategory: "cloack", CraftType: 3 }, "scroll18": { Strength: 70, RepairCost: 10307, MarketCategory: "weapon", CraftType: 3 }, "scloack8": { Strength: 30, RepairCost: 2052, MarketCategory: "cloack", CraftType: 3 }, "bravery_medal": { Strength: 25, RepairCost: 560, MarketCategory: "necklace", CraftType: 3 }, "mmzamulet13": { Strength: 60, RepairCost: 9975, MarketCategory: "necklace", CraftType: 3 }, "dring12": { Strength: 65, RepairCost: 13356, MarketCategory: "ring", CraftType: 3 }, "soul_cape": { Strength: 30, RepairCost: 1197, MarketCategory: "cloack", CraftType: 3 }, "wiz_cape": { Strength: 60, RepairCost: 8711, MarketCategory: "cloack", CraftType: 3 }, "samul17": { Strength: 30, RepairCost: 4389, MarketCategory: "necklace", CraftType: 3 }, "smamul14": { Strength: 30, RepairCost: 4370, MarketCategory: "necklace", CraftType: 3 }, "verve_ring": { Strength: 18, RepairCost: 1577, MarketCategory: "ring", CraftType: 3 }, "dring9": { Strength: 50, RepairCost: 10032, MarketCategory: "ring", CraftType: 3 }, "smring17": { Strength: 30, RepairCost: 2907, MarketCategory: "ring", CraftType: 3 }, "magring13": { Strength: 60, RepairCost: 10279, MarketCategory: "ring", CraftType: 3 }, "scloack16": { Strength: 30, RepairCost: 3192, MarketCategory: "cloack", CraftType: 3 }, "powercape": { Strength: 40, RepairCost: 5339, MarketCategory: "cloack", CraftType: 3 }, "scoutcloack": { Strength: 20, RepairCost: 304, MarketCategory: "cloack", CraftType: 3 }, "energy_scroll": { Strength: 70, RepairCost: 9044, MarketCategory: "weapon", CraftType: 3 }, "samul8": { Strength: 30, RepairCost: 3391, MarketCategory: "necklace", CraftType: 3 }, "sring10": { Strength: 30, RepairCost: 2859, MarketCategory: "ring", CraftType: 3 }, "antiair_cape": { Strength: 60, RepairCost: 2926, MarketCategory: "cloack", CraftType: 3 }, "antimagic_cape": { Strength: 50, RepairCost: 4949, MarketCategory: "cloack", CraftType: 3 }, "d_spray": { Strength: 15, RepairCost: 3325, MarketCategory: "no_sell", CraftType: 3 }, "bfly": { Strength: 50, RepairCost: 49875, MarketCategory: "no_sell", CraftType: 3 }, "bril_pendant": { Strength: 50, RepairCost: 23275, MarketCategory: "no_sell", CraftType: 3 }, "warmor": { Strength: 50, RepairCost: 16625, MarketCategory: "no_sell", CraftType: 2 }, "flowers3": { Strength: 15, RepairCost: 3325, MarketCategory: "no_sell", CraftType: 3 }, "flowers1": { Strength: 10, RepairCost: 332, MarketCategory: "no_sell", CraftType: 3 }, "flowers4": { Strength: 25, RepairCost: 4987, MarketCategory: "no_sell", CraftType: 3 }, "flowers2": { Strength: 10, RepairCost: 332, MarketCategory: "no_sell", CraftType: 3 }, "roses": { Strength: 40, RepairCost: 8312, MarketCategory: "no_sell", CraftType: 3 }, "flowers5": { Strength: 25, RepairCost: 4987, MarketCategory: "no_sell", CraftType: 3 }, "half_heart_m": { Strength: 25, RepairCost: 4987, MarketCategory: "no_sell", CraftType: 3 }, "half_heart_w": { Strength: 25, RepairCost: 4987, MarketCategory: "no_sell", CraftType: 3 }, "venok": { Strength: 10, RepairCost: 332, MarketCategory: "no_sell", CraftType: 2 }, "defender_dagger": { Strength: 15, RepairCost: 1330, MarketCategory: "no_sell", CraftType: 2 }, "goldciras": { Strength: 50, RepairCost: 13300, MarketCategory: "no_sell", CraftType: 2 }, "koltsou": { Strength: 40, RepairCost: 23275, MarketCategory: "no_sell", CraftType: 3 }, "bril_ring": { Strength: 40, RepairCost: 33250, MarketCategory: "no_sell", CraftType: 3 }, "wboots": { Strength: 50, RepairCost: 16625, MarketCategory: "no_sell", CraftType: 2 }, "flower_heart": { Strength: 20, RepairCost: 1662, MarketCategory: "no_sell", CraftType: 3 }, "protazan": { Strength: 40, RepairCost: 8312, MarketCategory: "no_sell", CraftType: 1 }, "whelmet": { Strength: 50, RepairCost: 16625, MarketCategory: "no_sell", CraftType: 2 }, "shpaga": { Strength: 60, RepairCost: 26600, MarketCategory: "no_sell", CraftType: 1 }, "coldamul": { Strength: 75, RepairCost: 11000, MarketCategory: "necklace", CraftType: 3 }, "sun_armor": { Strength: 85, RepairCost: 9500, MarketCategory: "cuirass", CraftType: 2 }, "super_dagger": { Strength: 75, RepairCost: 10400, MarketCategory: "weapon", CraftType: 1 }, "clover_amul": { Strength: 75, RepairCost: 11000, MarketCategory: "necklace", CraftType: 3 }, "ring2013": { Strength: 50, RepairCost: 800, MarketCategory: "ring", CraftType: 3 }, "sun_ring": { Strength: 75, RepairCost: 6400, MarketCategory: "ring", CraftType: 3 }, "coldring_n": { Strength: 75, RepairCost: 6400, MarketCategory: "ring", CraftType: 3 }, "lbow": { Strength: 85, RepairCost: 10100, MarketCategory: "weapon", CraftType: 1 }, "cold_sword2014": { Strength: 85, RepairCost: 17600, MarketCategory: "weapon", CraftType: 1 }, "finecl": { Strength: 80, RepairCost: 10000, MarketCategory: "cloack", CraftType: 3 }, "sun_boots": { Strength: 85, RepairCost: 8700, MarketCategory: "boots", CraftType: 2 }, "sun_helm": { Strength: 85, RepairCost: 7400, MarketCategory: "helm", CraftType: 2 }, "wshield": { Strength: 65, RepairCost: 4000, MarketCategory: "shield", CraftType: 2 }, "shield_14y": { Strength: 70, RepairCost: 14000, MarketCategory: "shield", CraftType: 2 }, "cold_shieldn": { Strength: 85, RepairCost: 10400, MarketCategory: "shield", CraftType: 2 }, "n_amul": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 3 }, "n_boots": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 2 }, "n_armor": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 2 }, "n_ringa": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 3 }, "n_ringd": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 3 }, "n_sword": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 1 }, "n_clk": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 3 }, "n_helmet": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 2 }, "n_shield": { Strength: 40, RepairCost: 2000, MarketCategory: "no_sell", CraftType: 2 }, "neut_amulet": { Strength: 20, RepairCost: 10000, MarketCategory: "necklace", CraftType: 3 }, "forest_armor": { Strength: 1, RepairCost: 10000, MarketCategory: "cuirass", CraftType: 2 }, "forest_dagger": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "forest_blade": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "neut_ring": { Strength: 1, RepairCost: 10000, MarketCategory: "ring", CraftType: 3 }, "les_cl": { Strength: 20, RepairCost: 10000, MarketCategory: "cloack", CraftType: 3 }, "forest_bow": { Strength: 20, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "forest_boots": { Strength: 1, RepairCost: 10000, MarketCategory: "boots", CraftType: 2 }, "forest_helm": { Strength: 1, RepairCost: 10000, MarketCategory: "helm", CraftType: 2 }, "shieldofforest": { Strength: 1, RepairCost: 10000, MarketCategory: "shield", CraftType: 2 }, "hunter_pendant1": { Strength: 10, RepairCost: 400, MarketCategory: "necklace", CraftType: 3 }, "hunter_bow1": { Strength: 10, RepairCost: 400, MarketCategory: "weapon", CraftType: 1 }, "hunter_gloves1": { Strength: 10, RepairCost: 400, MarketCategory: "other", CraftType: 3 }, "hunter_jacket1": { Strength: 10, RepairCost: 400, MarketCategory: "cuirass", CraftType: 2 }, "hunter_boots1": { Strength: 10, RepairCost: 400, MarketCategory: "boots", CraftType: 2 }, "hunter_sword1": { Strength: 10, RepairCost: 400, MarketCategory: "weapon", CraftType: 1 }, "hunter_hat1": { Strength: 10, RepairCost: 400, MarketCategory: "helm", CraftType: 2 }, "hunter_shield1": { Strength: 10, RepairCost: 400, MarketCategory: "shield", CraftType: 2 }, "hunter_amulet1": { Strength: 10, RepairCost: 800, MarketCategory: "necklace", CraftType: 3 }, "hunter_armor1": { Strength: 10, RepairCost: 800, MarketCategory: "cuirass", CraftType: 2 }, "hunterdagger": { Strength: 10, RepairCost: 800, MarketCategory: "weapon", CraftType: 1 }, "hunter_ring2": { Strength: 10, RepairCost: 800, MarketCategory: "ring", CraftType: 3 }, "hunter_ring1": { Strength: 10, RepairCost: 800, MarketCategory: "ring", CraftType: 3 }, "hunter_roga1": { Strength: 10, RepairCost: 800, MarketCategory: "helm", CraftType: 2 }, "huntersword2": { Strength: 10, RepairCost: 800, MarketCategory: "weapon", CraftType: 1 }, "hunter_boots3": { Strength: 10, RepairCost: 800, MarketCategory: "boots", CraftType: 2 }, "hunter_bow2": { Strength: 10, RepairCost: 800, MarketCategory: "weapon", CraftType: 1 }, "hunter_mask1": { Strength: 10, RepairCost: 800, MarketCategory: "cloack", CraftType: 3 }, "hunterdsword": { Strength: 10, RepairCost: 800, MarketCategory: "weapon", CraftType: 1 }, "hunter_boots2": { Strength: 10, RepairCost: 800, MarketCategory: "boots", CraftType: 2 }, "hunter_arrows1": { Strength: 10, RepairCost: 800, MarketCategory: "other", CraftType: 1 }, "hunter_helm": { Strength: 10, RepairCost: 800, MarketCategory: "helm", CraftType: 2 }, "huntershield2": { Strength: 10, RepairCost: 800, MarketCategory: "shield", CraftType: 2 }, "gm_amul": { Strength: 10, RepairCost: 1200, MarketCategory: "necklace", CraftType: 3 }, "gm_arm": { Strength: 10, RepairCost: 1200, MarketCategory: "cuirass", CraftType: 2 }, "gm_rring": { Strength: 10, RepairCost: 1200, MarketCategory: "ring", CraftType: 3 }, "gm_kastet": { Strength: 10, RepairCost: 1200, MarketCategory: "weapon", CraftType: 1 }, "gm_sring": { Strength: 10, RepairCost: 1200, MarketCategory: "ring", CraftType: 3 }, "gm_abow": { Strength: 10, RepairCost: 1200, MarketCategory: "weapon", CraftType: 1 }, "gm_protect": { Strength: 10, RepairCost: 1200, MarketCategory: "cloack", CraftType: 3 }, "gm_sword": { Strength: 10, RepairCost: 1200, MarketCategory: "weapon", CraftType: 1 }, "gm_spdb": { Strength: 10, RepairCost: 1200, MarketCategory: "boots", CraftType: 2 }, "gm_3arrows": { Strength: 10, RepairCost: 1200, MarketCategory: "other", CraftType: 1 }, "gm_hat": { Strength: 10, RepairCost: 1200, MarketCategory: "helm", CraftType: 2 }, "gm_defence": { Strength: 10, RepairCost: 1200, MarketCategory: "shield", CraftType: 2 }, "sh_amulet2": { Strength: 15, RepairCost: 2400, MarketCategory: "necklace", CraftType: 3 }, "sh_armor": { Strength: 15, RepairCost: 2400, MarketCategory: "cuirass", CraftType: 2 }, "sh_ring1": { Strength: 15, RepairCost: 2400, MarketCategory: "ring", CraftType: 3 }, "sh_ring2": { Strength: 15, RepairCost: 2400, MarketCategory: "ring", CraftType: 3 }, "sh_spear": { Strength: 15, RepairCost: 2400, MarketCategory: "weapon", CraftType: 1 }, "sh_bow": { Strength: 15, RepairCost: 2400, MarketCategory: "weapon", CraftType: 1 }, "sh_cloak": { Strength: 15, RepairCost: 2400, MarketCategory: "cloack", CraftType: 3 }, "sh_sword": { Strength: 15, RepairCost: 2400, MarketCategory: "weapon", CraftType: 1 }, "sh_boots": { Strength: 15, RepairCost: 2400, MarketCategory: "boots", CraftType: 2 }, "sh_4arrows": { Strength: 15, RepairCost: 2400, MarketCategory: "other", CraftType: 1 }, "sh_helmet": { Strength: 15, RepairCost: 2400, MarketCategory: "helm", CraftType: 2 }, "sh_shield": { Strength: 15, RepairCost: 2400, MarketCategory: "shield", CraftType: 2 }, "thief_neckl": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 3 }, "thief_arb": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 1 }, "thief_goodarmor": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 2 }, "thief_ml_dagger": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 1 }, "ring_of_thief": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 3 }, "thief_msk": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 2 }, "thief_cape": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 3 }, "thief_fastboots": { Strength: 60, RepairCost: 8000, MarketCategory: "thief", CraftType: 2 }, "tm_amulet": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 3 }, "tm_arb": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 1 }, "tm_armor": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 2 }, "tm_knife": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 1 }, "tm_mring": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 3 }, "tm_wring": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 3 }, "tm_msk": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 2 }, "tm_cape": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 3 }, "tm_boots": { Strength: 60, RepairCost: 24000, MarketCategory: "thief", CraftType: 2 }, "r_warriorsamulet": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 3 }, "r_m_amulet": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 3 }, "r_zarmor": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 2 }, "r_dagger": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 1 }, "r_magicsring": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 3 }, "r_warring": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 3 }, "r_bow": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 1 }, "r_bigsword": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 1 }, "r_clck": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 3 }, "r_magy_staff": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 1 }, "r_bootsmb": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 2 }, "r_goodscroll": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 3 }, "r_helmb": { Strength: 70, RepairCost: 36000, MarketCategory: "relict", CraftType: 2 }, "tact1w1_wamulet": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 3 }, "tactcv1_armor": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 2 }, "tactsm0_dagger": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 1 }, "tactspw_mring": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 3 }, "tactwww_wring": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 3 }, "tact765_bow": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 1 }, "tactms1_mamulet": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 3 }, "tactpow_cloack": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 3 }, "tactmag_staff": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 1 }, "tactzl4_boots": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 2 }, "tactaz_axe": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 1 }, "tacthapp_helmet": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 2 }, "tactdff_shield": { Strength: 75, RepairCost: 40000, MarketCategory: "tactic", CraftType: 2 }, "v_1armor": { Strength: 90, RepairCost: 48000, MarketCategory: "verb", CraftType: 2 }, "verb11_sword": { Strength: 90, RepairCost: 48000, MarketCategory: "verb", CraftType: 1 }, "verbboots": { Strength: 90, RepairCost: 48000, MarketCategory: "verb", CraftType: 2 }, "ve_helm": { Strength: 90, RepairCost: 48000, MarketCategory: "verb", CraftType: 2 }, "vrb_shild": { Strength: 90, RepairCost: 48000, MarketCategory: "verb", CraftType: 2 }, "tl_medal1": { Strength: 50, RepairCost: 32000, MarketCategory: "medals", CraftType: 3 }, "tl_medal2": { Strength: 40, RepairCost: 16000, MarketCategory: "medals", CraftType: 3 }, "tl_medal3": { Strength: 30, RepairCost: 6000, MarketCategory: "medals", CraftType: 3 }, "bwar1": { Strength: 1, RepairCost: 60000, MarketCategory: "medals", CraftType: 3 }, "kwar1": { Strength: 1, RepairCost: 60000, MarketCategory: "medals", CraftType: 3 }, "gnomewar1": { Strength: 70, RepairCost: 60000, MarketCategory: "medals", CraftType: 3 }, "bwar2": { Strength: 1, RepairCost: 48000, MarketCategory: "medals", CraftType: 3 }, "kwar2": { Strength: 1, RepairCost: 48000, MarketCategory: "medals", CraftType: 3 }, "gnomewar2": { Strength: 65, RepairCost: 48000, MarketCategory: "medals", CraftType: 3 }, "kwar3": { Strength: 1, RepairCost: 36000, MarketCategory: "medals", CraftType: 3 }, "gnomewar3": { Strength: 60, RepairCost: 36000, MarketCategory: "medals", CraftType: 3 }, "bwar3": { Strength: 1, RepairCost: 36000, MarketCategory: "medals", CraftType: 3 }, "bwar4": { Strength: 1, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "kwar4": { Strength: 1, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "gnomewar4": { Strength: 55, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "bwar5": { Strength: 1, RepairCost: 20000, MarketCategory: "medals", CraftType: 3 }, "kwar5": { Strength: 1, RepairCost: 20000, MarketCategory: "medals", CraftType: 3 }, "gnomewar5": { Strength: 50, RepairCost: 20000, MarketCategory: "medals", CraftType: 3 }, "bwar6": { Strength: 1, RepairCost: 16000, MarketCategory: "medals", CraftType: 3 }, "kwar6": { Strength: 1, RepairCost: 16000, MarketCategory: "medals", CraftType: 3 }, "gnomewar6": { Strength: 45, RepairCost: 16000, MarketCategory: "medals", CraftType: 3 }, "bwar7": { Strength: 1, RepairCost: 12000, MarketCategory: "medals", CraftType: 3 }, "kwar7": { Strength: 1, RepairCost: 12000, MarketCategory: "medals", CraftType: 3 }, "gnomewar7": { Strength: 40, RepairCost: 12000, MarketCategory: "medals", CraftType: 3 }, "bunt_medal1": { Strength: 60, RepairCost: 40000, MarketCategory: "medals", CraftType: 3 }, "bunt_medal2": { Strength: 50, RepairCost: 20000, MarketCategory: "medals", CraftType: 3 }, "bunt_medal3": { Strength: 40, RepairCost: 10000, MarketCategory: "medals", CraftType: 3 }, "bwar_splo": { Strength: 50, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "gnomewar_splo": { Strength: 50, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "kwar_splo": { Strength: 50, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "kwar_stoj": { Strength: 25, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "bwar_stoj": { Strength: 30, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "gnomewar_stoj": { Strength: 50, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "bwar_takt": { Strength: 50, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "gnomewar_takt": { Strength: 50, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "kwar_takt": { Strength: 50, RepairCost: 28000, MarketCategory: "medals", CraftType: 3 }, "necrwar1st": { Strength: 70, RepairCost: 56000, MarketCategory: "medals", CraftType: 3 }, "necrwar2st": { Strength: 60, RepairCost: 36000, MarketCategory: "medals", CraftType: 3 }, "necrwar3st": { Strength: 50, RepairCost: 20000, MarketCategory: "medals", CraftType: 3 }, "necrwar4st": { Strength: 40, RepairCost: 10000, MarketCategory: "medals", CraftType: 3 }, "necrwar5st": { Strength: 30, RepairCost: 4000, MarketCategory: "medals", CraftType: 3 }, "warthief_medal1": { Strength: 70, RepairCost: 18000, MarketCategory: "medals", CraftType: 3 }, "warthief_medal2": { Strength: 60, RepairCost: 14000, MarketCategory: "medals", CraftType: 3 }, "warthief_medal3": { Strength: 50, RepairCost: 10000, MarketCategory: "medals", CraftType: 3 }, "warthief_medal4": { Strength: 40, RepairCost: 6000, MarketCategory: "medals", CraftType: 3 }, "warthief_medal5": { Strength: 30, RepairCost: 2000, MarketCategory: "medals", CraftType: 3 }, "elfwar1": { Strength: 80, RepairCost: 60000, MarketCategory: "medals", CraftType: 3 }, "elfwar2": { Strength: 70, RepairCost: 40000, MarketCategory: "medals", CraftType: 3 }, "elfwar3": { Strength: 60, RepairCost: 32000, MarketCategory: "medals", CraftType: 3 }, "elfwar4": { Strength: 50, RepairCost: 20000, MarketCategory: "medals", CraftType: 3 }, "elfwar5": { Strength: 40, RepairCost: 10000, MarketCategory: "medals", CraftType: 3 }, "elfwar6": { Strength: 30, RepairCost: 4000, MarketCategory: "medals", CraftType: 3 }, "magewar1": { Strength: 80, RepairCost: 52000, MarketCategory: "medals", CraftType: 3 }, "magewar2": { Strength: 70, RepairCost: 40000, MarketCategory: "medals", CraftType: 3 }, "magewar3": { Strength: 60, RepairCost: 32000, MarketCategory: "medals", CraftType: 3 }, "magewar4": { Strength: 50, RepairCost: 20000, MarketCategory: "medals", CraftType: 3 }, "magewar5": { Strength: 35, RepairCost: 12000, MarketCategory: "medals", CraftType: 3 }, "demwar1": { Strength: 80, RepairCost: 60000, MarketCategory: "medals", CraftType: 3 }, "demwar2": { Strength: 70, RepairCost: 44000, MarketCategory: "medals", CraftType: 3 }, "demwar3": { Strength: 60, RepairCost: 36000, MarketCategory: "medals", CraftType: 3 }, "demwar4": { Strength: 50, RepairCost: 24000, MarketCategory: "medals", CraftType: 3 }, "demwar5": { Strength: 40, RepairCost: 16000, MarketCategory: "medals", CraftType: 3 }, "demwar6": { Strength: 30, RepairCost: 8000, MarketCategory: "medals", CraftType: 3 }, "barb_armor": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "barb_club": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 1 }, "barb_boots": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "barb_helm": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "barb_shield": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "necr_amulet": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 3 }, "necr_helm": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "necr_staff": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 1 }, "necr_robe": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "merc_armor": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "merc_dagger": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 1 }, "merc_sword": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 1 }, "merc_boots": { Strength: 100, RepairCost: 40000, MarketCategory: "relict", CraftType: 2 }, "elfamulet": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 3 }, "elfbow": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 1 }, "elfshirt": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "elfboots": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "darkelfkaska": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "darkelfciras": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "darkelfpendant": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 3 }, "darkelfcloack": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 3 }, "darkelfstaff": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 1 }, "darkelfboots": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "dem_amulet": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 3 }, "dem_armor": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "dem_bootshields": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "dem_axe": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 1 }, "dem_helmet": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "dem_shield": { Strength: 100, RepairCost: 50000, MarketCategory: "relict", CraftType: 2 }, "mage_cape": { Strength: 100, RepairCost: 60000, MarketCategory: "relict", CraftType: 3 }, "mage_staff": { Strength: 100, RepairCost: 60000, MarketCategory: "relict", CraftType: 1 }, "mage_robe": { Strength: 100, RepairCost: 60000, MarketCategory: "relict", CraftType: 2 }, "mage_boots": { Strength: 100, RepairCost: 60000, MarketCategory: "relict", CraftType: 2 }, "mage_scroll": { Strength: 100, RepairCost: 60000, MarketCategory: "relict", CraftType: 3 }, "mage_hat": { Strength: 100, RepairCost: 60000, MarketCategory: "relict", CraftType: 2 }, "gnomearmor": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "gnomehammer": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 1 }, "gnomeboots": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "gnomehelmet": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "gnomeshield": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "gnomem_amulet": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "gnomem_armor": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "gnomem_hammer": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "gnomem_boots": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "gnomem_helmet": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "gnomem_shield": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "gmage_crown": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "gmage_cloack": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "gmage_staff": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "gmage_armor": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "gmage_boots": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "gmage_scroll": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "welfarmor": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "welfbow": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 1 }, "welfsword": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 1 }, "welfboots": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "welfhelmet": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "welfshield": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "druid_amulet": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "druid_cloack": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "druid_staff": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "druid_armor": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "druid_boots": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "knightarmor": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "knightsword": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 1 }, "knightboots": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "knighthelmet": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "knightshield": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "paladin_bow": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "paladin_armor": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "paladin_sword": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "paladin_boots": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "paladin_helmet": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "paladin_shield": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "sv_arb": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "sv_body": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "sv_weap": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "sv_boot": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "sv_helm": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "sv_shield": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "nv_body": { Strength: 100, RepairCost: 56000, MarketCategory: "relict", CraftType: 2 }, "nv_weap": { Strength: 100, RepairCost: 56000, MarketCategory: "relict", CraftType: 1 }, "nv_boot": { Strength: 100, RepairCost: 56000, MarketCategory: "relict", CraftType: 2 }, "nv_helm": { Strength: 100, RepairCost: 56000, MarketCategory: "relict", CraftType: 2 }, "nv_shield": { Strength: 100, RepairCost: 56000, MarketCategory: "relict", CraftType: 2 }, "kn_body": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "kn_weap": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 1 }, "kn_helm": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "kn_shield": { Strength: 100, RepairCost: 44000, MarketCategory: "relict", CraftType: 2 }, "inq_body": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "inq_cl": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "inq_weap": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "inq_boot": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "inq_helm": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "amf_body": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "amf_cl": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "amf_boot": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "amf_weap": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 1 }, "amf_scroll": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 3 }, "amf_helm": { Strength: 100, RepairCost: 64000, MarketCategory: "relict", CraftType: 2 }, "8amul_inf": { Strength: 8, RepairCost: 12000, MarketCategory: "necklace", CraftType: 3 }, "quest_pendant1": { Strength: 20, RepairCost: 600, MarketCategory: "necklace", CraftType: 3 }, "9amu_let": { Strength: 9, RepairCost: 18000, MarketCategory: "necklace", CraftType: 3 }, "trinitypendant": { Strength: 50, RepairCost: 6400, MarketCategory: "necklace", CraftType: 3 }, "sunart2": { Strength: 20, RepairCost: 28000, MarketCategory: "weapon", CraftType: 1 }, "a_mallet": { Strength: 10000, RepairCost: 40, MarketCategory: "weapon", CraftType: 1 }, "buben2": { Strength: 1, RepairCost: 12800, MarketCategory: "weapon", CraftType: 1 }, "totem1": { Strength: 70, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "icesphere1": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "mechanic_glasses1": { Strength: 1, RepairCost: 8000, MarketCategory: "helm", CraftType: 2 }, "buben1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "anomal_ring1": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "mart8_ring1": { Strength: 8, RepairCost: 400, MarketCategory: "relict", CraftType: 3 }, "mart8_flowers1": { Strength: 8, RepairCost: 8000, MarketCategory: "relict", CraftType: 3 }, "wolfjacket": { Strength: 15, RepairCost: 800, MarketCategory: "cuirass", CraftType: 2 }, "sharik": { Strength: 1, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "thief_paper": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "magneticarmor": { Strength: 1, RepairCost: 36000, MarketCategory: "cuirass", CraftType: 2 }, "dragonstone": { Strength: 70, RepairCost: 12000, MarketCategory: "backpack", CraftType: 0 }, "dubina": { Strength: 30, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "ogre_bum": { Strength: 1, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "gdubina": { Strength: 30, RepairCost: 14000, MarketCategory: "weapon", CraftType: 1 }, "lizard_armor": { Strength: 15, RepairCost: 800, MarketCategory: "cuirass", CraftType: 2 }, "hopesh1": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "mgear": { Strength: 1, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "5years_star": { Strength: 10, RepairCost: 5000, MarketCategory: "necklace", CraftType: 3 }, "mirror": { Strength: 1, RepairCost: 16000, MarketCategory: "other", CraftType: 0 }, "znamya1": { Strength: 70, RepairCost: 8000, MarketCategory: "no_sell", CraftType: 0 }, "krest2": { Strength: 1, RepairCost: 9000, MarketCategory: "backpack", CraftType: 0 }, "znamya2": { Strength: 70, RepairCost: 8000, MarketCategory: "no_sell", CraftType: 0 }, "kznamya1": { Strength: 70, RepairCost: 10000, MarketCategory: "no_sell", CraftType: 0 }, "kznamya2": { Strength: 70, RepairCost: 10000, MarketCategory: "no_sell", CraftType: 0 }, "ankh1": { Strength: 70, RepairCost: 12000, MarketCategory: "backpack", CraftType: 0 }, "zub": { Strength: 30, RepairCost: 40000, MarketCategory: "necklace", CraftType: 3 }, "tunnel_kirka": { Strength: 25, RepairCost: 4000, MarketCategory: "weapon", CraftType: 1 }, "bludgeon": { Strength: 30, RepairCost: 28000, MarketCategory: "weapon", CraftType: 1 }, "brush": { Strength: 70, RepairCost: 19824, MarketCategory: "no_sell", CraftType: 1 }, "windsword": { Strength: 1, RepairCost: 22000, MarketCategory: "weapon", CraftType: 1 }, "pit_sword1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "pit_sword2": { Strength: 1, RepairCost: 13200, MarketCategory: "weapon", CraftType: 1 }, "kniga": { Strength: 40, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "skill_book11": { Strength: 1, RepairCost: 40000, MarketCategory: "backpack", CraftType: 0 }, "anomal_ring2": { Strength: 1, RepairCost: 18000, MarketCategory: "ring", CraftType: 3 }, "commander_ring": { Strength: 70, RepairCost: 20000, MarketCategory: "relict", CraftType: 3 }, "testring": { Strength: 30, RepairCost: 40000, MarketCategory: "relict", CraftType: 3 }, "thief_premiumring1": { Strength: 70, RepairCost: 24000, MarketCategory: "thief", CraftType: 3 }, "thief_premiumring2": { Strength: 65, RepairCost: 18000, MarketCategory: "thief", CraftType: 3 }, "thief_premiumring3": { Strength: 60, RepairCost: 12000, MarketCategory: "thief", CraftType: 3 }, "ttring": { Strength: 1, RepairCost: 10800, MarketCategory: "ring", CraftType: 3 }, "blackring": { Strength: 40, RepairCost: 8000, MarketCategory: "ring", CraftType: 3 }, "student_armor": { Strength: 30, RepairCost: 2000, MarketCategory: "cuirass", CraftType: 2 }, "pegaskop": { Strength: 1, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "sunart1": { Strength: 20, RepairCost: 14000, MarketCategory: "weapon", CraftType: 1 }, "kopie": { Strength: 30, RepairCost: 28000, MarketCategory: "weapon", CraftType: 1 }, "pika": { Strength: 30, RepairCost: 28000, MarketCategory: "weapon", CraftType: 1 }, "trogloditkop": { Strength: 1, RepairCost: 5600, MarketCategory: "weapon", CraftType: 1 }, "dragon_crown": { Strength: 50, RepairCost: 6800, MarketCategory: "helm", CraftType: 2 }, "necrohelm2": { Strength: 10, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "dem_kosa": { Strength: 30, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "pouch": { Strength: 70, RepairCost: 12000, MarketCategory: "backpack", CraftType: 0 }, "cubed": { Strength: 45, RepairCost: 4800, MarketCategory: "backpack", CraftType: 0 }, "bal_cube": { Strength: 45, RepairCost: 4800, MarketCategory: "backpack", CraftType: 0 }, "cubes": { Strength: 50, RepairCost: 6400, MarketCategory: "backpack", CraftType: 0 }, "cubeg": { Strength: 60, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "bshield3": { Strength: 1, RepairCost: 8000, MarketCategory: "shield", CraftType: 2 }, "icesphere2": { Strength: 1, RepairCost: 14400, MarketCategory: "backpack", CraftType: 0 }, "goblin_bow": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "centaurbow": { Strength: 30, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "sniperbow": { Strength: 1, RepairCost: 36000, MarketCategory: "relict", CraftType: 1 }, "totem3": { Strength: 70, RepairCost: 8400, MarketCategory: "backpack", CraftType: 0 }, "10scroll": { Strength: 1, RepairCost: 40000, MarketCategory: "backpack", CraftType: 0 }, "sunart3": { Strength: 20, RepairCost: 32000, MarketCategory: "weapon", CraftType: 1 }, "sword5": { Strength: 30, RepairCost: 4000, MarketCategory: "no_sell", CraftType: 1 }, "blacksword": { Strength: 10, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "sunart4": { Strength: 20, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "dem_dmech": { Strength: 30, RepairCost: 14000, MarketCategory: "weapon", CraftType: 1 }, "blacksword1": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "slayersword": { Strength: 30, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "meshok": { Strength: 2012, RepairCost: 2012, MarketCategory: "no_sell", CraftType: 0 }, "meshok2": { Strength: 2012, RepairCost: 2012, MarketCategory: "no_sell", CraftType: 0 }, "molot_tan": { Strength: 30, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "13coin": { Strength: 1, RepairCost: 40000, MarketCategory: "backpack", CraftType: 0 }, "snowjinka": { Strength: 40, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "sosulka": { Strength: 40, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "obereg": { Strength: 50, RepairCost: 20000, MarketCategory: "backpack", CraftType: 0 }, "castle_orden": { Strength: 60, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "order_griffin": { Strength: 70, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "order_manticore": { Strength: 70, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "eg_order1": { Strength: 1, RepairCost: 22000, MarketCategory: "necklace", CraftType: 3 }, "eg_order2": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "eg_order3": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "ord_light": { Strength: 75, RepairCost: 18000, MarketCategory: "necklace", CraftType: 3 }, "ord_dark": { Strength: 75, RepairCost: 18000, MarketCategory: "necklace", CraftType: 3 }, "mechanic_glasses2": { Strength: 1, RepairCost: 7400, MarketCategory: "helm", CraftType: 2 }, "pen": { Strength: 70, RepairCost: 19824, MarketCategory: "no_sell", CraftType: 1 }, "sandglass": { Strength: 70, RepairCost: 12000, MarketCategory: "backpack", CraftType: 0 }, "inq_ring1": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "battlem_cape": { Strength: 1, RepairCost: 28000, MarketCategory: "cloack", CraftType: 3 }, "stalkercl": { Strength: 1, RepairCost: 8000, MarketCategory: "cloack", CraftType: 3 }, "totem2": { Strength: 70, RepairCost: 9000, MarketCategory: "backpack", CraftType: 0 }, "2year_amul_lords": { Strength: 10, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "7ka": { Strength: 10, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "3year_amul": { Strength: 10, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "icesphere3": { Strength: 1, RepairCost: 12800, MarketCategory: "backpack", CraftType: 0 }, "inq_ring2": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "krest3": { Strength: 1, RepairCost: 8400, MarketCategory: "backpack", CraftType: 0 }, "anomal_ring3": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "buben3": { Strength: 1, RepairCost: 9600, MarketCategory: "weapon", CraftType: 1 }, "mechanic_glasses3": { Strength: 1, RepairCost: 6800, MarketCategory: "helm", CraftType: 2 }, "rog_demon": { Strength: 30, RepairCost: 40000, MarketCategory: "necklace", CraftType: 3 }, "runkam": { Strength: 50, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "lizard_boots": { Strength: 15, RepairCost: 800, MarketCategory: "boots", CraftType: 2 }, "torg_boots": { Strength: 1, RepairCost: 20000, MarketCategory: "boots", CraftType: 2 }, "krest1": { Strength: 1, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "thief_unique_secretops": { Strength: 200, RepairCost: 0, MarketCategory: "no_sell", CraftType: 1 }, "ankh2": { Strength: 70, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "compass": { Strength: 40, RepairCost: 8000, MarketCategory: "other", CraftType: 3 }, "statue": { Strength: 70, RepairCost: 12000, MarketCategory: "no_sell", CraftType: 0 }, "nefrit2": { Strength: 1, RepairCost: 9000, MarketCategory: "backpack", CraftType: 0 }, "nefrit3": { Strength: 1, RepairCost: 8400, MarketCategory: "backpack", CraftType: 0 }, "nefrit1": { Strength: 1, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "cat_statue": { Strength: 70, RepairCost: 8000, MarketCategory: "backpack", CraftType: 0 }, "bear_statue": { Strength: 70, RepairCost: 8000, MarketCategory: "backpack", CraftType: 0 }, "ru_statue": { Strength: 20, RepairCost: 2009, MarketCategory: "shield", CraftType: 3 }, "dog_statue": { Strength: 70, RepairCost: 8000, MarketCategory: "backpack", CraftType: 0 }, "msphere": { Strength: 60, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "3year_art": { Strength: 10, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "znak5": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak8": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak7": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak3": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak2": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak1": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak6": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak9": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "znak4": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "firehammer": { Strength: 1, RepairCost: 32000, MarketCategory: "weapon", CraftType: 1 }, "topor_drov": { Strength: 40, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "dem_dtopor": { Strength: 30, RepairCost: 48000, MarketCategory: "weapon", CraftType: 1 }, "taskaxe": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "orc_axe": { Strength: 1, RepairCost: 28000, MarketCategory: "weapon", CraftType: 1 }, "topor_skelet": { Strength: 30, RepairCost: 14000, MarketCategory: "weapon", CraftType: 1 }, "sea_trident": { Strength: 15, RepairCost: 4000, MarketCategory: "weapon", CraftType: 1 }, "bshield1": { Strength: 1, RepairCost: 16000, MarketCategory: "shield", CraftType: 2 }, "dudka": { Strength: 1, RepairCost: 6000, MarketCategory: "necklace", CraftType: 3 }, "flyaga": { Strength: 1, RepairCost: 60000, MarketCategory: "backpack", CraftType: 0 }, "antifire_cape": { Strength: 40, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "hopesh2": { Strength: 1, RepairCost: 7200, MarketCategory: "weapon", CraftType: 1 }, "12hron": { Strength: 1, RepairCost: 40000, MarketCategory: "backpack", CraftType: 0 }, "4year_klever": { Strength: 10, RepairCost: 4000, MarketCategory: "necklace", CraftType: 3 }, "6ring": { Strength: 10, RepairCost: 15000, MarketCategory: "ring", CraftType: 3 }, "lizard_helm": { Strength: 15, RepairCost: 800, MarketCategory: "helm", CraftType: 2 }, "ogre_helm": { Strength: 1, RepairCost: 24000, MarketCategory: "helm", CraftType: 2 }, "orc_hat": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "necrohelm3": { Strength: 10, RepairCost: 24000, MarketCategory: "helm", CraftType: 2 }, "necrohelm1": { Strength: 10, RepairCost: 10000, MarketCategory: "helm", CraftType: 2 }, "gargoshield": { Strength: 1, RepairCost: 16000, MarketCategory: "shield", CraftType: 2 }, "bshield2": { Strength: 1, RepairCost: 12000, MarketCategory: "shield", CraftType: 2 }, "e_shield2": { Strength: 1, RepairCost: 7200, MarketCategory: "shield", CraftType: 2 }, "e_shield1": { Strength: 1, RepairCost: 10000, MarketCategory: "shield", CraftType: 2 }, "elfdagger": { Strength: 1, RepairCost: 36000, MarketCategory: "relict", CraftType: 1 }, "dun_amul2": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "dun_bow2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "drak_armor1": { Strength: 1, RepairCost: 20000, MarketCategory: "cuirass", CraftType: 2 }, "dun_boots1": { Strength: 1, RepairCost: 20000, MarketCategory: "boots", CraftType: 2 }, "dun_amul1": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "dun_bow1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "dun_armor1": { Strength: 1, RepairCost: 20000, MarketCategory: "cuirass", CraftType: 2 }, "dun_dagger1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "dun_sword1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "dun_ring1": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "dun_cloak1": { Strength: 1, RepairCost: 18000, MarketCategory: "cloack", CraftType: 3 }, "dung_axe1": { Strength: 1, RepairCost: 18000, MarketCategory: "weapon", CraftType: 1 }, "hm2": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "dun_shield1": { Strength: 1, RepairCost: 20000, MarketCategory: "shield", CraftType: 2 }, "dun_armor2": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "dun_dagger2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "dering": { Strength: 1, RepairCost: 24000, MarketCategory: "relict", CraftType: 3 }, "drak_armor2": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "dun_boots3": { Strength: 1, RepairCost: 12000, MarketCategory: "boots", CraftType: 2 }, "dun_armor3": { Strength: 1, RepairCost: 12000, MarketCategory: "cuirass", CraftType: 2 }, "dun_shield3": { Strength: 1, RepairCost: 12000, MarketCategory: "helm", CraftType: 2 }, "drak_armor3": { Strength: 1, RepairCost: 12000, MarketCategory: "cuirass", CraftType: 2 }, "dun_bow3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "dun_dagger3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "dun_sword3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "dung_axe3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "dun_sword2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "dun_ring2": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "dun_cloak2": { Strength: 1, RepairCost: 15000, MarketCategory: "cloack", CraftType: 3 }, "crystal": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "dun_amul3": { Strength: 1, RepairCost: 12000, MarketCategory: "necklace", CraftType: 3 }, "dun_cloak3": { Strength: 1, RepairCost: 12000, MarketCategory: "cloack", CraftType: 3 }, "dun_ring3": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "dun_boots2": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "dung_axe2": { Strength: 1, RepairCost: 15000, MarketCategory: "weapon", CraftType: 1 }, "hm1": { Strength: 1, RepairCost: 14400, MarketCategory: "helm", CraftType: 2 }, "dun_shield2": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "ramul1": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "rarmor1": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "rdagger1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "rogring1": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "rarmor2": { Strength: 1, RepairCost: 8000, MarketCategory: "cuirass", CraftType: 2 }, "rboots2": { Strength: 1, RepairCost: 8000, MarketCategory: "boots", CraftType: 2 }, "rhelm2": { Strength: 1, RepairCost: 8000, MarketCategory: "helm", CraftType: 2 }, "rsword2": { Strength: 1, RepairCost: 8000, MarketCategory: "weapon", CraftType: 1 }, "raxe2": { Strength: 1, RepairCost: 8000, MarketCategory: "weapon", CraftType: 1 }, "rbow1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "rsword1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "rcloak1": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "rogring2": { Strength: 1, RepairCost: 8000, MarketCategory: "ring", CraftType: 3 }, "ramul2": { Strength: 1, RepairCost: 8000, MarketCategory: "necklace", CraftType: 3 }, "rdagger2": { Strength: 1, RepairCost: 8000, MarketCategory: "weapon", CraftType: 1 }, "rbow2": { Strength: 1, RepairCost: 8000, MarketCategory: "weapon", CraftType: 1 }, "rcloak2": { Strength: 1, RepairCost: 8000, MarketCategory: "cloack", CraftType: 3 }, "rshield2": { Strength: 1, RepairCost: 8000, MarketCategory: "shield", CraftType: 2 }, "rboots1": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "sumka": { Strength: 1, RepairCost: 12000, MarketCategory: "backpack", CraftType: 0 }, "raxe1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "rhelm1": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "rshield1": { Strength: 1, RepairCost: 16000, MarketCategory: "shield", CraftType: 2 }, "surv_halberdzg": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 1 }, "surv_wamuletik": { Strength: 1, RepairCost: 28000, MarketCategory: "necklace", CraftType: 3 }, "surv_crossbowsurv": { Strength: 1, RepairCost: 32000, MarketCategory: "weapon", CraftType: 1 }, "surv_armorsu": { Strength: 1, RepairCost: 28000, MarketCategory: "cuirass", CraftType: 2 }, "surv_wring2o": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "surv_daggermd": { Strength: 1, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "surv_sword2sd": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "surv_mring2fpg": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "surv_wring1my": { Strength: 1, RepairCost: 28000, MarketCategory: "ring", CraftType: 3 }, "surv_mbootsbb": { Strength: 1, RepairCost: 28000, MarketCategory: "boots", CraftType: 2 }, "surv_mamulka": { Strength: 1, RepairCost: 28000, MarketCategory: "necklace", CraftType: 3 }, "surv_marmoroz": { Strength: 1, RepairCost: 28000, MarketCategory: "cuirass", CraftType: 2 }, "surv_mhelmetcv": { Strength: 1, RepairCost: 28000, MarketCategory: "helm", CraftType: 2 }, "surv_mring1fd": { Strength: 1, RepairCost: 28000, MarketCategory: "ring", CraftType: 3 }, "surv_mcloacksv": { Strength: 1, RepairCost: 28000, MarketCategory: "cloack", CraftType: 3 }, "surv_sword_surv": { Strength: 1, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "surv_cloacksrv": { Strength: 1, RepairCost: 28000, MarketCategory: "cloack", CraftType: 3 }, "surv_staffik": { Strength: 1, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "surv_bootsurv": { Strength: 1, RepairCost: 28000, MarketCategory: "boots", CraftType: 2 }, "surv_scrollcd": { Strength: 1, RepairCost: 28000, MarketCategory: "weapon", CraftType: 3 }, "surv_axes": { Strength: 1, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "surv_helmetpi": { Strength: 1, RepairCost: 28000, MarketCategory: "helm", CraftType: 2 }, "surv_shieldvv": { Strength: 1, RepairCost: 28000, MarketCategory: "shield", CraftType: 2 }, "tj_magam2": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "mtcloak1": { Strength: 1, RepairCost: 24000, MarketCategory: "cloack", CraftType: 3 }, "tmarmor1": { Strength: 1, RepairCost: 24000, MarketCategory: "cuirass", CraftType: 2 }, "sph1": { Strength: 1, RepairCost: 24000, MarketCategory: "backpack", CraftType: 0 }, "tj_mtuf1": { Strength: 1, RepairCost: 24000, MarketCategory: "boots", CraftType: 2 }, "vbow1": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 1 }, "mhelmv1": { Strength: 1, RepairCost: 24000, MarketCategory: "helm", CraftType: 2 }, "vtmsword1": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 1 }, "vtjcloak1": { Strength: 1, RepairCost: 24000, MarketCategory: "cloack", CraftType: 3 }, "staff_v1": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 1 }, "vscroll-1": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 3 }, "vtmaxe1": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 1 }, "vmring1": { Strength: 1, RepairCost: 24000, MarketCategory: "ring", CraftType: 3 }, "tjarmor2": { Strength: 1, RepairCost: 20000, MarketCategory: "cuirass", CraftType: 2 }, "vrdagger2": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "v-ring2": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "tjam2": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "mtcloak3": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "vtjcloak3": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "staff_v3": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "tmarmor3": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "tj_vboots3": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "tj_mtuf3": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "tjarmor3": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "vrdagger3": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "vbow3": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "mhelmv3": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "vtmsword3": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "vtmaxe3": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "tj_helmet3": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "tj-shield3": { Strength: 1, RepairCost: 16000, MarketCategory: "shield", CraftType: 2 }, "vbow2": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "mhelmv2": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "vmring2": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "v-ring3": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "tj_magam3": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "tjam3": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "vbolt3": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "vscroll-3": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 3 }, "mtcloak2": { Strength: 1, RepairCost: 20000, MarketCategory: "cloack", CraftType: 3 }, "vtmsword2": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "v-ring1": { Strength: 1, RepairCost: 24000, MarketCategory: "ring", CraftType: 3 }, "tj_magam1": { Strength: 1, RepairCost: 24000, MarketCategory: "necklace", CraftType: 3 }, "vrdagger1": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 1 }, "tjam1": { Strength: 1, RepairCost: 24000, MarketCategory: "necklace", CraftType: 3 }, "vbolt1": { Strength: 1, RepairCost: 24000, MarketCategory: "ring", CraftType: 3 }, "vbolt2": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "vtjcloak2": { Strength: 1, RepairCost: 20000, MarketCategory: "cloack", CraftType: 3 }, "staff_v2": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "sph3": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "vmring3": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "tmarmor2": { Strength: 1, RepairCost: 20000, MarketCategory: "cuirass", CraftType: 2 }, "tj_vboots2": { Strength: 1, RepairCost: 20000, MarketCategory: "boots", CraftType: 2 }, "vscroll-2": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 3 }, "sph2": { Strength: 1, RepairCost: 20000, MarketCategory: "backpack", CraftType: 0 }, "vtmaxe2": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "tj_mtuf2": { Strength: 1, RepairCost: 20000, MarketCategory: "boots", CraftType: 2 }, "tj_vboots1": { Strength: 1, RepairCost: 24000, MarketCategory: "boots", CraftType: 2 }, "tjarmor1": { Strength: 1, RepairCost: 24000, MarketCategory: "cuirass", CraftType: 2 }, "tj_helmet1": { Strength: 1, RepairCost: 24000, MarketCategory: "helm", CraftType: 2 }, "tj-shield1": { Strength: 1, RepairCost: 24000, MarketCategory: "shield", CraftType: 2 }, "tj_helmet2": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "tj-shield2": { Strength: 1, RepairCost: 20000, MarketCategory: "shield", CraftType: 2 }, "p_amulet2": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "p_amulet1": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "piratehat3": { Strength: 1, RepairCost: 12000, MarketCategory: "helm", CraftType: 2 }, "pir_armor1": { Strength: 1, RepairCost: 20000, MarketCategory: "cuirass", CraftType: 2 }, "p_dag2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "p_dag1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "p_sword3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "pn_ring2": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "pn_ring1": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "p_compas2": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "p_compas1": { Strength: 1, RepairCost: 20000, MarketCategory: "backpack", CraftType: 0 }, "pn_ring3": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "piring2": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "piring1": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "pir_armor3": { Strength: 1, RepairCost: 12000, MarketCategory: "cuirass", CraftType: 2 }, "pir_armor2": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "p_pistol2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "p_pistol1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "p_cloak2": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "p_cloak1": { Strength: 1, RepairCost: 20000, MarketCategory: "cloack", CraftType: 3 }, "p_amulet3": { Strength: 1, RepairCost: 12000, MarketCategory: "necklace", CraftType: 3 }, "p_dag3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "p_compas3": { Strength: 1, RepairCost: 12000, MarketCategory: "backpack", CraftType: 0 }, "piring3": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "p_pistol3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "p_cloak3": { Strength: 1, RepairCost: 12000, MarketCategory: "cloack", CraftType: 3 }, "p_sword2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "p_boots2": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "p_boots1": { Strength: 1, RepairCost: 20000, MarketCategory: "boots", CraftType: 2 }, "p_boots3": { Strength: 1, RepairCost: 12000, MarketCategory: "boots", CraftType: 2 }, "piratehat2": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "piratehat1": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "p_sword1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "polk_sword1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "polk_armor2": { Strength: 1, RepairCost: 12000, MarketCategory: "cuirass", CraftType: 2 }, "gring": { Strength: 1, RepairCost: 24000, MarketCategory: "ring", CraftType: 3 }, "polk_armor3": { Strength: 1, RepairCost: 8000, MarketCategory: "cuirass", CraftType: 2 }, "polkboots3": { Strength: 1, RepairCost: 8000, MarketCategory: "boots", CraftType: 2 }, "polk_sword3": { Strength: 1, RepairCost: 8000, MarketCategory: "weapon", CraftType: 1 }, "polk__helm3": { Strength: 1, RepairCost: 8000, MarketCategory: "helm", CraftType: 2 }, "polk_sword2": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "gringd": { Strength: 1, RepairCost: 24000, MarketCategory: "ring", CraftType: 3 }, "polkboots2": { Strength: 1, RepairCost: 12000, MarketCategory: "boots", CraftType: 2 }, "polk_armor1": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "polkboots1": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "polk__helm1": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "polk__helm2": { Strength: 1, RepairCost: 12000, MarketCategory: "helm", CraftType: 2 }, "m_amul2": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "ocean_boots1": { Strength: 1, RepairCost: 20000, MarketCategory: "boots", CraftType: 2 }, "m_amul1": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "m_armor1": { Strength: 1, RepairCost: 20000, MarketCategory: "cuirass", CraftType: 2 }, "ocean_dgr1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "ocean_bw1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "ocean_sword1": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "ocean_per1": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "ocean_cl1": { Strength: 1, RepairCost: 20000, MarketCategory: "cloack", CraftType: 3 }, "ocean_hlm1": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "ocean_m_shield1": { Strength: 1, RepairCost: 20000, MarketCategory: "shield", CraftType: 2 }, "ocean_ring1": { Strength: 1, RepairCost: 20000, MarketCategory: "ring", CraftType: 3 }, "ocean_eye1": { Strength: 1, RepairCost: 20000, MarketCategory: "backpack", CraftType: 0 }, "m_armor2": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "ocean_dgr2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "ocean_ring2": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "m_armor3": { Strength: 1, RepairCost: 12000, MarketCategory: "cuirass", CraftType: 2 }, "ocean_boots3": { Strength: 1, RepairCost: 12000, MarketCategory: "boots", CraftType: 2 }, "ocean_dgr3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "ocean_sword3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "ocean_hlm3": { Strength: 1, RepairCost: 12000, MarketCategory: "helm", CraftType: 2 }, "ocean_m_shield3": { Strength: 1, RepairCost: 12000, MarketCategory: "shield", CraftType: 2 }, "ocean_bw2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "ocean_sword2": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "ocean_eye2": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "ocean_per2": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "ocean_cl2": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "ocean_ring3": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "ocean_eye3": { Strength: 1, RepairCost: 12000, MarketCategory: "backpack", CraftType: 0 }, "m_amul3": { Strength: 1, RepairCost: 12000, MarketCategory: "necklace", CraftType: 3 }, "ocean_bw3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "ocean_per3": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "ocean_cl3": { Strength: 1, RepairCost: 12000, MarketCategory: "cloack", CraftType: 3 }, "ocean_boots2": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "ocean_hlm2": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "ocean_m_shield2": { Strength: 1, RepairCost: 16000, MarketCategory: "shield", CraftType: 2 }, "adv_neck1": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "adv_armor1": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "a_dagger1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "adv_fring1": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "adv_armor2": { Strength: 1, RepairCost: 10000, MarketCategory: "cuirass", CraftType: 2 }, "adv_boot2": { Strength: 1, RepairCost: 10000, MarketCategory: "boots", CraftType: 2 }, "adv_hm2": { Strength: 1, RepairCost: 10000, MarketCategory: "helm", CraftType: 2 }, "adv_shild2": { Strength: 1, RepairCost: 10000, MarketCategory: "shield", CraftType: 2 }, "adv_saber2": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "adv_longbow1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "adv_clk1": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "adv_sumk2": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "adv_fring2": { Strength: 1, RepairCost: 10000, MarketCategory: "ring", CraftType: 3 }, "adv_neck2": { Strength: 1, RepairCost: 10000, MarketCategory: "necklace", CraftType: 3 }, "adv_longbow2": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "a_dagger2": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "adv_clk2": { Strength: 1, RepairCost: 10000, MarketCategory: "cloack", CraftType: 3 }, "adv_boot1": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "adv_sumk1": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "adv_hm1": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "adv_shild1": { Strength: 1, RepairCost: 16000, MarketCategory: "shield", CraftType: 2 }, "adv_saber1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "mir_am2": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "mir_am1": { Strength: 1, RepairCost: 24000, MarketCategory: "necklace", CraftType: 3 }, "mh_sword1": { Strength: 1, RepairCost: 24000, MarketCategory: "weapon", CraftType: 1 }, "mir_armor2": { Strength: 1, RepairCost: 20000, MarketCategory: "cuirass", CraftType: 2 }, "mir_armor3": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "mir_boots3": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "mh_sword3": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "mir_shld3": { Strength: 1, RepairCost: 16000, MarketCategory: "shield", CraftType: 2 }, "mh_sword2": { Strength: 1, RepairCost: 20000, MarketCategory: "weapon", CraftType: 1 }, "mir_am3": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "mir_boots2": { Strength: 1, RepairCost: 20000, MarketCategory: "boots", CraftType: 2 }, "mir_armor1": { Strength: 1, RepairCost: 24000, MarketCategory: "cuirass", CraftType: 2 }, "mir_shld1": { Strength: 1, RepairCost: 24000, MarketCategory: "shield", CraftType: 2 }, "mir_boots1": { Strength: 1, RepairCost: 24000, MarketCategory: "boots", CraftType: 2 }, "mir_shld2": { Strength: 1, RepairCost: 20000, MarketCategory: "shield", CraftType: 2 }, "ed_mbook1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "ed_armr1": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "ed_elfbow1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "ed_bsword1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "ed_ring1": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "ed_armr2": { Strength: 1, RepairCost: 14000, MarketCategory: "cuirass", CraftType: 2 }, "ed_mbook2": { Strength: 1, RepairCost: 14000, MarketCategory: "weapon", CraftType: 1 }, "ed_ring2": { Strength: 1, RepairCost: 14000, MarketCategory: "ring", CraftType: 3 }, "ed_armr3": { Strength: 1, RepairCost: 12000, MarketCategory: "cuirass", CraftType: 2 }, "ed_bsword3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "ed_elfbow2": { Strength: 1, RepairCost: 14000, MarketCategory: "weapon", CraftType: 1 }, "ed_bsword2": { Strength: 1, RepairCost: 14000, MarketCategory: "weapon", CraftType: 1 }, "ed_mbook3": { Strength: 54, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "ed_ring3": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "ed_elfbow3": { Strength: 1, RepairCost: 12000, MarketCategory: "weapon", CraftType: 1 }, "stalker_crsb2": { Strength: 1, RepairCost: 12800, MarketCategory: "weapon", CraftType: 1 }, "stalker_crsb1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "stalker_hlm1": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "stalker_dagger1": { Strength: 1, RepairCost: 16000, MarketCategory: "weapon", CraftType: 1 }, "stalker_hlm2": { Strength: 1, RepairCost: 12800, MarketCategory: "helm", CraftType: 2 }, "stalker_dagger2": { Strength: 1, RepairCost: 12800, MarketCategory: "weapon", CraftType: 1 }, "stalker_crsb3": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "stalker_hlm3": { Strength: 1, RepairCost: 10000, MarketCategory: "helm", CraftType: 2 }, "stalker_dagger3": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "imp_amul": { Strength: 80, RepairCost: 60000, MarketCategory: "necklace", CraftType: 3 }, "imp_crossbow": { Strength: 80, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "imp_armor": { Strength: 80, RepairCost: 36000, MarketCategory: "cuirass", CraftType: 2 }, "imp_dagger": { Strength: 80, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "imp_ring": { Strength: 80, RepairCost: 28000, MarketCategory: "ring", CraftType: 3 }, "imp_sword": { Strength: 80, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "imp_cloak": { Strength: 80, RepairCost: 36000, MarketCategory: "cloack", CraftType: 3 }, "imp_boots": { Strength: 80, RepairCost: 36000, MarketCategory: "boots", CraftType: 2 }, "imp_helmet": { Strength: 80, RepairCost: 36000, MarketCategory: "helm", CraftType: 2 }, "imp_shield": { Strength: 80, RepairCost: 36000, MarketCategory: "shield", CraftType: 2 }, "dark_amul": { Strength: 80, RepairCost: 60000, MarketCategory: "necklace", CraftType: 3 }, "dark_armor": { Strength: 80, RepairCost: 36000, MarketCategory: "cuirass", CraftType: 2 }, "dark_dagger": { Strength: 80, RepairCost: 36000, MarketCategory: "weapon", CraftType: 1 }, "dark_ring": { Strength: 80, RepairCost: 28000, MarketCategory: "ring", CraftType: 3 }, "dark_bow": { Strength: 80, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "dark_cloak": { Strength: 80, RepairCost: 36000, MarketCategory: "cloack", CraftType: 3 }, "dark_boots": { Strength: 80, RepairCost: 36000, MarketCategory: "boots", CraftType: 2 }, "dark_axe": { Strength: 80, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "dark_helmet": { Strength: 80, RepairCost: 36000, MarketCategory: "helm", CraftType: 2 }, "dark_shield": { Strength: 80, RepairCost: 36000, MarketCategory: "shield", CraftType: 2 }, "heaven_helm": { Strength: 80, RepairCost: 36000, MarketCategory: "helm", CraftType: 2 }, "heaven_clk": { Strength: 80, RepairCost: 36000, MarketCategory: "cloack", CraftType: 3 }, "heaven_bts": { Strength: 80, RepairCost: 36000, MarketCategory: "boots", CraftType: 2 }, "heaven_armr": { Strength: 80, RepairCost: 36000, MarketCategory: "cuirass", CraftType: 2 }, "heaven_staff": { Strength: 80, RepairCost: 40000, MarketCategory: "weapon", CraftType: 1 }, "potion01": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "potion02": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "potion03": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "potion04": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "potion05": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "potion06": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "potion07": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "potion08": { Strength: 1, RepairCost: 0, MarketCategory: "other", CraftType: 0 }, "16amul": { Strength: 16, RepairCost: 16161, MarketCategory: "necklace", CraftType: 3 }, "forest_crossbow": { Strength: 1, RepairCost: 10000, MarketCategory: "weapon", CraftType: 1 }, "icecr1": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "drak_crown1": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "ed_pendant1": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "arm_armor1": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "arm_cap1": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "eddem_ring1": { Strength: 1, RepairCost: 16000, MarketCategory: "ring", CraftType: 3 }, "stalker_cl1": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "arm_armor2": { Strength: 1, RepairCost: 12800, MarketCategory: "cuirass", CraftType: 2 }, "arm_cap2": { Strength: 1, RepairCost: 12800, MarketCategory: "helm", CraftType: 2 }, "drak_crown2": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "arm_cap3": { Strength: 1, RepairCost: 10000, MarketCategory: "helm", CraftType: 2 }, "mir_helmt3": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "icecr2": { Strength: 1, RepairCost: 14400, MarketCategory: "backpack", CraftType: 0 }, "icecr3": { Strength: 1, RepairCost: 12800, MarketCategory: "backpack", CraftType: 0 }, "eddem_ring2": { Strength: 1, RepairCost: 14000, MarketCategory: "undefined", CraftType: 3 }, "stalker_cl2": { Strength: 1, RepairCost: 12800, MarketCategory: "cloack", CraftType: 3 }, "ed_pendant2": { Strength: 1, RepairCost: 14000, MarketCategory: "necklace", CraftType: 3 }, "sun_staff": { Strength: 85, RepairCost: 17600, MarketCategory: "weapon", CraftType: 1 }, "drak_crown3": { Strength: 1, RepairCost: 12000, MarketCategory: "helm", CraftType: 2 }, "ed_pendant3": { Strength: 1, RepairCost: 12000, MarketCategory: "necklace", CraftType: 3 }, "arm_armor3": { Strength: 1, RepairCost: 10000, MarketCategory: "cuirass", CraftType: 2 }, "eddem_ring3": { Strength: 1, RepairCost: 12000, MarketCategory: "ring", CraftType: 3 }, "stalker_cl3": { Strength: 1, RepairCost: 10000, MarketCategory: "cloack", CraftType: 3 }, "wind_boots": { Strength: 85, RepairCost: 8700, MarketCategory: "boots", CraftType: 2 }, "mir_helmt1": { Strength: 1, RepairCost: 24000, MarketCategory: "helm", CraftType: 2 }, "wind_helm": { Strength: 85, RepairCost: 7400, MarketCategory: "helm", CraftType: 2 }, "mir_helmt2": { Strength: 1, RepairCost: 20000, MarketCategory: "helm", CraftType: 2 }, "wind_armor": { Strength: 85, RepairCost: 9500, MarketCategory: "cuirass", CraftType: 2 }, "wanderer_armor1": { Strength: 80, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "wanderer_armor2": { Strength: 80, RepairCost: 14000, MarketCategory: "cuirass", CraftType: 2 }, "wanderer_armor3": { Strength: 80, RepairCost: 12000, MarketCategory: "cuirass", CraftType: 2 }, "stalker_armour1": { Strength: 1, RepairCost: 16000, MarketCategory: "cuirass", CraftType: 2 }, "stalker_armour2": { Strength: 1, RepairCost: 12800, MarketCategory: "cuirass", CraftType: 2 }, "stalker_armour3": { Strength: 1, RepairCost: 10000, MarketCategory: "cuirass", CraftType: 2 }, "arm_clk1": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "arm_clk2": { Strength: 1, RepairCost: 12800, MarketCategory: "cloack", CraftType: 3 }, "arm_clk3": { Strength: 1, RepairCost: 10000, MarketCategory: "cloack", CraftType: 3 }, "pend_a1": { Strength: 1, RepairCost: 20000, MarketCategory: "necklace", CraftType: 3 }, "pend_a2": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "pend_a3": { Strength: 1, RepairCost: 12000, MarketCategory: "necklace", CraftType: 3 }, "lotus1": { Strength: 1, RepairCost: 9600, MarketCategory: "backpack", CraftType: 0 }, "lotus2": { Strength: 1, RepairCost: 9000, MarketCategory: "backpack", CraftType: 0 }, "lotus3": { Strength: 1, RepairCost: 8400, MarketCategory: "backpack", CraftType: 0 }, "eye1": { Strength: 1, RepairCost: 14400, MarketCategory: "necklace", CraftType: 3 }, "eye2": { Strength: 1, RepairCost: 12000, MarketCategory: "necklace", CraftType: 3 }, "eye3": { Strength: 1, RepairCost: 9600, MarketCategory: "necklace", CraftType: 3 }, "stalker_boot1": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "stalker_boot3": { Strength: 1, RepairCost: 10000, MarketCategory: "boots", CraftType: 2 }, "stalker_boot2": { Strength: 1, RepairCost: 12800, MarketCategory: "boots", CraftType: 2 }, "arm_sekstant1": { Strength: 1, RepairCost: 16000, MarketCategory: "backpack", CraftType: 0 }, "arm_sekstant3": { Strength: 1, RepairCost: 10000, MarketCategory: "backpack", CraftType: 0 }, "arm_sekstant2": { Strength: 1, RepairCost: 12800, MarketCategory: "backpack", CraftType: 0 }, "forest_bolt": { Strength: 1, RepairCost: 10000, MarketCategory: "ring", CraftType: 3 } , "mir_cl1": { Strength: 1, RepairCost: 24000, MarketCategory: "cloack", CraftType: 3 }, "mir_cl3": { Strength: 1, RepairCost: 16000, MarketCategory: "cloack", CraftType: 3 }, "mir_cl2": { Strength: 1, RepairCost: 20000, MarketCategory: "cloack", CraftType: 3 } , "dung_glefa1": { Strength: 1, RepairCost: 16800, MarketCategory: "weapon", CraftType: 1 }, "dung_glefa2": { Strength: 1, RepairCost: 14400, MarketCategory: "weapon", CraftType: 1 }, "dung_glefa3": { Strength: 1, RepairCost: 11800, MarketCategory: "weapon", CraftType: 1 } , "wanderer_hat1": { Strength: 1, RepairCost: 16000, MarketCategory: "helm", CraftType: 2 }, "wanderer_hat3": { Strength: 1, RepairCost: 14000, MarketCategory: "helm", CraftType: 2 }, "wanderer_hat2": { Strength: 1, RepairCost: 12000, MarketCategory: "helm", CraftType: 2 } , "ed_svboots1": { Strength: 1, RepairCost: 16000, MarketCategory: "boots", CraftType: 2 }, "ed_svboots3": { Strength: 1, RepairCost: 12000, MarketCategory: "boots", CraftType: 2 }, "ed_svboots2": { Strength: 1, RepairCost: 14000, MarketCategory: "boots", CraftType: 2 } , "stalker_aml2": { Strength: 1, RepairCost: 12800, MarketCategory: "necklace", CraftType: 3 }, "stalker_aml1": { Strength: 1, RepairCost: 16000, MarketCategory: "necklace", CraftType: 3 }, "stalker_aml3": { Strength: 1, RepairCost: 10000, MarketCategory: "necklace", CraftType: 3 } }; const EcostatDetailsIds = { 92: "wzzamulet16", 12: "amulet_of_luck", 120: "samul14", 107: "wzzamulet13", 66: "large_shield", 23: "hauberk", 131: "boots2", 150: "sword18", 95: "warring13", 98: "armor15", 126: "sarmor16", 154: "armor17", 160: "dagger16", 15: "leather_shiled", 142: "leatherboots", 140: "leatherplate", 18: "leather_helm", 100: "wwwring16", 149: "dring5", 76: "warriorring", 152: "dring18", 146: "dring15", 128: "sring4", 21: "doubt_ring", 159: "dring21", 139: "sring17", 32: "chain_coif", 61: "warrior_pendant", 56: "power_pendant", 156: "amulet19", 70: "mif_lboots", 88: "bow14", 155: "bow17", 132: "scloack8", 14: "bravery_medal", 48: "power_sword", 25: "requital_sword", 87: "firsword15", 121: "ssword16", 130: "ssword8", 127: "ssword10", 30: "broad_sword", 34: "def_sword", 135: "sarmor9", 147: "dring12", 102: "miff_plate", 74: "mif_sword", 24: "soul_cape", 116: "sarmor13", 90: "boots13", 115: "ssword13", 99: "zxhelmet13", 97: "shield13", 157: "samul17", 19: "verve_ring", 153: "dring9", 125: "scloack16", 114: "sboots12", 86: "mm_sword", 113: "shelm12", 124: "sboots16", 91: "boots15", 148: "boots17", 133: "sboots9", 47: "ciras", 16: "steel_blade", 51: "steel_helmet", 143: "s_shield", 63: "full_plate", 50: "steel_boots", 136: "samul8", 129: "sring10", 73: "mif_hboots", 72: "mif_hhelmet", 123: "shelm16", 138: "shelm8", 82: "myhelmet15", 151: "helmet17", 49: "dragon_shield", 83: "shield16", 158: "shield19", 134: "sshield5", 112: "sshield11", 17: "defender_shield", 118: "sshield14" }; const isEn = document.documentElement.lang == "en"; const Strings = { "ru": { Lot: ustring("Товар"), Cost: ustring("Цена"), TimeLeft: ustring("Завершение"), BattlePrice: ustring("Цена за бой"), Strength: ustring("Прочность"), RestStrength: ustring("Оставшаяся прочность"), OptimalStrength: ustring("До прочности"), Combats: ustring("Боев"), Options: ustring("Настройки"), BestApproach: ustring("Лучшее приближение к минимальной цене (%)"), GoodApproach: ustring("Хорошее приближение к минимальной цене (%)"), BuyInfo: ustring("Информация о покупке"), ShowAfterRepairBattleCostInInventory: ustring("Показывать в инвентаре стоимость боя после ремонта"), SmithLevel: ustring("Уровень кузнеца (0-9)"), SmithRewardPercent: "Вознаграждение кузнецу (10%-150%)", EditLotInfo: "О покупке", Spended: "Проведено", Remaining: "Осталось", ShopAndFactoryPrice: "Цена магазина и предприятия", ResidualValue: "Остаточная стоимость", gold: "золото", wood: "дерево", ore: "руда", mercury: "ртуть", sulfur: "сера", crystals: "кристаллы", gems: "самоцветы", diamonds: "бриллианты", Total: "Итого", BuyNow: "Купить сразу!", MarketPrice: "Цена на рынке", ToUpdateTheCertificatePrice: "Чтобы цена обновилась, зайдите на рынок (щелчок по картинке сертификата)", ArtBulkTtransferEnabledName: "Включить массовую передачу артефактов", Receiver: "Получатель", Transfer: "Передача", FillReceiver: "Задайте получателя", CancelAll: "Отменить всё", IntoOwnership: "В распоряжение", WithRecallIn: "С возвратом через", IntoRepairs: "В ремонт", PercentOfRepairCost: "% от цены ремонта (10 - 150)", Days: "Дней", TransferData: "Параметры передачи", AllowRepairing: "разрешить ремонт", ForAll: "Для всех", ForThis: "Для данного", ClearList: "Очистить список", Knight: "Рыцарь:", CombatLevel: "Боевой уровень:", SkillsCount: "Сумма умений", Ratio: "соотношение", UnderRepair: "В ремонте", SmithSchedulingEnabledName: "Включить расписание в кузнице", Sale: "Продать", AsForAll: "Как для всех", Forbid: "Запретить", Allow: "Разрешить", ToMarket: "На рынок", BeginRepairOnSmithFreeName: "Начинать ремонт при освобождении кузницы", WithRecallInTitle: "Надо задать ненулевые цену, количество дней и боёв", IntoOwnershipTitle: "Можно задать цену или оставить пустой", IntoRepairsTitle: "Должен быть задан % кузнецу", IncomeViewEnabledName: "Включить просмотр дохода", ShowResourcesCostPanelName: "Показывать панель стоимости ресурсов", TotalSkillsCountName: "Подсчитать сумму умений", ArtCost: "Стоимость арта", CraftCostString: "Стоимость крафта", Recalc: "Расчет", RecalcFromDaily: "Рассчитать стоимость крафта из статистики цен на элементы с Daily", BeginRepairClanDepositoryName: "Начинать ремонт кланового склада" }, "en": { Lot: "Lot", Cost: "Cost", TimeLeft: "Time left", BattlePrice: "Battle price", Strength: "Strength", RestStrength: "Rest strength", OptimalStrength: "Optimal strength", Combats: "Combats", Options: "Options", BestApproach: "Best approach to min price (%)", GoodApproach: "Good approach to min price (%)", BuyInfo: "Buy info", ShowAfterRepairBattleCostInInventory: "Show afterRepairBattleCost in inventory", SmithLevel: "Smith level (0-9)", SmithRewardPercent: "Smith reward (10%-150%)", EditLotInfo: "Lot info", Spended: "Spended", Remaining: "Remaining", ShopAndFactoryPrice: "Shop and factory price", ResidualValue: "Residual value", gold: "gold", wood: "wood", ore: "ore", mercury: "mercury", sulfur: "sulfur", crystals: "crystals", gems: "gems", diamonds: "diamonds", Total: "Total", BuyNow: "Buy now!", MarketPrice: "Market price", ToUpdateTheCertificatePrice: "To update the price, go to the market (click on the certificate image)", ArtBulkTtransferEnabledName: "Enable bulk arts transfer", Receiver: "Receiver", Transfer: "Transfer", FillReceiver: "Fill receiver", CancelAll: "Cancel all", IntoOwnership: "Into ownership", WithRecallIn: "With recall in", IntoRepairs: "Into repairs", PercentOfRepairCost: "% of repair cost (10 - 150)", Days: "Days", TransferData: "Transfer data", AllowRepairing: "Allow repairing", ForAll: "For all", ForThis: "For this", ClearList: "Clear list", Knight: "Knight:", CombatLevel: "Combat level:", SkillsCount: "Skills count", Ratio: "ratio", UnderRepair: "Under repair", SmithSchedulingEnabledName: "Enable smith scheduling", Sale: "Sale", AsForAll: "As for all", Forbid: "Forbid", Allow: "Allow", ToMarket: "To the market", BeginRepairOnSmithFreeName: "Begin repair on smith free", WithRecallInTitle: "It is necessary to set a non-zero price, number of days and fights", IntoOwnershipTitle: "You can set a price or leave it blank", IntoRepairsTitle: "Must be given % to the blacksmith", IncomeViewEnabledName: "Enable income view", ShowResourcesCostPanelName: "Show resources cost panel", TotalSkillsCountName: "Total skills count", ArtCost: "Art cost", CraftCostString: "Craft cost", Recalc: "Recalc", RecalcFromDaily: "Recalc craft cost from daily elements statistics", BeginRepairClanDepositoryName: "Begin repair clan depository" } }; const LocalizedString = Strings[document.documentElement.lang]; const StockArtifactIds = [ "finecl", "super_dagger", "sun_staff", "cold_sword2014", "wind_armor", "wind_boots", "wind_helm", "cold_shieldn", "coldring_n", "coldamul", "sun_boots", "sun_armor", "sun_helm", "sun_ring", "clover_amul", "lbow" ]; const SmithRecoveryEfficiency = [10, 20, 30, 40, 50, 60, 70, 80, 90, 90]; const inventoryStatsPanelSelector = doc => doc.querySelector("div.inventory_stats"); const inventoryArtsPanelSelector = doc => doc.querySelector("div#inv_doll_inside"); function getLocationNumberByCoordinate(x, y) { for(let locationNumber in locations) { if(locations[locationNumber][0] == x && locations[locationNumber][1] == y) { return locationNumber; } } } function uchar(s) { switch (s[0]) {case "А": return "\u0410"; case "Б": return "\u0411"; case "В": return "\u0412"; case "Г": return "\u0413"; case "Д": return "\u0414"; case "Е": return "\u0415"; case "Ж": return "\u0416"; case "З": return "\u0417"; case "И": return "\u0418"; case "Й": return "\u0419"; case "К": return "\u041a"; case "Л": return "\u041b"; case "М": return "\u041c"; case "Н": return "\u041d"; case "О": return "\u041e"; case "П": return "\u041f"; case "Р": return "\u0420"; case "С": return "\u0421"; case "Т": return "\u0422"; case "У": return "\u0423"; case "Ф": return "\u0424"; case "Х": return "\u0425"; case "Ц": return "\u0426"; case "Ч": return "\u0427"; case "Ш": return "\u0428"; case "Щ": return "\u0429"; case "Ъ": return "\u042a"; case "Ы": return "\u042b"; case "Ь": return "\u042c"; case "Э": return "\u042d"; case "Ю": return "\u042e"; case "Я": return "\u042f"; case "а": return "\u0430"; case "б": return "\u0431"; case "в": return "\u0432"; case "г": return "\u0433"; case "д": return "\u0434"; case "е": return "\u0435"; case "ж": return "\u0436"; case "з": return "\u0437"; case "и": return "\u0438"; case "й": return "\u0439"; case "к": return "\u043a"; case "л": return "\u043b"; case "м": return "\u043c"; case "н": return "\u043d"; case "о": return "\u043e"; case "п": return "\u043f"; case "р": return "\u0440"; case "с": return "\u0441"; case "т": return "\u0442"; case "у": return "\u0443"; case "ф": return "\u0444"; case "х": return "\u0445"; case "ц": return "\u0446"; case "ч": return "\u0447"; case "ш": return "\u0448"; case "щ": return "\u0449"; case "ъ": return "\u044a"; case "ы": return "\u044b"; case "ь": return "\u044c"; case "э": return "\u044d"; case "ю": return "\u044e"; case "я": return "\u044f"; case "Ё": return "\u0401"; case "ё": return "\u0451"; default: return s[0];}} function ustring(s) { s = String(s); var result = ""; for (var i = 0; i < s.length; i++) { result += uchar(s[i]); } return result; } function round00(value) { return Math.round(value * 100) / 100; } function getAfterRepairRestStrength(strength, smithLevel) { return Math.floor(strength * SmithRecoveryEfficiency[smithLevel || 9] / 100); } function optimalRepair(marketPrice, repairCost, strength, restStrength, wornStrength, wornRestStrength) { restStrength = restStrength || strength; let totalSpending = marketPrice; let currentRestStrength = restStrength; let totalCombatsAmount = currentRestStrength; let currentStrength = strength; let currentCombatCost = totalSpending / totalCombatsAmount; // Начальная стоимость боя //console.log(`currentStrength: ${currentStrength}, currentRestStrength: ${currentRestStrength}, totalSpending: ${totalSpending}, totalCombatsAmount: ${totalCombatsAmount}, newCombatCost: ${currentCombatCost}`); for(currentStrength = strength; currentStrength > 0; currentStrength--) { if(currentStrength == wornStrength) { var spendedCombats = totalCombatsAmount - wornRestStrength; } currentRestStrength = getAfterRepairRestStrength(currentStrength, SmithLevel); //console.log(`${GM_getValue(SmithRewardPercentName)}`); totalSpending += repairCost * parseInt(GM_getValue(SmithRewardPercentName, 100)) / 100; let newCombatCost = totalSpending / (totalCombatsAmount + currentRestStrength); //console.log(`currentStrength: ${currentStrength}, currentRestStrength: ${currentRestStrength}, totalSpending: ${totalSpending}, totalCombatsAmount: ${totalCombatsAmount + currentRestStrength}, newCombatCost: ${newCombatCost}`); if(newCombatCost > currentCombatCost) { break; } totalCombatsAmount += currentRestStrength; currentCombatCost = newCombatCost; } if(wornStrength) { var residualValue = round00(currentCombatCost * (totalCombatsAmount - spendedCombats) - repairCost * (wornStrength - currentStrength)); } return { Strength: currentStrength, CombatCost: round00(currentCombatCost), CombatsAmount: totalCombatsAmount, SpendedCombats: spendedCombats, ResidualValue: residualValue }; } function addElement(type, parent, data) { let el = createElement(type, data); if(parent) { parent.appendChild(el); } return el; } function createElement(type, data) { let el = document.createElement(type); if(data) { for(let key in data) { if(key == "innerText" || key == "innerHTML") { el[key] = data[key]; } else { el.setAttribute(key, data[key]); } } } return el; } function createPupupPanel(panelName, panelTitle, fieldsMap) { const backgroundPopupPanel = addElement("div", document.body, { id: panelName + "1", style: "position: fixed; left: 0pt; width: 100%; background: none repeat scroll 0% 0% gray; opacity: 0.5; top: 0px; height: 100%; display: block; z-index: 200;" }); backgroundPopupPanel.addEventListener("click", function() { hidePupupPanel(panelName); }, false); const popupPanel = addElement("div", document.body, { id: panelName + "2", style: `position: fixed; width: 650px; background: none repeat scroll 0% 0%; background-image: linear-gradient(to right, #eea2a2 0%, #bbc1bf 19%, #57c6e1 42%, #b49fda 79%, #7ac5d8 100%); left: ${((document.body.offsetWidth - 650) / 2)}px; top: 150px; display: block; z-index: 200; border: 4mm ridge rgba(211, 220, 50, .6);` }); const contentDiv = addElement("div", popupPanel, { id: panelName + "3", style: "border: 1px solid #abc; padding: 5px; margin: 2px; display: flex; flex-wrap: wrap;" }); if(panelTitle) { addElement("b", contentDiv, { innerText: panelTitle, style: "text-align: center; margin: auto; width: 90%; display: block;" }); } const divClose = addElement("div", contentDiv, { id: panelName + "close", title: "Close", innerText: "x", style: "border: 1px solid #abc; width: 15px; height: 15px; text-align: center; cursor: pointer;" }); divClose.addEventListener("click", function() { hidePupupPanel(panelName); }, false); addElement("div", contentDiv, { style: "flex-basis: 100%; height: 0;"}); if(fieldsMap) { const contentTable = addElement("table", contentDiv); for(const rowData of fieldsMap) { const row = addElement("tr", contentTable); for(const cellData of rowData) { const cell = addElement("td", row); if(cellData) { cell.appendChild(cellData); } } } } return contentDiv; } function showPupupPanel(panelName) { let backgroundPopupPanel = document.getElementById(panelName + "1"); let popupPanel = document.getElementById(panelName + "2"); if(backgroundPopupPanel) { backgroundPopupPanel.style.display = popupPanel.style.display = 'block'; return true; } return false; } function hidePupupPanel(panelName) { let backgroundPopupPanel = document.getElementById(panelName + "1"); let popupPanel = document.getElementById(panelName + "2"); backgroundPopupPanel.style.display = popupPanel.style.display = 'none'; } function showScriptOptions() { if(showPupupPanel(GM_info.script.name)) { return; } const fieldsMap = []; const combatCostBestDeviationLabel = createElement("label", { for: "combatCostBestDeviationInput", innerText: LocalizedString.BestApproach + "\t", style: `background-color: ${CombatCostBestDeviationColor};` }); const combatCostBestDeviationInput = createElement("input", { id: "combatCostBestDeviationInput", type: "number", value: CombatCostBestDeviation, onfocus: "this.select();" }); combatCostBestDeviationInput.addEventListener("change", function() { GM_setValue("CombatCostBestDeviation", parseInt(this.value)); CombatCostBestDeviation = parseInt(this.value); }, false); const combatCostBestDeviationColorInput = createElement("input", { id: "combatCostBestDeviationColorInput", type: "color", value: CombatCostBestDeviationColor, style: "height: 22px; width: 30px;" }); combatCostBestDeviationColorInput.addEventListener("change", function() { GM_setValue("CombatCostBestDeviationColor", this.value); CombatCostBestDeviationColor = this.value; combatCostBestDeviationLabel.style.backgroundColor = this.value; }, false); fieldsMap.push([combatCostBestDeviationLabel, combatCostBestDeviationInput, combatCostBestDeviationColorInput]); const combatCostGoodDeviationLabel = createElement("label", { for: "combatCostGoodDeviationInput", innerText: LocalizedString.GoodApproach + "\t", style: `background-color: ${CombatCostGoodDeviationColor};` }); const combatCostGoodDeviationInput = createElement("input", { id: "combatCostGoodDeviationInput", type: "number", value: CombatCostGoodDeviation, onfocus: "this.select();" }); combatCostGoodDeviationInput.addEventListener("change", function() { GM_setValue("CombatCostGoodDeviation", parseInt(this.value)); CombatCostGoodDeviation = parseInt(this.value); }, false); const combatCostGoodDeviationColorInput = createElement("input", { id: "combatCostGoodDeviationColorInput", type: "color", value: CombatCostGoodDeviationColor, style: "height: 22px; width: 30px;" }); combatCostGoodDeviationColorInput.addEventListener("change", function() { GM_setValue("CombatCostGoodDeviationColor", this.value); CombatCostGoodDeviationColor = this.value; combatCostGoodDeviationLabel.style.backgroundColor = this.value; }, false); fieldsMap.push([combatCostGoodDeviationLabel, combatCostGoodDeviationInput, combatCostGoodDeviationColorInput]); const showAfterRepairBattleCostInInventoryLable = createElement("label", { for: "showAfterRepairBattleCostInInventoryInput", innerText: LocalizedString.ShowAfterRepairBattleCostInInventory + "\t" }); const showAfterRepairBattleCostInInventoryInput = createElement("input", { id: "showAfterRepairBattleCostInInventoryInput", type: "checkbox" }); showAfterRepairBattleCostInInventoryInput.checked = gmGetBool("ShowAfterRepairBattleCostInInventory"); showAfterRepairBattleCostInInventoryInput.addEventListener("change", function() { GM_setValue("ShowAfterRepairBattleCostInInventory", this.checked); }, false); fieldsMap.push([showAfterRepairBattleCostInInventoryLable, showAfterRepairBattleCostInInventoryInput]); const artBulkTtransferEnabledLable = createElement("label", { for: "artBulkTtransferEnabledInput", innerText: LocalizedString.ArtBulkTtransferEnabledName + "\t" }); const artBulkTtransferEnabledInput = createElement("input", { id: "artBulkTtransferEnabledInput", type: "checkbox" }); artBulkTtransferEnabledInput.checked = gmGetBool("ArtBulkTtransferEnabled"); artBulkTtransferEnabledInput.addEventListener("change", function() { GM_setValue("ArtBulkTtransferEnabled", this.checked); }, false); fieldsMap.push([artBulkTtransferEnabledLable, artBulkTtransferEnabledInput]); const artSmithScheduleEnabledLable = createElement("label", { for: "artSmithScheduleEnabledInput", innerText: LocalizedString.SmithSchedulingEnabledName + "\t" }); const artSmithScheduleEnabledInput = createElement("input", { id: "artSmithScheduleEnabledInput", type: "checkbox" }); artSmithScheduleEnabledInput.checked = gmGetBool("SmithSchedulingEnabled"); artSmithScheduleEnabledInput.addEventListener("change", function() { GM_setValue("SmithSchedulingEnabled", this.checked); }, false); fieldsMap.push([artSmithScheduleEnabledLable, artSmithScheduleEnabledInput]); const artBeginRepairOnSmithFreeLable = createElement("label", { for: "artBeginRepairOnSmithFreeInput", innerText: LocalizedString.BeginRepairOnSmithFreeName + "\t" }); const artBeginRepairOnSmithFreeInput = createElement("input", { id: "artBeginRepairOnSmithFreeInput", type: "checkbox" }); artBeginRepairOnSmithFreeInput.checked = gmGetBool("BeginRepairOnSmithFree"); artBeginRepairOnSmithFreeInput.addEventListener("change", function() { GM_setValue("BeginRepairOnSmithFree", this.checked); }, false); fieldsMap.push([artBeginRepairOnSmithFreeLable, artBeginRepairOnSmithFreeInput]); const incomeViewEnabledLable = createElement("label", { for: "incomeViewEnabledInput", innerText: LocalizedString.IncomeViewEnabledName + "\t" }); const incomeViewEnabledInput = createElement("input", { id: "incomeViewEnabledInput", type: "checkbox" }); incomeViewEnabledInput.checked = gmGetBool("IncomeViewEnabled"); incomeViewEnabledInput.addEventListener("change", function() { GM_setValue("IncomeViewEnabled", this.checked); }, false); fieldsMap.push([incomeViewEnabledLable, incomeViewEnabledInput]); const showResourcesCostPanelLable = createElement("label", { for: "showResourcesCostPanelInput", innerText: LocalizedString.ShowResourcesCostPanelName + "\t" }); const showResourcesCostPanelInput = createElement("input", { id: "showResourcesCostPanelInput", type: "checkbox" }); showResourcesCostPanelInput.checked = gmGetBool("ShowResourcesCostPanel"); showResourcesCostPanelInput.addEventListener("change", function() { GM_setValue("ShowResourcesCostPanel", this.checked); }, false); fieldsMap.push([showResourcesCostPanelLable, showResourcesCostPanelInput]); const totalSkillsCountLable = createElement("label", { for: "totalSkillsCountCheckbox", innerText: LocalizedString.TotalSkillsCountName + "\t" }); const totalSkillsCountCheckbox = createElement("input", { id: "totalSkillsCountCheckbox", type: "checkbox" }); totalSkillsCountCheckbox.checked = gmGetBool("TotalSkillsCount"); totalSkillsCountCheckbox.addEventListener("change", function() { GM_setValue("TotalSkillsCount", this.checked); }, false); fieldsMap.push([totalSkillsCountLable, totalSkillsCountCheckbox]); const beginRepairClanDepositoryLable = createElement("label", { for: "beginRepairClanDepositoryCheckbox", innerText: LocalizedString.BeginRepairClanDepositoryName + "\t" }); const beginRepairClanDepositoryCheckbox = createElement("input", { id: "beginRepairClanDepositoryCheckbox", type: "checkbox" }); beginRepairClanDepositoryCheckbox.checked = gmGetBool("BeginRepairClanDepository"); beginRepairClanDepositoryCheckbox.addEventListener("change", function() { GM_setValue("BeginRepairClanDepository", this.checked); }, false); //fieldsMap.push([beginRepairClanDepositoryLable, beginRepairClanDepositoryCheckbox]); const showTradesToMeLable = createElement("label", { for: "ShowTradesToMeCheckbox", innerText: (isEn ? "Show trades to me icon" : "Показать индикатор передач") + "\t" }); const showTradesToMeCheckbox = createElement("input", { id: "ShowTradesToMeCheckbox", type: "checkbox" }); showTradesToMeCheckbox.checked = gmGetBool("ShowTradesToMe"); showTradesToMeCheckbox.addEventListener("change", function() { GM_setValue("ShowTradesToMe", this.checked); }, false); fieldsMap.push([showTradesToMeLable, showTradesToMeCheckbox]); const showThresholdPricesIndicatorLable = createElement("label", { for: "ShowThresholdPricesImdicatorCheckbox", innerText: (isEn ? "Show advantageous lots" : "Показать индикатор выгодных лотов") + "\t" }); const showThresholdPricesImdicatorCheckbox = createElement("input", { id: "ShowThresholdPricesImdicatorCheckbox", type: "checkbox" }); showThresholdPricesImdicatorCheckbox.checked = gmGetBool("ShowThresholdPricesIndicator"); showThresholdPricesImdicatorCheckbox.addEventListener("change", function() { GM_setValue("ShowThresholdPricesIndicator", this.checked); }, false); const showThresholdPricesNotificationLable = createElement("label", { for: "ShowThresholdPricesNotificationCheckbox", innerText: (isEn ? "Notification" : "Оповещение") + "\t" }); const showThresholdPricesNotificationCheckbox = createElement("input", { id: "ShowThresholdPricesNotificationCheckbox", type: "checkbox" }); showThresholdPricesNotificationCheckbox.checked = gmGetBool("ShowThresholdPricesNotification"); showThresholdPricesNotificationCheckbox.addEventListener("change", function() { GM_setValue("ShowThresholdPricesNotification", this.checked); }, false); fieldsMap.push([showThresholdPricesIndicatorLable, showThresholdPricesImdicatorCheckbox, showThresholdPricesNotificationLable, showThresholdPricesNotificationCheckbox]); const showClanDepositoryRepairIconLable = createElement("label", { for: "showClanDepositoryRepairIconSelect", innerText: (isEn ? "Show clan depository repair icon" : "Показать индикатор ремонта на складе") + "\t" }); const showClanDepositoryRepairIconSelect = createElement("select", { id: "showClanDepositoryRepairIconSelect" }); showClanDepositoryRepairIconSelect.addEventListener("change", function() { GM_setValue("ShowClanDepositoryRepairIcon", parseInt(this.value)); }, false); const showClanDepositoryRepairIconOptions = {"0": "Никогда", "1": "Если кузница свободна", "2": "Всегда"}; for(const key in showClanDepositoryRepairIconOptions) { let option = addElement("option", showClanDepositoryRepairIconSelect, { value: parseInt(key), innerHTML: showClanDepositoryRepairIconOptions[key] }); if(key == GM_getValue("ShowClanDepositoryRepairIcon")) { option.setAttribute("selected", "selected"); } } fieldsMap.push([showClanDepositoryRepairIconLable, showClanDepositoryRepairIconSelect]); const smithLevelLable = createElement("label", { for: "OptimalRepairAtMarketSmithLevelInput", innerText: LocalizedString.SmithLevel + "\t" }); const optimalRepairAtMarketSmithLevelInput = createElement("input", { id: "OptimalRepairAtMarketSmithLevelInput", type: "number", value: SmithLevel, onfocus: "this.select();" }); optimalRepairAtMarketSmithLevelInput.addEventListener("change", function() { GM_setValue(OptimalRepairAtMarketSmithLevelName, parseInt(this.value)); SmithLevel = parseInt(this.value); }, false); fieldsMap.push([smithLevelLable, optimalRepairAtMarketSmithLevelInput]); const smithRewardPercentLable = createElement("label", { for: "OptimalRepairAtMarketSmithRewardPercentInput", innerText: LocalizedString.SmithRewardPercent + "\t" }); const optimalRepairAtMarketSmithRewardPercentInput = createElement("input", { id: "OptimalRepairAtMarketSmithRewardPercentInput", type: "number", value: GM_getValue(SmithRewardPercentName, ""), onfocus: "this.select();" }); optimalRepairAtMarketSmithRewardPercentInput.addEventListener("change", function() { gmSetOrDeleteNumber(SmithRewardPercentName, this.value); }, false); fieldsMap.push([smithRewardPercentLable, optimalRepairAtMarketSmithRewardPercentInput]); createPupupPanel(GM_info.script.name, LocalizedString.Options + " " + GM_info.script.name, fieldsMap); } function groupBy(list, keyFieldOrSelector) { return list.reduce(function(t, item) { const keyValue = typeof keyFieldOrSelector === 'function' ? keyFieldOrSelector(item) : item[keyFieldOrSelector]; (t[keyValue] = t[keyValue] || []).push(item); return t; }, {}); }; function sortTable(tableElement, columnIndex, sortType) { sortType = sortType || SortType.Text; let rows, switching, i, x, y, shouldSwitch; switching = true; while(switching) { /* Make a loop that will continue until no switching has been done: */ switching = false; // Start by saying: no switching is done: rows = tableElement.rows; for(i = 1; i < (rows.length - 1); i++) { /* Loop through all table rows (except the first, which contains table headers): */ shouldSwitch = false; // Start by saying there should be no switching: x = rows[i].cells[columnIndex]; /* Get the two elements you want to compare, one from current row and one from the next: */ y = rows[i + 1].cells[columnIndex]; if(sortType == SortType.Text && x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) { // Check if the two rows should switch place: shouldSwitch = true; // If so, mark as a switch and break the loop: break; } if(sortType == SortType.Number && parseFloat(x.innerHTML) > parseFloat(y.innerHTML)) { // Check if the two rows should switch place: shouldSwitch = true; // If so, mark as a switch and break the loop: break; } } if(shouldSwitch) { rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); /* If a switch has been marked, make the switch and mark that a switch has been done: */ switching = true; } } } function extendLotsTable(doc, url, removeForms = false, getDataOnly = false) { const ss2 = doc.querySelector("select[name='ss2']"); const ss2Table = getParent(ss2, "table"); if(!ss2Table) { return; } if(removeForms) { const forms = ss2Table.querySelectorAll("form"); for(const form of forms) { form.remove(); } } let tableHeaderRow; for(const tr of doc.querySelectorAll("tr")) { if(tr.nextElementSibling && tr.textContent.includes(LocalizedString.Lot) && tr.textContent.includes(LocalizedString.Cost) && tr.textContent.includes(LocalizedString.TimeLeft)) { tableHeaderRow = tr; break; } } if(!tableHeaderRow) { tableHeaderRow = ss2Table.rows[1]; } if(!tableHeaderRow) { return; } const urlArtId = getUrlParamValue(url, "art_type"); if(urlArtId) { const product = tableHeaderRow.cells[0]; var shopCostInfo = getFormatedArtCost(urlArtId); if(shopCostInfo) { var shopCostSpan = addElement("span", product, { innerText: shopCostInfo.CostInfo, title: LocalizedString.ShopAndFactoryPrice, style: "padding-left: 3px;" }); } } const selForm = ss2Table.querySelector("form[name='sort']"); if(selForm && gmGetBool("IncomeViewEnabled")) { addElement("span", selForm, { innerText: "Только с выгодой" }); const incomeOnlyCheckbox = addElement("input", selForm, { type: "checkbox" }); incomeOnlyCheckbox.checked = gmGetBool("IncomeOnly"); incomeOnlyCheckbox.addEventListener("change", function(e) { e.stopPropagation(); GM_setValue("IncomeOnly", this.checked); toggleIncomeRows(getParent(tableHeaderRow, "table")); }, false); } if(selForm && urlArtId && gmGetBool("ShowThresholdPricesIndicator")) { const thresholdPrices = JSON.parse(GM_getValue("ThresholdPrices", "{}")); const indicatedPriceInput = addElement("input", selForm, { type: "number", value: thresholdPrices[urlArtId] || "", title: "Цена для индикации" }); indicatedPriceInput.addEventListener("change", function(e) { e.stopPropagation(); if(Number(this.value) > 0) { thresholdPrices[urlArtId] = this.value; thresholdPrices[`Url${urlArtId}`] = url; } else { delete thresholdPrices[urlArtId]; }; GM_setValue("ThresholdPrices", JSON.stringify(thresholdPrices)); GM_deleteValue("ShowThresholdPricesData"); GM_deleteValue("ShowThresholdPricesImdicatorLastRequestTime"); }, false); } const urlCat = getUrlParamValue(url, "cat") || "my"; const drawOptimalRepairColumns = (!urlArtId || urlArtId in ArtifactInfo) && !["res", "elements", "part", "obj_share", "cert", "dom"].includes(urlCat); if(drawOptimalRepairColumns) { ss2Table.rows[0].cells[1].setAttribute("colspan", "7"); let td = addElement("td", tableHeaderRow, { style: "text-align: center;", innerText: LocalizedString.BattlePrice }); td.addEventListener("click", showScriptOptions, false); let sortDiv = addElement("div", td, { style: "float: right; border: 1px solid; cursor: pointer;", innerText: "v", title: "Sort" }); sortDiv.addEventListener("click", function(e) { sortTable(tableHeaderRow.parentNode, 5, SortType.Number); e.stopPropagation(); }, false); td = addElement("td", tableHeaderRow, { style: "text-align: center;", innerText: LocalizedString.OptimalStrength }); td.addEventListener("click", showScriptOptions, false); td = addElement("td", tableHeaderRow, { style: "text-align: center;", innerText: LocalizedString.Combats }); td.addEventListener("click", showScriptOptions, false); } logNewArtifactsIds(doc, tableHeaderRow.previousElementSibling); let row = tableHeaderRow; let arts = []; while(row = row.nextElementSibling) { const art = parseLotRow(row, urlArtId); if(art) { arts.push(art); if(drawOptimalRepairColumns && art.OptimalRepairCombatCost) { let td = addElement("td", row, { style: "text-align: center;", innerText: `${art.OptimalRepairCombatCost}` }); td = addElement("td", row, { style: "text-align: center;", innerText: `${art.OptimalRepairStrength}` }); let title = `Затраты в кузне:\n(${art.LotStrength} - ${art.OptimalRepairStrength}) * ${art.RepairCost} = ${((art.LotStrength - art.OptimalRepairStrength) * art.RepairCost).toLocaleString()}`; if(art.CraftCost > 0) { title += `\nСтоимость крафта: ${art.CraftCost.toLocaleString()}, стоимость арта без крафта: ${(art.LotPrice - art.CraftCost).toLocaleString()}`; } td = addElement("td", row, { style: "text-align: center;", innerText: `${art.OptimalRepairCombatsAmount}`, title: title }); } if(art.Uid) { let buyHrefElement = row.querySelector("a[onclick*='show_js_button']"); if(buyHrefElement) { buyHrefElement.addEventListener("click", function() { GM_setValue(art.Uid, JSON.stringify(art)); }, false); } } } } const grouppedArts = groupBy(arts.filter(x => x.LotType == LotType.Purchase), x => `${x.Id}${x.CraftInfo ? "#" + x.CraftInfo : ""}`); for(const artHash in grouppedArts) { const [artId, craftInfo] = artHash.split("#"); const isArt = artId in ArtifactInfo; const arts = grouppedArts[artHash]; //console.log(`artId: ${artId}, craftInfo: ${craftInfo}`); // Раскраска дохода if(artId) { // artId нету у лотов, которые ещё не парсятся целой категорией. Например у домов. Если ид нет в урл, то нет вообще if(gmGetBool("IncomeViewEnabled")) { arts.sort(function(a,b) { return isArt ? a.OptimalRepairCombatCost - b.OptimalRepairCombatCost : a.LotPrice - b.LotPrice; }); let basePrice = isArt ? arts[0].OptimalRepairCombatCost : arts[0].LotPrice; const shopCostInfo1 = getFormatedArtCost(artId); if(shopCostInfo1 && !craftInfo) { basePrice = shopCostInfo1.MinBattleCost; } else { for(const el of arts) { const secondLotPrice = isArt ? el.OptimalRepairCombatCost : el.LotPrice; if(secondLotPrice > basePrice) { basePrice = secondLotPrice; break; } } } for(const el of arts) { const goldImageElement = el.RowElement.querySelector("img[src*='gold.png']"); const priceTable = getParent(goldImageElement, "table"); const tr = addElement("tr", priceTable); let income; let title; if(isArt) { income = (basePrice - el.OptimalRepairCombatCost) * el.OptimalRepairCombatsAmount; const titel1 = shopCostInfo1 && !craftInfo ? "Цена за бой на предприятии" : "Цена за бой второго по дешевизне лота"; title = `Выгода (${titel1}: ${basePrice} - Цена за бой лота: ${el.OptimalRepairCombatCost}) * Количество боев лота: ${el.OptimalRepairCombatsAmount}`; } else { income = basePrice - el.LotPrice; title = `Выгода по сравнению со вторым по дешевизне лотом`; } addElement("td", tr, { colspan: 2, name: "income", innerText: income.toLocaleString(), style: `color: ${income < 0 ? "red" : "blue"};`, title: title }); } } } // Раскраска оптимального слома if(isArt) { const minCombatCost = arts.reduce((c, e) => Math.min(c, e.OptimalRepairCombatCost), arts[0].OptimalRepairCombatCost); for(const art of arts) { if(art.RowElement.cells.length > 5) { if(art.OptimalRepairCombatCost <= minCombatCost * (100 + CombatCostBestDeviation) / 100) { art.RowElement.cells[5].style.backgroundColor = CombatCostBestDeviationColor; } else if(art.OptimalRepairCombatCost <= minCombatCost * (100 + CombatCostGoodDeviation) / 100) { art.RowElement.cells[5].style.backgroundColor = CombatCostGoodDeviationColor; } } } if(shopCostSpan) { if(minCombatCost > shopCostInfo.MinBattleCost) { shopCostSpan.style.backgroundColor = CombatCostBestDeviationColor; } } } if(urlCat != "my") { // Запомним последнюю рыночную минимальную цену let strength = ArtifactInfo[artId]?.Strength; let fullArs = []; for(const art of arts) { if(!isArt || art.LotStrength == strength && art.RestLotStrength == strength || !StockArtifactIds.includes(artId)) { fullArs.push(art); } } if(fullArs.length > 0) { if(isArt) { let minOptimalRepairCombatCost = fullArs.reduce((c, e) => Math.min(c, e.OptimalRepairCombatCost), fullArs[0].OptimalRepairCombatCost); let minPriceArt; for(const art of fullArs) { if(art.OptimalRepairCombatCost == minOptimalRepairCombatCost) { minPriceArt = art; break; } } GM_setValue(LastBestLotDataName + artId, JSON.stringify(minPriceArt)); } else { const minLotPrice = fullArs.reduce((c, e) => Math.min(c, e.LotPrice), fullArs[0].LotPrice); GM_setValue(LastBestLotDataName + artId, minLotPrice); } } } } if(gmGetBool("IncomeViewEnabled")) { toggleIncomeRows(ss2Table); } return { Table: ss2Table, Arts: grouppedArts }; } function parseLotRow(row, urlArtId) { if(!row || row.nodeName != "TR") { return; } const goldImageElement = row.querySelector("img[src*='gold.png']"); if(!goldImageElement) { return; } const lotPrice = parseFloat(goldImageElement.parentNode.nextElementSibling.innerText.replace(/,/g, "")); let artId; let lotAmount = 1; const lotAmountExec = new RegExp(`(\\d+) ${isEn ? "pcs." : "шт."}`).exec(row.innerHTML); //console.log(lotAmountExec); if(lotAmountExec) { lotAmount = parseInt(lotAmountExec[1]); } const lotType = row.innerHTML.includes(LocalizedString.BuyNow) ? LotType.Purchase : LotType.Auction; const artImageRefElement = row.querySelector("a[href*='art_info.php']"); if(!artImageRefElement) { artId = urlArtId; const elementsList = Object.values(ElementsTypes).join("|"); const elementParse = (new RegExp(`gn_res/(${elementsList}).png`)).exec(row.innerHTML); if(elementParse) { artId = elementParse[1]; } if(row.innerHTML.includes("house_cert")) { const locationsList = Object.values(locations).map(x => x[2]).join("|"); const sertParse = (new RegExp(`<br>(${locationsList}) <b>`)).exec(row.innerHTML); if(sertParse) { artId = getSertIdByLocationName(sertParse[1]); } } const resourcesList = Object.values(ResourcesTypes).map(x => x.ImageName).join("|"); const resourceParse = (new RegExp(`/(${resourcesList}).png`)).exec(row.innerHTML); if(resourceParse) { artId = "res_" + resourceParse[1]; } if(row.innerHTML.includes("auc_dom")) { const locationsList = Object.values(locations).map(x => x[2]).join("|"); const sertParse = (new RegExp(`<br>(${locationsList}) <b>`)).exec(row.innerHTML); if(sertParse) { artId = getHouseIdByLocationName(sertParse[1]); } } if(row.innerHTML.includes("obj_share_pic")) { const locationsList = Object.values(locations).map(x => x[2]).join("|"); const sertParse = (new RegExp(`<br>(${locationsList}) <b>`)).exec(row.innerHTML); if(sertParse) { artId = getShaIdByLocationName(sertParse[1]); } } } else { artId = getUrlParamValue(artImageRefElement.href, "id"); var artUid = getUrlParamValue(artImageRefElement.href, "uid");; const strengthData = row.innerText.match(/\d+\/\d+/); var restLotStrength = parseInt(strengthData[0].split("/")[0]); var lotStrength = parseInt(strengthData[0].split("/")[1]); } const lotRef = row.querySelector("a[href^='auction_lot_protocol.php']"); const lotId = getUrlParamValue(lotRef.href, "id"); const artefact = new ArtefactLot(artUid, artId, lotStrength, restLotStrength, lotPrice, undefined, undefined, undefined, row, lotType, lotAmount, lotId); artefact.CalcOptRepair(); const lotCell = getParent(lotRef, "td"); const craftExec = /\[(([IDN]\d{1,2})?(E\d{1,2})?(A\d{1,2})?(W\d{1,2})?(F\d{1,2})?)\]/.exec(lotCell.innerHTML); //const craftExec = /\[(.+)\]/.exec(isMobileInterface ? lotRef.parentNode?.previousSibling?.textContent : lotRef.nextSibling?.textContent) || /\[(.+)\]/.exec(isMobileInterface ? lotRef.parentNode?.previousElementSibling?.innerHTML : lotRef.nextSibling?.nextElementSibling?.innerText); if(craftExec) { artefact.CraftInfo = craftExec[1]; artefact.CraftCost = getCraftCost(artefact.CraftInfo, ArtifactInfo[artefact.Id]?.CraftType); } return artefact; } function toggleIncomeRows(table) { for(const row of table.rows) { const goldImageElement = row.querySelector("img[src*='gold.png']"); if(!goldImageElement) { continue; } const incomeCell = row.querySelector("td[name='income']"); let income = 0; if(incomeCell) { income = parseFloat(incomeCell.innerText.replace(/\\s/g, "").replace(/,/g, ".")); } row.style.display = income > 0 || !gmGetBool("IncomeOnly") ? '' : 'none'; } } function ArtefactLot(uid, id, lotStrength, restLotStrength, lotPrice, optimalRepairCombatCost, optimalRepairStrength, optimalRepairCombatsAmount, rowElement, lotType, lotAmount, lotId) { this.Uid = uid; this.Id = id; this.LotStrength = lotStrength; this.RestLotStrength = restLotStrength; this.LotPrice = lotPrice; this.OptimalRepairCombatCost = optimalRepairCombatCost; this.OptimalRepairStrength = optimalRepairStrength; this.OptimalRepairCombatsAmount = optimalRepairCombatsAmount; this.RowElement = rowElement; this.LotType = lotType; this.LotAmount = lotAmount || 1; this.LotId = lotId; this.RepairCost = ArtifactInfo[this.Id]?.RepairCost; this.CraftInfo = undefined; this.CraftCost = undefined; this.ArtCost = undefined; this.CalcOptRepair = function() { if(this.Id in ArtifactInfo) { const optRepair = optimalRepair(this.LotPrice, this.RepairCost, this.LotStrength, this.RestLotStrength); this.OptimalRepairCombatCost = optRepair.CombatCost; this.OptimalRepairStrength = optRepair.Strength; this.OptimalRepairCombatsAmount = optRepair.CombatsAmount; } } this.GetLotInfo = function(wornStrength, wornRestStrength) { const optRepair = optimalRepair(this.LotPrice, ArtifactInfo[this.Id].RepairCost, this.LotStrength, this.RestLotStrength, wornStrength, wornRestStrength); //console.log(optRepair); let wornData = ""; if(optRepair.SpendedCombats) { wornData = `, ${LocalizedString.Spended}: ${optRepair.SpendedCombats}, ${LocalizedString.Remaining}: ${optRepair.CombatsAmount - optRepair.SpendedCombats}, ${LocalizedString.ResidualValue}: ${optRepair.ResidualValue}`; } return `${LocalizedString.BuyInfo}: ${LocalizedString.Cost}: ${this.LotPrice}, ${LocalizedString.Strength}: ${this.RestLotStrength}/${this.LotStrength}, ${LocalizedString.BattlePrice}: ${this.OptimalRepairCombatCost}, ${LocalizedString.Strength}: ${this.OptimalRepairStrength}, ${LocalizedString.Combats}: ${this.OptimalRepairCombatsAmount}${wornData}`; } } function logNewArtifactsIds(doc, containsRow) { if(!containsRow) { return; } //ShowBigData(doc.body.innerHTML) let newArtIds = []; let options = containsRow.getElementsByTagName("option"); for(const constoptionElement of options) { let valueParts = constoptionElement.value.split("#"); if(valueParts.length >= 2) { let artId = valueParts[1]; if(!(artId in ArtifactInfo)) { let category = ""; const re = new RegExp(`auction.php\\?cat=(\\w+)&sort=0&art_type=${artId}`); const ex = re.exec(document.documentElement.innerHTML); if(ex) { category = ex[1]; } newArtIds.push({ArtId: artId, Category: category}); } } } if(newArtIds.length > 0) { ShowBigData(newArtIds.reduce((t, e) => t + `, "${e.ArtId}": { Strength: 1, RepairCost: 1, MarketCategory: "${e.Category}", CraftType: 1 }`, "")); } } function ShowBigData(data) { addElement("TEXTAREA", document.body, { innerText: data }); } function AppendLotInfo(parentElement, artUid, restStrengthInfoElement) { restStrengthInfoElement = restStrengthInfoElement || parentElement; let artefact = getArtefactLot(artUid); if(parentElement && artefact.Id) { const wornStrengthData = /(\d{1,3})\/(\d{1,3})/.exec(restStrengthInfoElement.innerHTML); if(wornStrengthData && wornStrengthData.length >= 3) { var wornStrength = parseInt(wornStrengthData[2]); var wornRestStrength = parseInt(wornStrengthData[1]); } //console.log([wornStrength, wornRestStrength]); addElement("b", parentElement, { innerText: artefact.GetLotInfo(wornStrength, wornRestStrength) }); } } function getArtefactLot(artUid, artId) { let artefact; let artefactData = GM_getValue(artUid); if(artefactData && artefactData != "") { artefact = Object.assign(new ArtefactLot, JSON.parse(artefactData)); } if(!artefact) { artefact = new ArtefactLot(artUid, artId); } return artefact; } function getArtMinBattlePrice(artId, artUid) { const art = ArtifactInfo[artId]; const factoryPrice = parseInt(GM_getValue(ShopArtFactoryPriceName + artId, 0)); const factoryBattlePrice = round00(factoryPrice / art.Strength); const shopPrice = parseInt(GM_getValue(ShopArtShopPriceName + artId, 0)); const shopBattlePrice = round00(shopPrice / art.Strength); const lot = getSavedArtifactLot(artId, artUid); // if(artId == "sring17") { // console.log(`factoryPrice: ${factoryPrice}, shopPrice: ${shopPrice}, lot.OptimalRepairCombatCost: ${lot.OptimalRepairCombatCost}`); // } let hint = ""; let minBatlePrice = 0; if(minBatlePrice == 0 || minBatlePrice > factoryBattlePrice) { minBatlePrice = factoryBattlePrice; hint = `На производстве цена за бой: ${factoryBattlePrice}`; } if(minBatlePrice == 0 || minBatlePrice > shopBattlePrice) { minBatlePrice = shopBattlePrice; hint = `В магазине цена за бой: ${shopBattlePrice}`; } if(lot && (minBatlePrice == 0 || minBatlePrice > lot.OptimalRepairCombatCost)) { minBatlePrice = lot.OptimalRepairCombatCost; hint = `На рынке цена за бой: ${lot.OptimalRepairCombatCost}`; } return { minBatlePrice: minBatlePrice, hint: hint }; } function addAfterRepairCombatCostToInventory() { const artInfoDivs = document.querySelectorAll("div.inventory_item_div.inventory_item2"); //console.log(`addAfterRepairCombatCostToInventory artInfoDivs: ${artInfoDivs.length}`); for(const artInfoDiv of artInfoDivs) { const artIndex = parseInt(artInfoDiv.getAttribute("art_idx")); const artInfo = windowObject.arts[artIndex]; const artId = artInfo.art_id; if(artId in ArtifactInfo) { const repairCost = ArtifactInfo[artId].RepairCost; const afterRepairCombatCost = Math.round(repairCost * (parseInt(GM_getValue(SmithRewardPercentName, 100)) / 100) / getAfterRepairRestStrength(artInfo.durability2, SmithLevel)); if(gmGetBool("ShowAfterRepairBattleCostInInventory") && !isNaN(afterRepairCombatCost)) { const overlapInfoDiv = artInfoDiv.querySelector("div.art_durability_hidden"); const artMinBattlePrice = getArtMinBattlePrice(artId); const color = artMinBattlePrice.minBatlePrice < afterRepairCombatCost ? "red" : "green"; overlapInfoDiv.innerHTML += `<br><span style="color: ${color};">${afterRepairCombatCost}</span>`; const img = artInfoDiv.querySelector("img.cre_mon_image2.show_hint"); img.setAttribute("hint", img.getAttribute("hint") + "<br>" + artMinBattlePrice.hint); const customArtInfo = GM_getValue("CustomArtInfo" + artInfo.id, ""); if(customArtInfo != "") { img.setAttribute("hint", img.getAttribute("hint") + "<br>" + customArtInfo); } } const factoryPrice = parseInt(GM_getValue(ShopArtFactoryPriceName + artId, 0)); const shopPrice = parseInt(GM_getValue(ShopArtShopPriceName + artId, 0)); if(factoryPrice > 0 && shopPrice > 0 && shopPrice <= factoryPrice) { const brokenDiv = artInfoDiv.querySelector("div.inventory_item_normal.inventory_item_broken"); if(brokenDiv) { //console.log([artId, shopPrice, factoryPrice]); brokenDiv.style.borderColor = "green"; } } } } } function addBattlePriceToInventory() { // Выведем цену за бой let dressedArtsBattleCost = 0; for(let i = 0; i < windowObject.slots.length; i++) { let slot = windowObject.slots[i]; if(slot) { let artUid = parseInt(slot); let artInfo; for(const art of windowObject.arts) { if(art.id == artUid) { artInfo = art; break; } } if(artInfo) { const artBattleCost = getArtBattleCost(artInfo.art_id, artUid); dressedArtsBattleCost += artBattleCost; if(artBattleCost > 0) { const slotDiv = document.getElementById(`slot${i}`); const durabilityDiv = slotDiv.querySelector("div.art_durability_hidden"); let battleCostSpan = durabilityDiv.querySelector(`span#slot${i}BattleCost`); if(!battleCostSpan) { addElement("br", durabilityDiv); battleCostSpan = addElement("span", durabilityDiv, { id: `slot${i}BattleCost` }); } battleCostSpan.innerText = artBattleCost; } } } } const inventoryStatsDiv = document.querySelector("div.inventory_stats"); let dressedArtsBattleCostDiv = inventoryStatsDiv.querySelector("div#dressedArtsBattleCostDiv"); if(!dressedArtsBattleCostDiv) { addElement("div", inventoryStatsDiv, { class: "inv_stat_data show_hint", title: LocalizedString.BattlePrice, innerHTML: ` <div class="inv_stat_img_div"> <div class="set_wh100"></div> <img src="${GoldPng48}" class="mwh100"> </div> <div id="dressedArtsBattleCostDiv" class="inv_stat_text"></div>` }); dressedArtsBattleCostDiv = inventoryStatsDiv.querySelector("div#dressedArtsBattleCostDiv"); } dressedArtsBattleCostDiv.innerHTML = Math.round(dressedArtsBattleCost); } function getArtBattleCost(artId, artUid) { //console.log(`getArtBattleCost artId: ${artId}, artUid: ${artUid}`) let artifactLot = getSavedArtifactLot(artId, artUid, true); if(artifactLot) { return artifactLot.OptimalRepairCombatCost; } const art = ArtifactInfo[artId]; const factoryPrice = parseInt(GM_getValue(ShopArtFactoryPriceName + artId, 0)); // Фабричная цена if(factoryPrice > 0) { return round00(factoryPrice / art.Strength); } const shopPrice = parseInt(GM_getValue(ShopArtShopPriceName + artId, 0)); // Магазинная цена if(shopPrice > 0) { return round00(shopPrice / art.Strength); } artifactLot = getSavedArtifactLot(artId, artUid); if(artifactLot) { return artifactLot.OptimalRepairCombatCost; } return 0; } function getSavedArtifactLot(artId, artUid, uniqueOnly = false) { // Рыночная цена. Сначала пытаемся найти данные о лоте, если нет, то последние минимальные по данному арту let lastBestLotData = GM_getValue(artUid); if((!lastBestLotData || lastBestLotData == "") && !uniqueOnly) { lastBestLotData = GM_getValue(LastBestLotDataName + artId, ""); } if(lastBestLotData && lastBestLotData != "") { return Object.assign(new ArtefactLot, JSON.parse(lastBestLotData)); } } function addShopArtsPriceAndBattleCost() { let artInfoDivs = document.querySelectorAll("div.s_art"); for(const artInfoDiv of artInfoDivs) { let artPropDiv = artInfoDiv.querySelector("div.s_art_prop"); let artId = getArtIdFromArtInfoRef(artInfoDiv).Id; addShopArtPriceAndBattleCost(artId, artInfoDiv, artPropDiv); } } function addShopArtPriceAndBattleCost(artId, artInfoDiv, artPropDiv) { let price = 0; let isPriceFromLot = false; let needConvertResourcesToGold = false; let amountElement; let goldImage = artInfoDiv.querySelector("img[src*='gold']"); if(goldImage) { amountElement = goldImage.nextSibling || goldImage.parentNode.nextSibling; if(amountElement) { price += parseInt(amountElement.textContent.replace(/,/g, "")); } } let woodImage = artInfoDiv.querySelector("img[src*='wood']"); if(woodImage) { amountElement = woodImage.nextSibling || woodImage.parentNode.nextSibling; if(amountElement) { needConvertResourcesToGold = true; price += parseInt(amountElement.textContent) * 180; } } let oreImage = artInfoDiv.querySelector("img[src*='ore']"); if(oreImage) { amountElement = oreImage.nextSibling || oreImage.parentNode.nextSibling; if(amountElement) { needConvertResourcesToGold = true; price += parseInt(amountElement.textContent) * 180; } } let mercuryImage = artInfoDiv.querySelector("img[src*='mercury']"); if(mercuryImage) { amountElement = mercuryImage.nextSibling || mercuryImage.parentNode.nextSibling; if(amountElement) { needConvertResourcesToGold = true; price += parseInt(amountElement.textContent) * 360; } } let sulfurImage = artInfoDiv.querySelector("img[src*='sulfur']"); if(sulfurImage) { amountElement = sulfurImage.nextSibling || sulfurImage.parentNode.nextSibling; if(amountElement) { needConvertResourcesToGold = true; price += parseInt(amountElement.textContent) * 360; } } let crystalsImage = artInfoDiv.querySelector("img[src*='crystals']"); if(crystalsImage) { amountElement = crystalsImage.nextSibling || crystalsImage.parentNode.nextSibling; if(amountElement) { needConvertResourcesToGold = true; price += parseInt(amountElement.textContent) * 360; } } let gemsImage = artInfoDiv.querySelector("img[src*='gems']"); if(gemsImage) { amountElement = gemsImage.nextSibling || gemsImage.parentNode.nextSibling; if(amountElement) { needConvertResourcesToGold = true; price += parseInt(amountElement.textContent) * 360; } } if(price > 0) { GM_setValue(ShopArtShopPriceName + artId, price); } let battlePriceText = ""; const art = ArtifactInfo[artId]; if(art) { battlePriceText = `(${round00(price / art.Strength)})`; } if(price == 0) { let lastBestLotData = GM_getValue(LastBestLotDataName + artId, ""); if(lastBestLotData && lastBestLotData != "") { let artefact = Object.assign(new ArtefactLot, JSON.parse(lastBestLotData)); price = artefact.LotPrice; battlePriceText = `(${artefact.OptimalRepairCombatCost})`; isPriceFromLot = true; } } if(price > 0) { if(isPriceFromLot) { GM_deleteValue(ShopArtFactoryPriceName + artId); // Записался мусор GM_deleteValue(ShopArtShopPriceName + artId); } if(!getKeyByValue(EcostatDetailsIds, artId)) { GM_deleteValue(ShopArtFactoryPriceName + artId); // Если арт только магазинный - Записался мусор } let factoryPrice = parseInt(GM_getValue(ShopArtFactoryPriceName + artId, 0)); let factoryPriceText = ""; if(art && factoryPrice > 0 && factoryPrice != price) { factoryPriceText = ` / ${factoryPrice}(${round00(factoryPrice / art.Strength)})`; } if(!(battlePriceText == "" && factoryPriceText == "" && !needConvertResourcesToGold)) { addElement("label", artPropDiv, { innerText: ` = ${price}${battlePriceText}${factoryPriceText}` }); } } } function getKeyByValue(object, value) { return Object.keys(object).find(key => object[key] === value); } function getRequest(url, overrideMimeType) { return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: "GET", url: url, overrideMimeType: overrideMimeType || "text/html; charset=windows-1251", onload: function(response) { resolve((new DOMParser).parseFromString(response.responseText, "text/html")); }, onerror: function(error) { reject(error); } }); }); } function postRequest(url, data) { return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: "POST", url: url, headers: { "Content-Type": "application/x-www-form-urlencoded" }, data: data, onload: function(response) { resolve(response); }, onerror: function(error) { reject(error); } }); }); } function getFormatedArtCost(artId) { let shopPrice = GM_getValue(ShopArtShopPriceName + artId); let factoryPrice = GM_getValue(ShopArtFactoryPriceName + artId); if(shopPrice || factoryPrice) { let result = ""; let minBattleCost = 0; let minArtPrice = 0; let strength = ArtifactInfo[artId].Strength; if(shopPrice) { shopPrice = parseInt(shopPrice); minArtPrice = shopPrice; const shopBattleCost = round00(shopPrice / strength); minBattleCost = shopBattleCost; result += `${shopPrice}(${shopBattleCost})`; } if(factoryPrice && shopPrice != parseInt(factoryPrice)) { factoryPrice = parseInt(factoryPrice); minArtPrice = factoryPrice < shopPrice || minArtPrice == 0 ? factoryPrice : minArtPrice; const factoryBattleCost = round00(factoryPrice / strength); minBattleCost = minBattleCost > 0 && minBattleCost <= factoryBattleCost ? minBattleCost : factoryBattleCost; result += (result != "" ? " / " : "") + `${factoryPrice}(${factoryBattleCost})`; } return { CostInfo: result, MinBattleCost: minBattleCost, MinArtPrice: minArtPrice }; } } function getArtIdFromArtInfoRef(artInfoRefContainer) { let artId; let artUid; if(artInfoRefContainer) { const artInfoRef = artInfoRefContainer.querySelector("a[href*='art_info.php']"); if(artInfoRef) { artId = getUrlParamValue(artInfoRef.href, "id"); artUid = getUrlParamValue(artInfoRef.href, "uid"); } } return { Id: artId, Uid: artUid }; } function getObjectPrice() { let buyResForm = document.querySelector("form[name='buy_res']"); let artId = getArtIdFromArtInfoRef(buyResForm).Id; let tableElement = buyResForm.querySelector("table"); let amountCell = tableElement.rows[1].cells[2]; let priceCell = tableElement.rows[1].cells[3]; let amount = parseInt(amountCell.innerText.split("/")[0].replace(/,/g, "")); let price = parseInt(priceCell.innerText.replace(/,/g, "")); if(amount > 0) { // артефакт есть в наличии saveBestArtPrice(artId, price); } } function saveBestArtPrice(artId, newPrice, force) { let savedPrice = parseInt(GM_getValue(ShopArtFactoryPriceName + artId, 0)); if(newPrice < savedPrice || savedPrice == 0 || force) { GM_setValue(ShopArtFactoryPriceName + artId, newPrice); } } function openArtPriceSettings(artUid, artId, craftInfo) { if(showPupupPanel(ArtPriceSettingsName)) { return; } const artefact = getArtefactLot(artUid, artId); artefact.CraftInfo = craftInfo; const fieldsMap = []; const costLabel = createElement("label", { for: "openArtPriceSettingsLotPrice", innerText: LocalizedString.Cost + "\t" }); const openArtPriceSettingsLotPrice = createElement("input", { id: "openArtPriceSettingsLotPrice", type: "number", value: artefact.LotPrice }); openArtPriceSettingsLotPrice.addEventListener("change", function() { artefact.LotPrice = parseInt(this.value); calcArtefactLotAndSave(artefact); openArtPriceSettingsRefresh(artefact); }, false); const artCostLabel = createElement("label", { for: "artCostInput", innerText: LocalizedString.ArtCost + "\t" }); const artCostInput = createElement("input", { id: "artCostInput", type: "number", value: artefact.ArtCost }); artCostInput.addEventListener("change", function() { artefact.ArtCost = parseInt(this.value); calcArtefactLotAndSave(artefact); openArtPriceSettingsRefresh(artefact); }, false); fieldsMap.push([costLabel, openArtPriceSettingsLotPrice, artCostLabel, artCostInput]); const strengthLabel = createElement("label", { for: "openArtPriceSettingsLotStrength", innerText: LocalizedString.Strength + "\t" }); const openArtPriceSettingsLotStrength = createElement("input", { id: "openArtPriceSettingsLotStrength", type: "number", value: artefact.LotStrength }); openArtPriceSettingsLotStrength.addEventListener("change", function() { artefact.LotStrength = parseInt(this.value); calcArtefactLotAndSave(artefact); openArtPriceSettingsRefresh(artefact); }, false); const craftCostLabel = createElement("label", { for: "craftCostInput", innerText: LocalizedString.CraftCostString + "\t" }); const craftCostInput = createElement("input", { id: "craftCostInput", type: "number", value: artefact.CraftCost }); craftCostInput.addEventListener("change", function() { artefact.CraftCost = parseInt(this.value); calcArtefactLotAndSave(artefact); openArtPriceSettingsRefresh(artefact); }, false); const craftCostRecalcButton = createElement("input", { id: "craftCostRecalcButton", type: "button", value: LocalizedString.Recalc, title: LocalizedString.RecalcFromDaily }); craftCostRecalcButton.addEventListener("click", function() { craftCostRecalc(artefact, craftCostInput); }, false); fieldsMap.push([strengthLabel, openArtPriceSettingsLotStrength, craftCostLabel, craftCostInput, craftCostRecalcButton]); const restStrengthLabel = createElement("label", { for: "openArtPriceSettingsRestLotStrength", innerText: LocalizedString.RestStrength + "\t" }); const openArtPriceSettingsRestLotStrength = createElement("input", { id: "openArtPriceSettingsRestLotStrength", type: "number", value: artefact.RestLotStrength }); openArtPriceSettingsRestLotStrength.addEventListener("change", function() { artefact.RestLotStrength = parseInt(this.value); calcArtefactLotAndSave(artefact); openArtPriceSettingsRefresh(artefact); }, false); fieldsMap.push([restStrengthLabel, openArtPriceSettingsRestLotStrength]); const battlePriceLabel = createElement("label", { for: "openArtPriceSettingsOptimalRepairCombatCost", innerText: LocalizedString.BattlePrice + "\t" }); const openArtPriceSettingsOptimalRepairCombatCost = createElement("input", { id: "openArtPriceSettingsOptimalRepairCombatCost", type: "number", value: artefact.OptimalRepairCombatCost, disabled: "disabled" }); fieldsMap.push([battlePriceLabel, openArtPriceSettingsOptimalRepairCombatCost]); const optimalStrengthLabel = createElement("label", { for: "openArtPriceSettingsOptimalRepairStrength", innerText: LocalizedString.OptimalStrength + "\t" }); const openArtPriceSettingsOptimalRepairStrength = createElement("input", { id: "openArtPriceSettingsOptimalRepairStrength", type: "number", value: artefact.OptimalRepairStrength, disabled: "disabled" }); fieldsMap.push([optimalStrengthLabel, openArtPriceSettingsOptimalRepairStrength]); const combatsLabel = createElement("label", { for: "openArtPriceSettingsOptimalRepairCombatsAmount", innerText: LocalizedString.Combats + "\t" }); const openArtPriceSettingsOptimalRepairCombatsAmount = createElement("input", { id: "openArtPriceSettingsOptimalRepairCombatsAmount", type: "number", value: artefact.OptimalRepairCombatsAmount, disabled: "disabled" }); fieldsMap.push([combatsLabel, openArtPriceSettingsOptimalRepairCombatsAmount]); // Стоимость элементов const getYesterdayDailyPricesButton = createElement("input", { id: "getYesterdayDailyPricesButton", type: "button", value: isEn ? "Yesterday Daily's" : "Вчерашние с дейли", title: isEn ? "Get yesterday daily prices" : "Получить вчерашние цены с дейли" }); getYesterdayDailyPricesButton.addEventListener("click", async function() { await getDailyElementsPrices(); bindElementPrices(); }, false); const getMarketPricesButton = createElement("input", { id: "getMarketPricesButton", type: "button", value: isEn ? "Market prices" : "Рыночные цены", title: isEn ? "Get market prices" : "Получить рыночные цены" }); getMarketPricesButton.addEventListener("click", async function() { await getMarketElementPrices(); bindElementPrices(); }, false); fieldsMap.push([null, createElement("b", { innerText: (isEn ? "Elements price" : "Стоимость элементов"), style: "text-align: center; margin: auto; width: 90%; display: block;" }), getYesterdayDailyPricesButton, getMarketPricesButton]); const elementsPrices = JSON.parse(GM_getValue("ElementPrices", "{}")); let arr = []; for(let i = 0; i < ElementNames.length; i++) { const elementName = ElementNames[i]; const label = createElement("label", { for: `${elementName}Price`, innerText: elementName + "\t" }); const price = createElement("input", { id: `${elementName}Price`, type: "number", value: elementsPrices[elementName], onfocus: "this.select();" }); price.addEventListener("change", function() { elementsPrices[elementName] = this.value; GM_setValue("ElementPrices", JSON.stringify(elementsPrices)); }, false); arr.push(label); arr.push(price); //console.log(`i: ${i}, i % 2 == 1: ${i % 2 == 1}, arr.length: ${arr.length}, fieldsMap.length: ${fieldsMap.length}, price.id: ${price.id}`); if(i % 2 == 1 || i == ElementNames.length - 1) { fieldsMap.push(arr); arr = []; } } createPupupPanel(ArtPriceSettingsName, LocalizedString.EditLotInfo, fieldsMap); } function bindElementPrices() { const elementsPrices = JSON.parse(GM_getValue("ElementPrices", "{}")); for(const elementName of ElementNames) { document.getElementById(`${elementName}Price`).value = elementsPrices[elementName]; } } async function craftCostRecalc(artefact, craftCostInput) { //console.log(`Id: ${artefact.Id}, artefact.CraftInfo: ${artefact.CraftInfo}, CraftType: ${ArtifactInfo[artefact.ArtId]?.CraftType}`); artefact.CraftCost = getCraftCost(artefact.CraftInfo, ArtifactInfo[artefact.Id]?.CraftType, true); if(craftCostInput) { craftCostInput.value = artefact.CraftCost; } calcArtefactLotAndSave(artefact); openArtPriceSettingsRefresh(artefact); } function openArtPriceSettingsRefresh(artefact) { document.getElementById("openArtPriceSettingsLotPrice").value = artefact.LotPrice; document.getElementById("openArtPriceSettingsOptimalRepairCombatCost").value = artefact.OptimalRepairCombatCost; document.getElementById("openArtPriceSettingsOptimalRepairStrength").value = artefact.OptimalRepairStrength; document.getElementById("openArtPriceSettingsOptimalRepairCombatsAmount").value = artefact.OptimalRepairCombatsAmount; } function calcArtefactLotAndSave(artefact) { if(artefact.ArtCost > 0 || artefact.CraftCost > 0) { artefact.LotPrice = (artefact.ArtCost || 0) + (artefact.CraftCost || 0); } if(artefact.LotPrice > 0 && artefact.LotStrength > 0 && artefact.RestLotStrength > 0) { const artRepairCost = ArtifactInfo[artefact.Id].RepairCost; const optimalRepairData = optimalRepair(artefact.LotPrice, artRepairCost, artefact.LotStrength, artefact.RestLotStrength); artefact.OptimalRepairCombatCost = optimalRepairData.CombatCost; artefact.OptimalRepairStrength = optimalRepairData.Strength; artefact.OptimalRepairCombatsAmount = optimalRepairData.CombatsAmount; } GM_setValue(artefact.Uid, JSON.stringify(artefact)); } function getOrCreateAndResizeDropdown(baseElement, style, zIndex) { const dropdownId = `${baseElement.id}Dropdown`; let dropdown = document.getElementById(dropdownId); if(!dropdown) { dropdown = addElement("div", document.body, { id: dropdownId, style: `position: absolute; z-index: ${zIndex || baseElement.style.zIndex};` + (style || "") }); let hideTimer; const dropdownTimeout = 100; baseElement.addEventListener("mouseenter", function() { clearTimeout(hideTimer); if(dropdown.style.display == "none") { setTimeout(function() { dropdown.style.display = "block"; }, dropdownTimeout); } }, false); baseElement.addEventListener("mouseleave", function() { hideTimer = setTimeout(function() { dropdown.style.display = "none"; }, dropdownTimeout); }, false); dropdown.addEventListener("mouseenter", function() { clearTimeout(hideTimer); }, false); dropdown.addEventListener("mouseleave", function() { hideTimer = setTimeout(function() { dropdown.style.display = "none"; }, dropdownTimeout); }, false); } const baseElementRect = baseElement.getBoundingClientRect(); dropdown.style.top = `${baseElementRect.bottom + window.scrollY + 1}px`; dropdown.style.left = `${baseElementRect.left}px`; return dropdown; } function countResources() { if(!gmGetBool("ShowResourcesCostPanel")) { return; } let dropdown, foreColor; let gold, wood, ore, mercury, sulfur, crystals, gems, diamonds; const topResTable = document.getElementById("top_res_table"); if(topResTable) { gold = parseInt(topResTable.querySelector("img[src*='gold.png']").parentNode.nextElementSibling.innerText.replace(/,/g, "")); wood = parseInt(topResTable.querySelector("img[src*='wood.png']").parentNode.nextElementSibling.innerText.replace(/,/g, "")); ore = parseInt(topResTable.querySelector("img[src*='ore.png']").parentNode.nextElementSibling.innerText.replace(/,/g, "")); mercury = parseInt(topResTable.querySelector("img[src*='mercury.png']").parentNode.nextElementSibling.innerText.replace(/,/g, "")); sulfur = parseInt(topResTable.querySelector("img[src*='sulfur.png']").parentNode.nextElementSibling.innerText.replace(/,/g, "")); crystals = parseInt(topResTable.querySelector("img[src*='crystals.png']").parentNode.nextElementSibling.innerText.replace(/,/g, "")); gems = parseInt(topResTable.querySelector("img[src*='gems.png']").parentNode.nextElementSibling.innerText.replace(/,/g, "")); diamonds = parseFloat(topResTable.querySelector("img[src*='diamonds.png']").parentNode.parentNode.nextElementSibling.innerText.replace(/,/g, "")); dropdown = getOrCreateAndResizeDropdown(topResTable, `color: ${topResTable.style.color}; padding: 2px 3px 2px 3px; white-space: nowrap; background: url(https://dcdn2.heroeswm.ru/i/top/bkg2.jpg);`, 5); foreColor = topResTable.style.color; } const resourcesPanel = document.getElementById("ResourcesPanel"); if(resourcesPanel) { gold = parseInt(resourcesPanel.querySelector("img[src*='gold.png']").nextElementSibling.innerText.replace(/,/g, "")); wood = parseInt(resourcesPanel.querySelector("img[src*='wood.png']").nextElementSibling.innerText.replace(/,/g, "")); ore = parseInt(resourcesPanel.querySelector("img[src*='ore.png']").nextElementSibling.innerText.replace(/,/g, "")); mercury = parseInt(resourcesPanel.querySelector("img[src*='mercury.png']").nextElementSibling.innerText.replace(/,/g, "")); sulfur = parseInt(resourcesPanel.querySelector("img[src*='sulfur.png']").nextElementSibling.innerText.replace(/,/g, "")); crystals = parseInt(resourcesPanel.querySelector("img[src*='crystals.png']").nextElementSibling.innerText.replace(/,/g, "")); gems = parseInt(resourcesPanel.querySelector("img[src*='gems.png']").nextElementSibling.innerText.replace(/,/g, "")); diamonds = parseFloat(resourcesPanel.querySelector("img[src*='diamonds.png']").nextElementSibling.innerText.replace(/,/g, "")); dropdown = getOrCreateAndResizeDropdown(resourcesPanel, `color: #ccb89f; padding: 2px 3px 2px 3px; white-space: nowrap; background: #592c08;`, 101); foreColor = "#ccb89f"; } if(dropdown) { const table = addElement("table", dropdown, { style: `color: ${foreColor};` }); dropdown.style.display = "block"; let tr; if(wood > 0) { tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.wood, style: `color: ${foreColor};` }); addElement("td", tr, { innerText: `${wood} * 180 =`, style: `color: ${foreColor}; text-align: right;` }); addElement("td", tr, { innerText: `${(wood * 180).toLocaleString()}`, style: `color: ${foreColor}; text-align: right;` }); } if(ore > 0) { tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.ore, style: `color: ${foreColor};` }); addElement("td", tr, { innerText: `${ore} * 180 =`, style: `color: ${foreColor}; text-align: right;` }); addElement("td", tr, { innerText: `${(ore * 180).toLocaleString()}`, style: `color: ${foreColor}; text-align: right;` }); } if(mercury > 0) { tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.mercury, style: `color: ${foreColor};` }); addElement("td", tr, { innerText: `${mercury} * 360 =`, style: `color: ${foreColor}; text-align: right;` }); addElement("td", tr, { innerText: `${(mercury * 360).toLocaleString()}`, style: `color: ${foreColor}; text-align: right;` }); } if(sulfur > 0) { tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.sulfur, style: `color: ${foreColor};` }); addElement("td", tr, { innerText: `${sulfur} * 360 =`, style: `color: ${foreColor}; text-align: right;` }); addElement("td", tr, { innerText: `${(sulfur * 360).toLocaleString()}`, style: `color: ${foreColor}; text-align: right;` }); } if(crystals > 0) { tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.crystals, style: `color: ${foreColor};` }); addElement("td", tr, { innerText: `${crystals} * 360 =`, style: `color: ${foreColor}; text-align: right;` }); addElement("td", tr, { innerText: `${(crystals * 360).toLocaleString()}`, style: `color: ${foreColor}; text-align: right;` }); } if(gems > 0) { tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.gems, style: `color: ${foreColor};` }); addElement("td", tr, { innerText: `${gems} * 360 =`, style: `color: ${foreColor}; text-align: right;` }); addElement("td", tr, { innerText: `${(gems * 360).toLocaleString()}`, style: `color: ${foreColor}; text-align: right;` }); } const totalResourcesValue = wood * 180 + ore * 180 + mercury * 360 + sulfur * 360 + crystals * 360 + gems * 360; if(totalResourcesValue > 0) { tr = addElement("tr", table, { style: "color: yellow; font-weight: bold;" }); addElement("td", tr, { innerText: LocalizedString.Total, style: "color: yellow;" }); addElement("td", tr); addElement("td", tr, { innerText: `${totalResourcesValue.toLocaleString()}`, style: "color: yellow; text-align: right;" }); } tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.gold, style: `color: ${foreColor};` }); addElement("td", tr); addElement("td", tr, { innerText: gold.toLocaleString(), style: `color: ${foreColor}; text-align: right;` }); if(totalResourcesValue > 0) { tr = addElement("tr", table, { style: "color: yellow; font-weight: bold;" }); addElement("td", tr, { innerText: LocalizedString.Total, style: "color: yellow;" }); addElement("td", tr); addElement("td", tr, { innerText: (gold + totalResourcesValue).toLocaleString(), style: "color: yellow; text-align: right;" }); } if(diamonds > 0) { tr = addElement("tr", table); addElement("td", tr, { innerText: LocalizedString.diamonds, style: `color: ${foreColor};` }); addElement("td", tr, { innerText: `${diamonds} * 5000 = `, style: `color: ${foreColor}; text-align: right;` }); addElement("td", tr, { innerText: (diamonds * 5000).toLocaleString(), style: `color: ${foreColor}; text-align: right;` }); tr = addElement("tr", table, { style: "color: yellow; font-weight: bold;" }); addElement("td", tr, { innerText: LocalizedString.Total, style: "color: yellow;" }); addElement("td", tr); addElement("td", tr, { innerText: (gold + totalResourcesValue + diamonds * 5000).toLocaleString(), style: "color: yellow; text-align: right;" }); } dropdown.style.display = "none"; } } function certificateAuctionReferences() { const houseCertificates = document.querySelectorAll("img[src*='house_cert.jpg']"); let table; let totalAmount = 0; let total = 0; for(const houseCertificate of houseCertificates) { const cell = houseCertificate.parentNode; const row = cell.parentNode; if(!table) { table = row.parentNode; } const sectorRef = row.querySelector("a[href*='map.php']"); const locationNumber = getLocationNumberByCoordinate(getUrlParamValue(sectorRef.href, "cx"), getUrlParamValue(sectorRef.href, "cy")); const artId = getSertIdByLocationNumber(locationNumber); const auctionLotUrl = `/auction.php?cat=cert&sort=0&art_type=${artId}`; cell.removeChild(houseCertificate); const auctionLotRef = addElement("a", cell, { href: auctionLotUrl }); auctionLotRef.appendChild(houseCertificate); const amountCell = row.cells[2]; const amount = parseInt(/(\d+)%/.exec(amountCell.innerHTML)[1]); const marketPrice = parseInt(GM_getValue(LastBestLotDataName + artId, 0)); //console.log(`marketPrice: ${marketPrice}, amount: ${amount}, artId: ${artId}`); addElement("td", row, { innerText: (marketPrice > 0 ? marketPrice.toLocaleString() : "" ), class: "wbwhite", style: "text-align: right;" }); addElement("td", row, { innerText: (marketPrice > 0 ? (amount * marketPrice).toLocaleString() : ""), class: "wbwhite", style: "text-align: right;" }); totalAmount += amount; total += amount * marketPrice; } if(table) { const titleRow = table.rows[0]; addElement("td", titleRow, { innerText: LocalizedString.MarketPrice, class: "wbwhite", style: "text-align: center; font-weight: bold;", title: LocalizedString.ToUpdateTheCertificatePrice }); addElement("td", titleRow, { innerText: LocalizedString.Total, class: "wbwhite", style: "text-align: center; font-weight: bold;" }); const totalRow = addElement("tr", table); addElement("td", totalRow, { innerText: LocalizedString.Total, colspan: 2, class: "wbwhite", style: "font-weight: bold;" }); addElement("td", totalRow, { innerText: totalAmount.toLocaleString(), class: "wbwhite", style: "text-align: right; font-weight: bold;" }); addElement("td", totalRow, { innerText: "", class: "wbwhite", style: "text-align: right; font-weight: bold;" }); addElement("td", totalRow, { innerText: total.toLocaleString(), class: "wbwhite", style: "text-align: right; font-weight: bold;" }); } } function main() { countResources(); if(location.pathname == '/pl_info_realty.php') { certificateAuctionReferences(); } if(location.pathname == '/auction.php') { const table = document.querySelector("table.wb"); const catContainer = table.rows[1].cells[0]; const catContainerFirstChild = catContainer.firstChild; const lot = createElement("b", { innerHTML: `<center><a href="auction_new_lot.php">Выставить лот</a></center>` }); catContainer.insertBefore(lot, catContainerFirstChild); const br = createElement("br"); catContainer.insertBefore(br, catContainerFirstChild); extendLotsTable(document, location.href, false); } if(location.pathname == '/art_info.php') { const artId = getUrlParamValue(location.href, "id"); const artUid = getUrlParamValue(location.href, "uid");; const s_art_insideDiv = document.querySelector("div.s_art_inside"); if(artUid) { AppendLotInfo(s_art_insideDiv, artUid); const home_art_infoDiv = document.querySelector("div.home_art_info"); const buttonsDiv = home_art_infoDiv.nextElementSibling; if(buttonsDiv) { const art_info_mod_textDiv = document.querySelector("div.art_info_mod_text"); if(art_info_mod_textDiv) { var craftInfo = /\[(.+)\]/.exec(art_info_mod_textDiv.innerText)[1]; //console.log(craftInfo); } const openArtPriceSettingsRef = addElement("a", buttonsDiv, { href: "#", style: "text-decoration: none;", innerHTML: ` <div class="s_art_btn_small s_art_btn_margin" style="padding: 0.4em 0;font-size: 11px;"> <div class="s_art_prop_amount_icon s_art_bold_font" style="padding-left: 0;">${LocalizedString.EditLotInfo}</div></div>` }); openArtPriceSettingsRef.addEventListener("click", function() { openArtPriceSettings(artUid, artId, craftInfo); }, false); } } else { const tables = s_art_insideDiv.querySelectorAll("table"); if(tables.length == 3) { // Три таблицы с ценой, характеристиками и стоимостью ремонта const costInfoRow = tables[0].rows[0]; const td = addElement("td", costInfoRow); addShopArtPriceAndBattleCost(artId, costInfoRow, td); } else { const div = addElement("div"); s_art_insideDiv.childNodes[1].after(div); addShopArtPriceAndBattleCost(artId, div, div); } } } if(location.pathname == '/mod_workbench.php') { const formElement = document.querySelector("form[name='fmain']"); if(formElement) { const idInput = formElement.querySelector("input[name='art_id2']"); if(idInput && idInput.value != "") { AppendLotInfo(formElement, idInput.value, getParent(formElement, "TABLE")); } } } if(location.pathname == '/inventory.php') { drawArtsTtransferPanel(); attachArtTtransferActionsToItems(); addAfterRepairCombatCostToInventory(); observe(document.querySelector("div#inventory_block"), function() { attachArtTtransferActionsToItems(); addAfterRepairCombatCostToInventory(); }); addBattlePriceToInventory(); observe([inventoryArtsPanelSelector, inventoryStatsPanelSelector], addBattlePriceToInventory); } if(location.pathname == "/auction_new_lot.php") { auctionNewLot(); } if(location.pathname == '/shop.php') { addShopArtsPriceAndBattleCost(); } if(location.pathname == '/object-info.php') { getObjectPrice(); } if(location.pathname == '/ecostat.php') { let tableDiv = document.getElementById("tableDiv"); let ecostatTable = tableDiv.querySelector("table"); for(const row of ecostatTable.rows) { let ref = row.cells[0].querySelector("a"); if(ref) { let ecostatDetailsId = getUrlParamValue(ref.href, "id"); if(ecostatDetailsId in EcostatDetailsIds) { let artId = EcostatDetailsIds[ecostatDetailsId]; let averagePrice = parseInt(row.cells[2].innerText.replace(/,/g, "")); let currentSavedFactoryPrice = parseInt(GM_getValue("ShopArtFactoryPrice_" + artId, 0)); //console.log([artId, averagePrice, currentSavedFactoryPrice]); if(averagePrice > 0 && (currentSavedFactoryPrice > 0 && averagePrice < currentSavedFactoryPrice || currentSavedFactoryPrice == 0)) { GM_setValue("ShopArtFactoryPrice_" + artId, averagePrice); } } } } } if(location.pathname == '/ecostat_details.php') { let tableDiv = document.getElementById("tableDiv"); let ecostatTable = tableDiv.querySelector("table"); let artId = getUrlParamValue(location.href, "r"); if(!artId) { let ecostatDetailsId = getUrlParamValue(location.href, "id"); if(ecostatDetailsId) { artId = EcostatDetailsIds[ecostatDetailsId]; } } //console.log(`artId: ${artId}`); if(artId) { let minPrice = 0; for(const row of ecostatTable.rows) { let amount = parseInt(row.cells[2].innerText); if(amount > 0) { let price = parseInt(row.cells[3].innerText.replace(/,/g, "")); if(price < minPrice || minPrice == 0) { minPrice = price; } } } //console.log(`minPrice: ${minPrice}`); if(minPrice > 0) { saveBestArtPrice(artId, minPrice, true); } else { GM_deleteValue(ShopArtFactoryPriceName + artId); // На предприятиях кончилось } } } if(location.pathname == '/home.php' || location.pathname == '/pl_info.php') { addBattlePrice(); let artsUpdatePanel; let statsUpdatePanel; if(location.pathname == '/home.php') { if(isNewPersonPage) { artsUpdatePanel = document.querySelector("div#inv_doll_stats"); } else { artsUpdatePanel = getParent(document.querySelector("div.arts_info.shop_art_info"), "table"); } statsUpdatePanel = isNewPersonPage ? document.getElementById("home_css_stats_wrap_div") : getParent(document.querySelector("img[src*='attr_attack']"), "table", 2); } if(location.pathname == '/pl_info.php') { artsUpdatePanel = getParent(document.querySelector("div[class^='slot']"), "div"); statsUpdatePanel = getParent(document.querySelector("img[src*='attr_attack']"), "table"); } if(artsUpdatePanel) { observe([statsUpdatePanel, artsUpdatePanel], addBattlePrice); } } createPersonPageSellResourceReferences(); } function addBattlePrice() { let artDivs = document.querySelectorAll("div.arts_info.shop_art_info"); let battleCost = 0; for(const artDiv of artDivs) { let artId = getArtIdFromArtInfoRef(artDiv).Id; let artUid = getArtIdFromArtInfoRef(artDiv).Uid; let artBattleCost = getArtBattleCost(artId, artUid); if(artBattleCost > 0) { let artDurabilityDiv = artDiv.querySelector("div.art_durability_hidden"); if(!artDurabilityDiv.innerText.includes(`\n${artBattleCost}`)) { artDurabilityDiv.innerText += `\n${artBattleCost}`; } } battleCost += artBattleCost; } let addbonusesImage = document.querySelector("img[src*='attr_addbonuses']"); if(addbonusesImage && battleCost > 0) { battleCost = Math.round(battleCost); if(location.pathname == '/home.php') { let hwmOptimalRepairAtMarketBattlePriceContainer = document.getElementById("hwmOptimalRepairAtMarketBattlePriceContainer"); if(!hwmOptimalRepairAtMarketBattlePriceContainer) { let tr = addbonusesImage.parentNode.parentNode.parentNode; if(isNewPersonPage) { const ff = addElement("div", tr, { class: "inv_stat_data home_stat_data show_hint", title: `${LocalizedString.BattlePrice}` }); addElement("div", ff, { innerHTML: `<img src="${GoldPng48}" alt="" title="${LocalizedString.BattlePrice}" width="24" height="24" border="0">`, class: "inv_stat_img_div home_stat_img_div" }); addElement("div", ff, { innerHTML: `<b id="hwmOptimalRepairAtMarketBattlePriceContainer"></b>`, align: "center", class: "inv_stat_text home_stat_text" }); } else { addElement("td", tr, { innerHTML: `<img src="${GoldPng48}" alt="" title="${LocalizedString.BattlePrice}" width="24" height="24" border="0">`, style: "padding-left: 3px;" }); addElement("td", tr, { innerHTML: `${LocalizedString.BattlePrice}: `, align: "center", style: "padding-left: 3px;" }); addElement("td", tr, { innerHTML: `<b id="hwmOptimalRepairAtMarketBattlePriceContainer"></b>`, align: "center", style: "padding-left: 3px;" }); } hwmOptimalRepairAtMarketBattlePriceContainer = document.getElementById("hwmOptimalRepairAtMarketBattlePriceContainer"); } hwmOptimalRepairAtMarketBattlePriceContainer.innerHTML = `${battleCost}`; } if(location.pathname == '/pl_info.php') { let hwmOptimalRepairAtMarketBattlePriceContainer = document.getElementById("hwmOptimalRepairAtMarketBattlePriceContainer"); if(!hwmOptimalRepairAtMarketBattlePriceContainer) { const tableElement = addbonusesImage.parentNode.parentNode.parentNode.parentNode; hwmOptimalRepairAtMarketBattlePriceContainer = addElement("tr", tableElement, { id: "hwmOptimalRepairAtMarketBattlePriceContainer" }); } hwmOptimalRepairAtMarketBattlePriceContainer.innerHTML = `<td><img src="${GoldPng48}" alt="" title="${LocalizedString.BattlePrice}" width="24" height="24" border="0"></td><td align="center"><b>${battleCost}</b></td>`; } } } function getUrlParamValue(url, paramName) { return (new URLSearchParams(url.split("?")[1])).get(paramName); } function gmGetBool(valueName, defaultValue = false) { const value = GM_getValue(valueName); if(value) { if(typeof(value) == "string") { return value == "true"; } if(typeof(value) == "boolean") { return value; } } return defaultValue; } function getParent(element, parentType, number = 1) { if(!element) { return; } let result = element; let foundNumber = 0; while(result = result.parentNode) { if(result.nodeName.toLowerCase() == parentType.toLowerCase()) { foundNumber++; if(foundNumber == number) { return result; } } } } async function startRepairWaiting() { let leader = getRepairQueueLeader(); if(gmGetBool("BeginRepairOnSmithFree") && leader && isHeartOnPage) { let savedRepairEnd = GM_getValue("RepairEnd"); if(!savedRepairEnd || parseInt(savedRepairEnd) <= Date.now()) { let doc = await getRequest("/mod_workbench.php?type=repair"); parseSmithPage(doc); leader = getRepairQueueLeader(); if(leader) { savedRepairEnd = GM_getValue("RepairEnd"); if(savedRepairEnd) { setTimeout(startRepairWaiting, parseInt(savedRepairEnd) - Date.now()); } else { const butValue = isEn ? "Repair" : "%CE%F2%F0%E5%EC%EE%ED%F2%E8%F0%EE%E2%E0%F2%FC"; await postRequest("/mod_workbench.php", `action=repair&art_id=${leader.Id}&art_id2=${leader.Id}&but=${butValue}`); removeArtFromSmithSchedule(leader); doc = await getRequest("/mod_workbench.php?type=repair"); parseSmithPage(doc); } } } else { setTimeout(startRepairWaiting, parseInt(savedRepairEnd) - Date.now()); } } } function getRepairQueueLeader() { let savedSmithSchedulingRecords = GM_getValue("SmithSchedulingRecords"); if(savedSmithSchedulingRecords) { const smithSchedulingRecords = savedSmithSchedulingRecords.split("&").map(x => JSON.parse(x)); return smithSchedulingRecords[0]; } } async function findClanDepository() { if(location.pathname=='/map.php' && location.search == '') { //console.log(`ClanDepository: ${GM_getValue("ClanDepository")}, ClanDepositoryLocations: ${GM_getValue("ClanDepositoryLocations")}`); GM_deleteValue("InClanDepositorySector"); const mapRightBlock = document.getElementById("map_right_block"); if(mapRightBlock) { const sklad = mapRightBlock.querySelector("a[href^='sklad_info.php']"); if(sklad) { GM_setValue("InClanDepositorySector", true); } const clanDepository = GM_getValue("ClanDepository"); if(sklad) { if(!clanDepository || clanDepository != sklad.href || !GM_getValue("ClanDepositoryLocations")) { GM_setValue("ClanDepository", sklad.href); const doc = await getRequest(sklad.href); const stockSectorRefs = Array.from(doc.querySelectorAll("a[href^='map.php?cx']")); const stockLocationNumbers = stockSectorRefs.map(x => getLocationNumberFromMapUrlByXy(x.href)); //console.log(`ClanDepositoryLocations: ${stockLocationNumbers.join()}`); GM_setValue("ClanDepositoryLocations", stockLocationNumbers.join()); } } else { if(clanDepository) { const clanDepositoryLocations = GM_getValue("ClanDepositoryLocations", "").split(",").filter(x => x != "").map(x => parseInt(x)); if(clanDepositoryLocations.includes(playerLocationNumber)) { // Склада - нет, а мы в его секторе. Значит игрок вышел из клана GM_deleteValue("ClanDepository"); GM_deleteValue("ClanDepositoryLocations"); } } } } } } async function findClanDepositoryRepair() { const clanDepository = GM_getValue("ClanDepository"); //console.log(clanDepository); if(isHeartOnPage && clanDepository && !GM_getValue("RepairEnd") && gmGetBool("BeginRepairClanDepository") && gmGetBool("InClanDepositorySector")) { const clanDepositoryLastRequestedTime = GM_getValue("ClanDepositoryLastRequestedTime"); //console.log(`clanDepositoryLastRequestedTime: ${clanDepositoryLastRequestedTime}, ${((Date.now() - parseInt(clanDepositoryLastRequestedTime)) < 60 * 1000)}`); if(clanDepositoryLastRequestedTime && ((Date.now() - parseInt(clanDepositoryLastRequestedTime)) < 60 * 1000)) { setTimeout(findClanDepositoryRepair, 40 * (1 + Math.random()) * 1000); return; } const doc = await getRequest(clanDepository); const repairRefs = doc.querySelectorAll("a[href*='sklad_info.php']"); //sklad_info.php?id=175&cat=-1&action=repair&repair_id=418409576&sign=4d0c5f8dfcc71ed0619916bdcbac8d9b GM_setValue("ClanDepositoryLastRequestedTime", Date.now()); let maxCost = 0; let repair; for(const repairRef of repairRefs) { if(getUrlParamValue(repairRef.href, "action") == "repair") { const td = getParent(repairRef, "td"); const re = new RegExp(`${ isEn ? "Your cut" : "Вам" }: ([\\d,]+)`); //console.log(`td.innerHTML: ${td.innerHTML}, re: ${re}`); const result = re.exec(td.innerHTML); const cost = parseInt(result[1].replace(/,/g, "")); if(maxCost == 0 || cost > maxCost) { maxCost = cost; repair = repairRef; } } } if(repair) { console.log(`repair found: ${repair.href}, maxCost: ${maxCost}`); let doc = await getRequest("/mod_workbench.php?type=repair"); parseSmithPage(doc); if(!GM_getValue("RepairEnd")) { await getRequest(repair.href); doc = await getRequest("/mod_workbench.php?type=repair"); parseSmithPage(doc); } } else { console.log("Clan depository needn't for repair"); setTimeout(findClanDepositoryRepair, 40 * (1 + Math.random()) * 1000); } } } async function checkClanDepositoryNeedRepair() { const clanDepository = GM_getValue("ClanDepository"); const lastClanDepositoryNeedRepairRequestDate = parseInt(GM_getValue("LastClanDepositoryNeedRepairRequestDate", 0)); if(isHeartOnPage && clanDepository && (GM_getValue("ShowClanDepositoryRepairIcon", "0") == "2" || GM_getValue("ShowClanDepositoryRepairIcon", "0") == "1" && !GM_getValue("RepairEnd"))) { //console.log(`clanDepository: ${clanDepository}, isOnClanDepositoryPage: ${location.href.includes(clanDepository)}, lastClanDepositoryNeedRepairRequestDate: ${Date.now() - lastClanDepositoryNeedRepairRequestDate}`); if(location.href.includes(clanDepository) || Date.now() - lastClanDepositoryNeedRepairRequestDate > 1000 * 60) { const doc = location.href.includes(clanDepository) ? document : await getRequest(clanDepository); parseClanDepositoryNeedRepair(doc); } const lastClanDepositoryNeedRepairRequestResult = GM_getValue("LastClanDepositoryNeedRepairRequestResult"); toggleHomeIndicator("https://dcdn.heroeswm.ru/i/castle_im/btn_forge.png", lastClanDepositoryNeedRepairRequestResult, clanDepository, !!lastClanDepositoryNeedRepairRequestResult, "StockRepairSignTitle", "StockRepairSign"); } } function parseClanDepositoryNeedRepair(doc) { GM_setValue("LastClanDepositoryNeedRepairRequestDate", Date.now()); const bolds = doc.querySelectorAll("b"); for(const bold of bolds) { if(bold.innerHTML.includes(isEn ? "Artifacts to repair" : "Артефакты для ремонта")) { var artsForRepairContainer = getParent(bold, "tr").nextElementSibling; } } if(artsForRepairContainer) { const arts = artsForRepairContainer.querySelectorAll("a[href^='art_info.php']"); const lastClanDepositoryNeedRepairRequestResult = isEn ? `There are ${arts.length} artifacts in stock in need of repair` : `На складе ${arts.length} артефакт(а)(ов) требует ремонта`; //console.log(lastClanDepositoryNeedRepairRequestResult); GM_setValue("LastClanDepositoryNeedRepairRequestResult", lastClanDepositoryNeedRepairRequestResult); } else { GM_deleteValue("LastClanDepositoryNeedRepairRequestResult"); } } async function smithScheduling() { if(!gmGetBool("SmithSchedulingEnabled")) { return; } const repairRefs = document.querySelectorAll("a[href*='sklad_info.php']"); //sklad_info.php?id=175&cat=-1&action=repair&repair_id=418409576&sign=4d0c5f8dfcc71ed0619916bdcbac8d9b for(const repairRef of repairRefs) { if(getUrlParamValue(repairRef.href, "action") == "repair") { repairRef.addEventListener("click", function() { GM_setValue("RepairAwaiting", Date.now()); }, false); } } if(location.pathname=='/mod_workbench.php' && getUrlParamValue(location.href, "type") == "repair") { const artsInfos = parseSmithPage(document); const baseTable = document.querySelector("table.wbwhite"); const tr = addElement("tr", baseTable); const container = addElement("td", tr); refreshSmithScheduleTable(container, artsInfos); refreshSmithBrokenArtsTable(container, artsInfos); selectItemForRepair(); const but = document.querySelector("input[name='but']"); if(but) { but.addEventListener("click", function() { GM_setValue("RepairAwaiting", Date.now()); }, false); } } else if(GM_getValue("RepairAwaiting")) { const doc = await getRequest("/mod_workbench.php?type=repair"); parseSmithPage(doc); // Обновим информацию, т.к. ожидаем, что начали ремонт не через основной интерфейс } GM_deleteValue("RepairAwaiting"); startRepairWaiting(); updateRepairTimerPanel("SmithMoratoriumPanel"); } function selectItemForRepair() { const savedSmithSchedulingRecords = GM_getValue("SmithSchedulingRecords"); const savedRepairEnd = GM_getValue("RepairEnd"); const artsList = document.querySelector("select[name='art_id']"); if(/*!savedRepairEnd && */savedSmithSchedulingRecords && artsList && artsList.value == "0" && !gmGetBool("BeginRepairOnSmithFree")) { const smithSchedulingRecords = savedSmithSchedulingRecords.split("&").map(x => JSON.parse(x)); artsList.value = smithSchedulingRecords[0].Id; windowObject.selectart(0); } } function removeArtFromSmithSchedule(itemToRemove) { const savedSmithSchedulingRecords = GM_getValue("SmithSchedulingRecords"); const smithSchedulingRecords = savedSmithSchedulingRecords.split("&").map(x => JSON.parse(x)).filter(x => x.Id != itemToRemove.Id); smithSchedulingRecords.sort((a, b) => a.Queue == b.Queue ? 0 : (a.Queue > b.Queue ? 1 : -1)); let i = 1; for(const actualRecord of smithSchedulingRecords) { actualRecord.Queue = i++; } GM_setValue("SmithSchedulingRecords", smithSchedulingRecords.map(x => JSON.stringify(x)).join("&")); } function addArtToSmithSchedule(artInfo, container, artsInfos) { const savedSmithSchedulingRecords = GM_getValue("SmithSchedulingRecords"); const actualRecords = []; if(savedSmithSchedulingRecords) { const smithSchedulingRecords = savedSmithSchedulingRecords.split("&").map(x => JSON.parse(x)); const found = smithSchedulingRecords.find(x => x.Id == artInfo.Id); if(found) { return; } var lastQueue = smithSchedulingRecords.reduce((c, e) => Math.max(c, e.Queue), smithSchedulingRecords[0].Queue); actualRecords.push(savedSmithSchedulingRecords); } artInfo.Queue = (lastQueue || 0) + 1; actualRecords.push(JSON.stringify(artInfo)); GM_setValue("SmithSchedulingRecords", actualRecords.join("&")); refreshSmithScheduleTable(container, artsInfos); refreshSmithBrokenArtsTable(container, artsInfos); } function deleteArtFromSmithSchedule(artInfo, container, artsInfos) { const savedSmithSchedulingRecords = GM_getValue("SmithSchedulingRecords"); if(savedSmithSchedulingRecords) { const smithSchedulingRecords = savedSmithSchedulingRecords.split("&").map(x => JSON.parse(x)).filter(x => x.Id != artInfo.Id); let i = 1; for(const smithSchedulingRecord of smithSchedulingRecords) { smithSchedulingRecord.Queue = i++; } GM_setValue("SmithSchedulingRecords", smithSchedulingRecords.map(x => JSON.stringify(x)).join("&")); refreshSmithScheduleTable(container, artsInfos); refreshSmithBrokenArtsTable(container, artsInfos); } } function upArtInSmithSchedule(artInfo, scheduleRow, queueColumnIndex) { const smithSchedulingRecords = GM_getValue("SmithSchedulingRecords").split("&").map(x => JSON.parse(x)); const artIndex = smithSchedulingRecords.findIndex(x => x.Id == artInfo.Id); //console.log(`artInfo.Id: ${artInfo.Id}, artIndex: ${artIndex}`); if(artIndex == 0) { return; } smithSchedulingRecords[artIndex].Queue -= 1; scheduleRow.cells[queueColumnIndex].innerText = smithSchedulingRecords[artIndex].Queue; smithSchedulingRecords[artIndex - 1].Queue += 1; scheduleRow.previousElementSibling.cells[queueColumnIndex].innerText = smithSchedulingRecords[artIndex - 1].Queue; smithSchedulingRecords.splice(artIndex - 1, 2, smithSchedulingRecords[artIndex], smithSchedulingRecords[artIndex - 1]); //console.log(smithSchedulingRecords); GM_setValue("SmithSchedulingRecords", smithSchedulingRecords.map(x => JSON.stringify(x)).join("&")); scheduleRow.parentNode.insertBefore(scheduleRow, scheduleRow.previousElementSibling); } function downArtInSmithSchedule(artInfo, scheduleRow, queueColumnIndex) { const smithSchedulingRecords = GM_getValue("SmithSchedulingRecords").split("&").map(x => JSON.parse(x)); const artIndex = smithSchedulingRecords.findIndex(x => x.Id == artInfo.Id); //console.log(`artInfo.Id: ${artInfo.Id}, artIndex: ${artIndex}`); if(artIndex == smithSchedulingRecords.length - 1) { return; } smithSchedulingRecords[artIndex].Queue += 1; scheduleRow.cells[queueColumnIndex].innerText = smithSchedulingRecords[artIndex].Queue; smithSchedulingRecords[artIndex + 1].Queue -= 1; scheduleRow.nextElementSibling.cells[queueColumnIndex].innerText = smithSchedulingRecords[artIndex + 1].Queue; smithSchedulingRecords.splice(artIndex, 2, smithSchedulingRecords[artIndex + 1], smithSchedulingRecords[artIndex]); //console.log(smithSchedulingRecords); GM_setValue("SmithSchedulingRecords", smithSchedulingRecords.map(x => JSON.stringify(x)).join("&")); scheduleRow.parentNode.insertBefore(scheduleRow.nextElementSibling, scheduleRow); } function refreshSmithBrokenArtsTable(container, artsInfos) { const table = container.querySelector("table#SmithBrokenArtsTable") || addElement("table", container, { id: "SmithBrokenArtsTable" }); table.innerHTML = ""; const smithSchedulingRecordsIds = (GM_getValue("SmithSchedulingRecords")?.split("&").map(x => JSON.parse(x).Id)) || []; const artsInfosFiltered = artsInfos.filter(x => !smithSchedulingRecordsIds.includes(x.Id)); if(artsInfosFiltered.length > 0) { const buttonsClass = "inv_text_kukla_btn inv_text_kukla_btn_hover"; const cellStyle = "border: 1px solid #f5c137; overflow: hidden;"; const scheduleRow = addElement("tr", table); addElement("td", scheduleRow, { innerHTML: "<b>Номер арта</b>", style: cellStyle }); addElement("td", scheduleRow, { innerHTML: "<b>Наименование (прочность)</b>", style: cellStyle }); addElement("td", scheduleRow, { innerHTML: "<b>Поставить в очередь</b>", style: cellStyle }); for(const artInfo of artsInfosFiltered) { const scheduleRow = addElement("tr", table); addElement("td", scheduleRow, { innerText: artInfo.Id, style: cellStyle }); addElement("td", scheduleRow, { innerText: `${artInfo.Name} [0/${artInfo.Durability2}]`, style: cellStyle }); const toQueueTd = addElement("td", scheduleRow, { style: cellStyle }); const toQueueButton = addElement("input", toQueueTd, { type: "button", value: "В очередь", class: buttonsClass }); toQueueButton.addEventListener("click", function() { addArtToSmithSchedule(artInfo, container, artsInfos); }, false); } } } function refreshSmithScheduleTable(container, artsInfos) { const cellStyle = "border: 1px solid #f5c137; overflow: hidden;"; const table = container.querySelector("table#SmithScheduleTable") || addElement("table", container, { id: "SmithScheduleTable" }); table.innerHTML = ""; const savedSmithSchedulingRecords = GM_getValue("SmithSchedulingRecords"); if(savedSmithSchedulingRecords) { const buttonsClass = "inv_text_kukla_btn inv_text_kukla_btn_hover"; const smithSchedulingRecords = savedSmithSchedulingRecords.split("&").map(x => JSON.parse(x)); const scheduleRow = addElement("tr", table); addElement("td", scheduleRow, { innerHTML: "<b>Номер арта</b>", style: cellStyle }); addElement("td", scheduleRow, { innerHTML: "<b>Наименование (прочность)</b>", style: cellStyle }); addElement("td", scheduleRow, { innerHTML: "<b>Очередь</b>", style: cellStyle }); addElement("td", scheduleRow, { innerHTML: "<b>Поднять</b>", style: cellStyle }); addElement("td", scheduleRow, { innerHTML: "<b>Опустить</b>", style: cellStyle }); addElement("td", scheduleRow, { innerHTML: "<b>Удалить</b>", style: cellStyle }); const deleteButtonName = isEn ? "Delete" : (Math.random() < 0.05 ? "Нах" : "Удалить"); for(const smithSchedulingRecord of smithSchedulingRecords) { const scheduleRow = addElement("tr", table); addElement("td", scheduleRow, { innerText: smithSchedulingRecord.Id, style: cellStyle }); addElement("td", scheduleRow, { innerText: `${smithSchedulingRecord.Name} [0/${smithSchedulingRecord.Durability2}]`, style: cellStyle }); addElement("td", scheduleRow, { innerText: smithSchedulingRecord.Queue, style: cellStyle }); const upTd = addElement("td", scheduleRow, { style: cellStyle }); const upButton = addElement("input", upTd, { type: "button", value: "Вверх", class: buttonsClass }); upButton.addEventListener("click", function() { upArtInSmithSchedule(smithSchedulingRecord, scheduleRow, 2); }, false); const downTd = addElement("td", scheduleRow, { style: cellStyle }); const downButton = addElement("input", downTd, { type: "button", value: "Вниз", class: buttonsClass }); downButton.addEventListener("click", function() { downArtInSmithSchedule(smithSchedulingRecord, scheduleRow, 2); }, false); const deleteFromQueueTd = addElement("td", scheduleRow, { style: cellStyle }); const deleteFromQueueButton = addElement("input", deleteFromQueueTd, { type: "button", value: deleteButtonName, class: buttonsClass }); deleteFromQueueButton.addEventListener("click", function() { deleteArtFromSmithSchedule(smithSchedulingRecord, container, artsInfos); }, false); } } } function repackSavedSmithSchedule(brokenArts) { //console.log(brokenArts); const savedSmithSchedulingRecords = GM_getValue("SmithSchedulingRecords"); const actualRecords = [] if(savedSmithSchedulingRecords) { const smithSchedulingRecords = savedSmithSchedulingRecords.split("&").map(x => JSON.parse(x)); for(const smithSchedulingRecord of smithSchedulingRecords) { const found = brokenArts.find(x => x.Id == smithSchedulingRecord.Id); if(found) { actualRecords.push(smithSchedulingRecord); } } } //console.log(actualRecords); if(actualRecords.length > 0) { actualRecords.sort((a, b) => a.Queue == b.Queue ? 0 : (a.Queue > b.Queue ? 1 : -1)); let i = 1; for(const actualRecord of actualRecords) { actualRecord.Queue = i++; } GM_setValue("SmithSchedulingRecords", actualRecords.map(x => JSON.stringify(x)).join("&")); } else { GM_deleteValue("SmithSchedulingRecords"); } } function parseSmithPage(doc) { const allb = doc.querySelectorAll("b"); for(const b of allb) { if(b.innerText.includes(LocalizedString.UnderRepair)) { var repairData = b.innerText; break; } } if(repairData) { const restRepairTime = { Hours: 0, Minutes: 0, Seconds: 59 }; //В ремонте: еще 1 ч. 31 мин. //Under repair another 1 h. 17 min. const hoursRegex = new RegExp(`(\\d+) ${isEn ? "h" : "ч"}\\.`); const hoursRegexResult = hoursRegex.exec(repairData); if(hoursRegexResult) { restRepairTime.Hours = parseInt(hoursRegexResult[1]); } const minutesRegex = new RegExp(`(\\d+) ${isEn ? "min" : "мин"}\\.`); const minutesRegexResult = minutesRegex.exec(repairData); if(minutesRegexResult) { restRepairTime.Minutes = parseInt(minutesRegexResult[1]); } //console.log(repairData); //console.log(restRepairTime); const repairEnd = new Date(); repairEnd.setHours(repairEnd.getHours() + restRepairTime.Hours); repairEnd.setMinutes(repairEnd.getMinutes() + restRepairTime.Minutes); repairEnd.setSeconds(repairEnd.getSeconds() + restRepairTime.Seconds); //console.log(repairEnd); const savedRepairEnd = GM_getValue("RepairEnd"); if(!savedRepairEnd || Math.abs(repairEnd.getTime() - parseInt(savedRepairEnd)) / 1000 / 60 > 2) { GM_setValue("RepairEnd", repairEnd.getTime()); } } else { GM_deleteValue("RepairEnd"); } updateRepairTimerPanel("SmithMoratoriumPanel"); const artsInfos = []; const artsList = document.querySelector("select[name='art_id']"); if(artsList) { const artsOptions = artsList.querySelectorAll("option"); for(const artsOption of artsOptions) { const id = parseInt(artsOption.value); if(id > 0) { const artInfoExec = /(.+) \[0\/(\d+)\]/.exec(artsOption.innerText); //console.log(`artsOption.innerText: ${artsOption.innerText}, artInfoExec: ${artInfoExec}`); const artInfo = { Id: id, Name: artInfoExec[1], Durability2: parseInt(artInfoExec[2]) }; //console.log(artInfo); artsInfos.push(artInfo); } } repackSavedSmithSchedule(artsInfos); } return artsInfos; } function updateRepairTimerPanel(panelId) { const repairTimerPanel = document.querySelector(`#${panelId}`); let savedRepairEnd = GM_getValue("RepairEnd"); //console.log(savedRepairEnd); //console.log(repairTimerPanel); if(repairTimerPanel && savedRepairEnd) { savedRepairEnd = parseInt(savedRepairEnd); const now = Date.now(); if(savedRepairEnd > now) { let diff = savedRepairEnd - now; const days = Math.floor(diff / 1000 / 60 / 60 / 24); diff -= days * 1000 * 60 * 60 * 24; const hours = Math.floor(diff / 1000 / 60 / 60); diff -= hours * 1000 * 60 * 60; const mimutes = Math.floor(diff / 1000 / 60); diff -= mimutes * 1000 * 60; const seconds = Math.floor(diff / 1000); const formatedTime = (days > 0 ? days + " " : "") + (hours > 0 ? hours + ":" : "") + ( (mimutes < 10) ? '0' : '' ) + mimutes + ':' + (seconds < 10 ? '0' : '') + seconds; repairTimerPanel.innerText = formatedTime; setTimeout(function() { updateRepairTimerPanel(panelId); }, 1000); } else { repairTimerPanel.innerText = ""; GM_deleteValue("RepairEnd"); } } } function getURL(url) { window.location.href = url; } function attachArtTtransferActionsToItems() { if(!gmGetBool("ArtBulkTtransferEnabled")) { return; } let artInfoDivs = document.querySelectorAll("div.inventory_item_div.inventory_item2"); //console.log(`artInfoDivs.length: ${artInfoDivs.length}`); for(const artInfoDiv of artInfoDivs) { const artIndex = parseInt(artInfoDiv.getAttribute("art_idx")); const artInfo = windowObject.arts[artIndex]; if(artInfo.transfer_ok == 0) { continue; } const artId = artInfo.art_id; const artUid = artInfo.id; const artInfoDivRect = artInfoDiv.getBoundingClientRect(); const isBroken = artInfo.can_be_repaired == 1 ? true : false; //const isBroken = artInfoDiv.querySelector("div.inventory_item_normal.inventory_item_broken") ? true : false; const verticalShiftDown = 9; const artTransferFormActivatorWidth = 15; const artTransferFormActivatorHeight = 15; let rects; if(InventoryArtMenuDirection == InventoryArtMenuDirections.Horizontal) { rects = { artSelector: { top: artInfoDivRect.height - 18 + verticalShiftDown, left: artInfoDivRect.width - 18 + 9 }, artTransferFormActivator: { top: artInfoDivRect.height - artTransferFormActivatorHeight - 1 + verticalShiftDown, left: artInfoDivRect.width - artTransferFormActivatorWidth - 5, height: artTransferFormActivatorHeight, width: artTransferFormActivatorWidth }, artSaleButton: { top: artInfoDivRect.height - artTransferFormActivatorHeight - 1 + verticalShiftDown, left: artInfoDivRect.width - artTransferFormActivatorWidth * 2 - 5, height: artTransferFormActivatorHeight, width: artTransferFormActivatorWidth } }; } else { rects = { artSelector: { top: artInfoDivRect.height - 18 + verticalShiftDown, left: artInfoDivRect.width - 18 + 9 }, artTransferFormActivator: { top: artInfoDivRect.height - 18 + verticalShiftDown - artTransferFormActivatorHeight + 3, left: artInfoDivRect.width - 18 + 12, height: artTransferFormActivatorHeight, width: artTransferFormActivatorWidth }, artSaleButton: { top: artInfoDivRect.height - 18 + verticalShiftDown - artTransferFormActivatorHeight * 2 + 3, left: artInfoDivRect.width - 18 + 12, height: artTransferFormActivatorHeight, width: artTransferFormActivatorWidth } }; } const artSelector = addElement("input", artInfoDiv, { type: "checkbox", name: "artSelector", artId: artId, artUid: artUid, artIndex: artIndex, style: `position: absolute; top: ${rects.artSelector.top}px; left: ${rects.artSelector.left}px; z-index: 3;` }); if(isBroken) { artSelector.setAttribute("isBroken", isBroken); } artSelector.addEventListener("click", function(e) { e.stopPropagation(); const selectedArts = document.querySelectorAll("input[name='artSelector']:checked"); document.getElementById("ArtBulkTtransferTransferButton").disabled = document.getElementById("ArtBulkTtransferWithRecallInButton").disabled = selectedArts.length == 0; const selectedArtsArray = Array.from(selectedArts); let isBrokenCheckBox = selectedArtsArray.find(x => x.hasAttribute("isBroken")); document.getElementById("ArtBulkTtransferIntoRepairsButton").disabled = isBrokenCheckBox ? false : true; }, false); const artTransferFormActivator = addElement("input", artInfoDiv, { type: "image", src: "/i/inv_im/btn_art_transfer.png", name: "artTransferFormActivator", value: "...", artIndex: artIndex, style: `position: absolute; top: ${rects.artTransferFormActivator.top}px; left: ${rects.artTransferFormActivator.left}px; z-index: 3; width: ${rects.artTransferFormActivator.width}px; height: ${rects.artTransferFormActivator.height}px;`, title: LocalizedString.TransferData }); artTransferFormActivator.addEventListener("click", function(e) { e.stopPropagation(); showTransferDataPanel(parseInt(this.getAttribute("artIndex"))); }, false); const artSaleButton = addElement("input", artInfoDiv, { type: "image", src: "/i/r/48/gold.png", name: "artSaleButton", value: "...", artIndex: artIndex, style: `position: absolute; top: ${rects.artSaleButton.top}px; left: ${rects.artSaleButton.left}px; z-index: 3; width: ${rects.artSaleButton.width}px; height: ${rects.artSaleButton.height}px;`, title: artInfo.can_be_repaired == 0 ? LocalizedString.Sale : LocalizedString.ToMarket }); artSaleButton.addEventListener("click", function(e) { e.stopPropagation(); if(artInfo.can_be_repaired == 0) { GM_setValue("ArtSave", JSON.stringify({ Id: artId, Uid: artUid, Strength: artInfo.durability2, RestStrength: artInfo.durability1 })); getURL("/auction_new_lot.php"); } else { getURL(getAuctionUrl(`${artId}@${artUid}`)); } }, false); } } function createPersonPageSellResourceReferences() { if(location.pathname == '/pl_info.php' && getUrlParamValue(location.href, "id") == PlayerId) { const resourcesPanel = getResourcesPanel(); createPersonPageSellResourceReferencesCore(resourcesPanel); } } function createPersonPageSellResourceReferencesCore(resourcesPanel) { const resourceSlots = resourcesPanel.querySelectorAll("div.resourceSlot"); //console.log(`createPersonPageSellResourceReferencesCore resourceSlots: ${resourceSlots.length}`); for(const resourceSlot of resourceSlots) { const amountSlot = resourceSlot.querySelector("div.amountSlot"); const amount = parseInt(amountSlot.innerHTML); const auctionReference = resourceSlot.querySelector("a"); const artType = getUrlParamValue(auctionReference.href, "art_type"); const artCategory = getUrlParamValue(auctionReference.href, "cat"); let artId; let sellAmount = 0; if(artCategory == "part") { artId = artType.replace("part_", "ARTPART_"); sellAmount = amount > 20 ? 20 : 0; } if(artCategory == "elements") { artId = getElementOptionValueByName(artType); sellAmount = 1; } if(sellAmount > 0) { amountSlot.setAttribute("title", "Продать"); amountSlot.addEventListener("click", function(e) { GM_setValue("ArtSave", JSON.stringify({ Id: artId, Amount: sellAmount })); getURL("/auction_new_lot.php"); }); } } if(resourceSlots.length == 0) { observe(resourcesPanel, function() { createPersonPageSellResourceReferencesCore(resourcesPanel); }); } } function getResourcesPanel() { const tables = document.querySelectorAll("table.wblight"); for(const table of tables) { const bolds = table.querySelectorAll("b"); for(const bold of bolds) { if(bold.innerText == "Ресурсы") { return table.rows[1].cells[0]; } } } } function drawArtsTtransferPanel() { if(!gmGetBool("ArtBulkTtransferEnabled")) { return; } const containerBlock = document.querySelector("div.container_block"); const bulkSend = addElement("div", containerBlock, { class: "inv_note_kukla", style: "padding: 4px 4px 4px 4px" }); const buttonsClass = "inv_text_kukla_btn inv_text_kukla_btn_hover" addElement("div", bulkSend, { innerText: LocalizedString.Transfer, class: "inv_scroll_content_inside" }); addElement("br", bulkSend); addElement("span", bulkSend, { innerText: LocalizedString.Receiver }); const receiverName = addElement("input", bulkSend, { id: "TransferReceiverNameInput", type: "text", value: GM_getValue("LastReceiver", ""), style: "width: 100px;", autocomplete: "off", onfocus: "this.value = ''; document.getElementById('receiverNames').style.display = 'block'; document.getElementById('receiverNames').style.display = 'none';" }); createDataList(receiverName, "receiverNames", buttonsClass); addElement("br", bulkSend); const transferButton = addElement("input", bulkSend, { id: "ArtBulkTtransferTransferButton", type: "button", value: LocalizedString.IntoOwnership, title: LocalizedString.IntoOwnershipTitle, class: buttonsClass }); transferButton.disabled = true; transferButton.addEventListener("click", transferArts, false); const withRecallInButton = addElement("input", bulkSend, { id: "ArtBulkTtransferWithRecallInButton", type: "button", value: LocalizedString.WithRecallIn, title: LocalizedString.WithRecallInTitle, class: buttonsClass }); withRecallInButton.disabled = true; withRecallInButton.addEventListener("click", transferArtsWithRecall, false); addElement("br", bulkSend); addElement("span", bulkSend, { innerText: LocalizedString.PercentOfRepairCost }); const lastTransferRepairsPercentInput = addElement("input", bulkSend, { type: "number", value: GM_getValue("LastTransferRepairsPercent", "100"), min: "10", max: "150", style: "width: 50px;" }); lastTransferRepairsPercentInput.addEventListener("change", function() { gmSetOrDeleteNumber("LastTransferRepairsPercent", this.value); }, false); const intoRepairsButton = addElement("input", bulkSend, { id: "ArtBulkTtransferIntoRepairsButton", type: "button", value: LocalizedString.IntoRepairs, title: LocalizedString.IntoRepairsTitle, class: buttonsClass }); intoRepairsButton.disabled = true; intoRepairsButton.addEventListener("click", repairArts, false); const all_trades_from_me = document.querySelector("div#all_trades_from_me"); const cancelTransferButton = addElement("input", bulkSend, { type: "button", value: LocalizedString.CancelAll, class: buttonsClass }); cancelTransferButton.disabled = all_trades_from_me ? false : true; cancelTransferButton.addEventListener("click", cancelTransfers, false); } function auctionNewLot() { const sel = document.querySelector("select#sel"); const anl_count = document.querySelector("input#anl_count"); anl_count.type = "number"; anl_count.setAttribute("onfocus", "this.select();"); const anl_price = document.querySelector("input#anl_price"); anl_price.type = "number"; anl_price.setAttribute("onfocus", "this.select();"); //anl_price.setAttribute("step", "10"); // Допускает только кратные 10-ти значения const saleInfo = createElement("b", { style: "margin-left: 5px;" }); anl_price.parentNode.insertBefore(saleInfo, anl_price.nextElementSibling); anl_price.addEventListener("change", function() { if(sel.selectedIndex > -1) { saleInfo.innerText = ""; let artInfo = calcArtTypeAndCategory(sel.value); const strengthExec = /(\d+)\/(\d+)/.exec(sel.options[sel.selectedIndex].text); //console.log(strengthExec); if(strengthExec && strengthExec.length >=3) { var strength = parseInt(strengthExec[2]); var restStrength = parseInt(strengthExec[1]); let art = new ArtefactLot(artInfo.Uid, artInfo.Id, strength, restStrength, parseInt(this.value)); art.CalcOptRepair(); saleInfo.innerText = `${LocalizedString.BattlePrice}: ${art.OptimalRepairCombatCost}, ${LocalizedString.Strength}: ${art.OptimalRepairStrength}, ${LocalizedString.Combats}: ${art.OptimalRepairCombatsAmount}`; } } }, false); const anl_form_ok = document.querySelector("form[name='anl_form_ok']"); const formContainer = anl_form_ok.parentNode; const marketContainer = createElement("div"); formContainer.parentNode.insertBefore(marketContainer, formContainer.nextElementSibling); sel.addEventListener("change", function() { loadLots(marketContainer, getAuctionUrl(this.value)); let art = calcArtTypeAndCategory(this.value); GM_setValue("ArtSave", JSON.stringify({ Id: art.Id, Uid: art.Uid })); }, false); const toMarketButton = document.querySelector("div[onclick*='auction.php']"); toMarketButton.onclick = ""; toMarketButton.addEventListener("click", function() { getURL(getAuctionUrl(sel.value)); }, false); let art = GM_getValue("ArtSave"); if(art) { //console.log(art); art = JSON.parse(art); console.log(art); let searchStr = `option[value='${art.Id}']`; if(art.Uid) { searchStr = `option[value^='${art.Id}@']`; } const options = Array.from(sel.querySelectorAll(searchStr)); if(options.length == 1) { options[0].selected = true; } else if(options.length > 1) { console.log(options); const found = options.find(x => x.value.includes(art.Uid) || x.innerText.includes(`${art.RestStrength}/${art.Strength}`)); if(found) { found.selected = true; } } anl_count.value = art.Amount || 1; } loadLots(marketContainer, getAuctionUrl(sel.value)); } async function transferArts() { const receiverName = document.getElementById("TransferReceiverNameInput"); const receiver = receiverName.value; if(!receiver || receiver == "") { alert(LocalizedString.FillReceiver); return; } GM_setValue("LastReceiver", receiver); insertReceiverName("receiverNames", receiver); const selectedArts = document.querySelectorAll("input[name='artSelector']:checked"); for(const selectedArt of selectedArts) { const artUid = parseInt(selectedArt.getAttribute("artUid")); const artId = selectedArt.getAttribute("artId"); const gold = parseInt(GM_getValue("TransferGold" + artUid) || GM_getValue("TransferGold" + artId)) || 0; await postRequest("/art_transfer.php", `id=${artUid}&nick=${receiver}&gold=${gold}&sendtype=1&dtime=0&bcount=0&rep_price=0&art_id=&sign=${windowObject.sign}`); } window.location.reload(); } async function transferArtsWithRecall() { const receiverName = document.getElementById("TransferReceiverNameInput"); const receiver = receiverName.value; if(!receiver || receiver == "") { alert(LocalizedString.FillReceiver); return; } GM_setValue("LastReceiver", receiver); insertReceiverName("receiverNames", receiver); const selectedArts = document.querySelectorAll("input[name='artSelector']:checked"); for(const selectedArt of selectedArts) { const artUid = parseInt(selectedArt.getAttribute("artUid")); const artId = selectedArt.getAttribute("artId"); const gold = parseInt(GM_getValue("TransferGold" + artUid) || GM_getValue("TransferGold" + artId)) || 0; const days = parseInt(GM_getValue("TransferDays" + artUid) || GM_getValue("TransferDays" + artId)) || 0; const combats = parseInt(GM_getValue("TransferCombats" + artUid) || GM_getValue("TransferCombats" + artId)) || 0; const allowRepairing = (GM_getValue("TransferAllowRepairing" + artUid, "0") == "0" && gmGetBool("TransferAllowRepairing" + artId) || GM_getValue("TransferAllowRepairing" + artUid, "0") == "2") ? "&rep=on" : ""; //console.log(`artUid: ${artId}, repairCost: ${repairCost}, repairsPercent: ${repairsPercent}, repairPrice: ${repairPrice}`); if(gold > 0 && days > 0 && combats > 0) { await postRequest("/art_transfer.php", `id=${artUid}&nick=${receiver}&gold=${gold}&sendtype=2&dtime=${days}&bcount=${combats}${allowRepairing}&rep_price=0&art_id=&sign=${windowObject.sign}`); } } window.location.reload(); } async function showTradesToMeIndicator() { if(gmGetBool("ShowTradesToMe") && isHeartOnPage) { await readTradesToMe(); const trades = GM_getValue("TradesToMe", "").split("&").filter(x => x != "").map(x => JSON.parse(x)); toggleHomeIndicator("https://dcdn.heroeswm.ru/i/inv_im/btn_art_put.png", `${isEn ? "Trades for me" : "Передач вам" }: ${trades.length}`, "/inventory.php", trades.length > 0, "TradesToMeSignTitle", "TradesToMeSign"); } } async function showThresholdPricesIndicator() { if(gmGetBool("ShowThresholdPricesIndicator") && isHeartOnPage) { const thresholdPrices = JSON.parse(GM_getValue("ThresholdPrices", "{}")); const artIds = Object.keys(thresholdPrices).filter(x => !x.startsWith("Url")); const currentArtId = location.pathname == '/auction.php' && artIds.includes(getUrlParamValue(location.href, "art_type")) ? getUrlParamValue(location.href, "art_type") : undefined; if(currentArtId) { GM_deleteValue("ShowThresholdPricesImdicatorLastRequestTime"); } const timeExpired = Date.now() > parseInt(GM_getValue("ShowThresholdPricesImdicatorLastRequestTime", 0)) + 1000 * 60; //console.log(`showThresholdPricesIndicator ShowThresholdPricesData: ${GM_getValue("ShowThresholdPricesData")}, timeExpired: ${timeExpired}, mooving: ${mooving}`); if(timeExpired && !mooving) { GM_setValue("ShowThresholdPricesImdicatorLastRequestTime", Date.now()); GM_deleteValue("ShowThresholdPricesData"); for(const artId of artIds) { const url = thresholdPrices[`Url${artId}`]; const doc = await getRequest(url); const elementMarketInfos = extendLotsTable(doc, url, false).Arts; const thresholdPrice = Number(thresholdPrices[artId]); const arts = elementMarketInfos[artId]; if(!arts) { continue; } //console.log(`artId: ${artId}, url: ${url}, thresholdPrice: ${thresholdPrice}, elementMarketInfos.length: ${elementMarketInfos.length}`); const minLotPrice = arts.reduce((c, e) => Math.min(c, e.LotPrice), arts[0].LotPrice); const thresholdExists = minLotPrice <= thresholdPrice; //console.log(`artId: ${artId}, url: ${url}, thresholdPrice: ${thresholdPrice}, minLotPrice: ${minLotPrice}`); if(thresholdExists) { GM_setValue("ShowThresholdPricesData", url); if(gmGetBool("ShowThresholdPricesNotification")) { const lotId = arts.find(x => x.LotPrice == minLotPrice).LotId; if(!GM_getValue(`NotificatedThresholdPricesLotId${lotId}`)) { GM_setValue(`NotificatedThresholdPricesLotId${lotId}`, Date.now()); GM.notification(`${isEn ? "Advantageous lot" : "Выгодный лот" }`, "ГВД", "https://dcdn2.heroeswm.ru/i/forum/130_1.png?v=1", function() { window.focus(); console.log(GM_getValue("ShowThresholdPricesData")); window.location.href = GM_getValue("ShowThresholdPricesData"); }); } } break; } } } if(GM_getValue("ShowThresholdPricesData")) { toggleHomeIndicator("https://dcdn2.heroeswm.ru/i/forum/130_1.png?v=1", `${isEn ? "Advantageous lot" : "Выгодный лот" }`, GM_getValue("ShowThresholdPricesData"), true, "ThresholdPricesTitle", "ThresholdPrices"); } setTimeout(showThresholdPricesIndicator, 1000 * 60); } } async function readTradesToMe(force = false) { const lastTradesToMeRequestDate = parseInt(GM_getValue("LastTradesToMeRequestDate", 0)); const isOnInventoryPage = location.href.includes("inventory.php"); //console.log(`TradesToMe: ${GM_getValue("TradesToMe")}, isOnInventoryPage: ${isOnInventoryPage}, lastTradesToMeRequestDate: ${Date.now() - lastTradesToMeRequestDate}`); if(isOnInventoryPage || Date.now() - lastTradesToMeRequestDate > 1000 * 60 * 2 || force) { GM_setValue("LastTradesToMeRequestDate", Date.now()); const doc = isOnInventoryPage ? document : await getRequest("/inventory.php"); const allTradesToMeDiv = doc.querySelector("div#all_trades_to_me"); const trades = []; if(allTradesToMeDiv) { const tradeDivs = allTradesToMeDiv.querySelectorAll("div.inv_peredachka"); for(const tradeDiv of tradeDivs) { const senderRef = tradeDiv.querySelector("a[href^='pl_info.php']"); const senderId = getUrlParamValue(senderRef.href, "id"); const senderName = (senderRef.querySelector("b") || senderRef).innerHTML; const artRef = tradeDiv.querySelector("a[href^='art_info.php']"); const artId = getUrlParamValue(artRef.href, "id"); const cancelRef = tradeDiv.querySelector("a[href^='trade_cancel.php']"); const tradeId = getUrlParamValue(cancelRef.href, "tid"); const forRepairs = tradeDiv.innerHTML.includes(isEn ? "for repairs" : "на ремонт"); const artName = tradeDiv.querySelector("b").innerHTML; const artInfoDiv = tradeDiv.querySelector("div.inv_request_info"); const div2 = artInfoDiv.children[1]; const div2b = div2.querySelectorAll("b"); const durability = div2b[0].innerHTML; let cost; let percent; if(forRepairs) { cost = div2b[1].innerHTML percent = /\((\d+)%\)/.exec(div2.innerHTML)[1]; } trades.push({ Id: tradeId, SenderId: senderId, SenderName: senderName, ArtId: artId, ArtName: artName, ForRepairs: forRepairs, Cost: cost, Durability: durability, Percent: percent }); } } GM_setValue("TradesToMe", trades.map(x => JSON.stringify(x)).join("&")); // {"Id":"53897507","SenderId":"4039417","SenderName":"iNeroon","ArtId":"boots13","ArtName":"Обсидиановые сапоги","ForRepairs":true,"Cost":"7,652","Durability":"0/70","Percent":"90"} //console.log(GM_getValue("TradesToMe")); } } var notificationNumber = 0; function toggleHomeIndicator(imageName, message, url, condition, indicatorContainerId, indicatorId) { if(condition) { const homeRef = document.querySelector("a[href='home.php']"); const existingIndicator = document.getElementById(indicatorContainerId); if(existingIndicator) { existingIndicator.title = message; } else { notificationNumber++; if(isNewInterface) { const a = addElement("a", homeRef.parentNode, { id: indicatorId, href: url }); const width = 24; const height = 24; const top = -1 + height; const right = -3 + width * (notificationNumber - 1); const div = addElement("div", a, { id: indicatorContainerId, title: message, style: `height: ${height}px; width: ${width}px; position: absolute; top: ${top}px; right: ${right}px;` }); addElement("img", div, { src: imageName, class: "NotificationIcon" }); } else { const td = getParent(homeRef, "td"); const newTd = addElement("td", td.parentNode, { id: indicatorId }); const a = addElement("a", newTd, { href: url }); addElement("img", a, { id: indicatorContainerId, src: imageName, title: message, style: "width: 12px; height: 12px; border-radius: 50%;" }); } } } else { const existingIndicator = document.getElementById(indicatorId); if(existingIndicator) { existingIndicator.remove(); notificationNumber--; } } } async function repairArts() { const receiverName = document.getElementById("TransferReceiverNameInput"); const receiver = receiverName.value; const repairsPercent = parseInt(GM_getValue("LastTransferRepairsPercent", "100")); if(!receiver || receiver == "") { alert(LocalizedString.FillReceiver); return; } GM_setValue("LastReceiver", receiver); insertReceiverName("receiverNames", receiver); const selectedArts = Array.from(document.querySelectorAll("input[name='artSelector']:checked")).filter(x => x.hasAttribute("isBroken")); for(const selectedArt of selectedArts) { const artUid = parseInt(selectedArt.getAttribute("artUid")); const artId = selectedArt.getAttribute("artId"); const repairCost = ArtifactInfo[artId].RepairCost; const repairPrice = repairCost * repairsPercent / 100; //console.log(`artId: ${artId}, repairCost: ${repairCost}, repairsPercent: ${repairsPercent}, repairPrice: ${repairPrice}`); await postRequest("/art_transfer.php", `id=${artUid}&nick=${receiver}&gold=0&sendtype=5&dtime=0&bcount=0&rep_price=${repairPrice}&art_id=&sign=${windowObject.sign}`); } window.location.reload(); } async function cancelTransfers() { const all_trades_from_me = document.querySelector("div#all_trades_from_me"); if(all_trades_from_me) { const tradeCancelRefs = all_trades_from_me.querySelectorAll("a[href*='trade_cancel.php']"); for(const tradeCancelRef of tradeCancelRefs) { await getRequest(tradeCancelRef.href); } window.location.reload(); } } var ResourcesTypes = { "wood": { Type: "1", ImageName: "wood" }, "ore": { Type: "2", ImageName: "ore" }, "mercury": { Type: "3", ImageName: "mercury" }, "sulphur": { Type: "4", ImageName: "sulfur" }, "crystal": { Type: "5", ImageName: "crystals" }, "gem": { Type: "6", ImageName: "gems" } }; var ElementsTypes = { "42": "abrasive", "43": "snake_poison", "46": "tiger_tusk", "44": "ice_crystal", "45": "moon_stone", "40": "fire_crystal", "37": "meteorit", "41": "witch_flower", "39": "wind_flower", "78": "fern_flower", "38": "badgrib" } var ElementNames = ["abrasive", "snake_poison", "tiger_tusk", "ice_crystal", "moon_stone", "fire_crystal", "meteorit", "witch_flower", "wind_flower", "fern_flower", "badgrib"]; function calcArtTypeAndCategory(selectValue) { if(selectValue) { if(selectValue.includes("@")) { let artId = selectValue.split("@")[0]; let uid = selectValue.split("@")[1]; if(ArtifactInfo[artId]) { return { ArtType: artId, Category: ArtifactInfo[artId].MarketCategory, Id: artId, Uid: uid }; } } else if(ResourcesTypes[selectValue]) { return { Type: ResourcesTypes[selectValue].Type, Category: "res", Id: selectValue }; } else if(selectValue.match(/EL_\d{2}/)) { let elNumber = parseInt(/EL_(\d{2})/.exec(selectValue)[1]); return { ArtType: ElementsTypes[elNumber], Category: "elements", Id: selectValue }; } else if(selectValue.match(/ARTPART_.+/)) { let artType = /ARTPART_(.+)/.exec(selectValue)[1]; return { ArtType: "part_" + artType, Category: "part", Id: selectValue }; } else if(selectValue.match(/CERT_\d+/)) { let artType = /CERT_(\d+)/.exec(selectValue)[1]; //console.log(artType); return { ArtType: getSertIdByLocationNumber(artType), Category: "cert", Id: selectValue }; } } } function getElementOptionValueByName(name) { return "EL_" + getKeyByValue(ElementsTypes, name); } function getSertIdByLocationNumber(locationNumber) { return "sec_" + (locationNumber.toString()).padStart(2, "0"); } function getSertIdByLocationName(locationName) { const locationNumber = Object.keys(locations).find(x => locations[x][2] == locationName); return getSertIdByLocationNumber(locationNumber); } function getHouseIdByLocationNumber(locationNumber) { return "dom_" + (locationNumber.toString()).padStart(2, "0"); } function getHouseIdByLocationName(locationName) { const locationNumber = Object.keys(locations).find(x => locations[x][2] == locationName); return getHouseIdByLocationNumber(locationNumber); } function getShaIdByLocationNumber(locationNumber) { return "sha_" + (locationNumber.toString()).padStart(2, "0"); } function getShaIdByLocationName(locationName) { const locationNumber = Object.keys(locations).find(x => locations[x][2] == locationName); return getShaIdByLocationNumber(locationNumber); } function getAuctionUrl(selectValue) { let urlParams = calcArtTypeAndCategory(selectValue); if(urlParams) { let url = `/auction.php?cat=${urlParams.Category}`; if(urlParams.ArtType) { url += `&art_type=${urlParams.ArtType}`; } if(urlParams.Type) { url += `&type=${urlParams.Type}`; } return url; } return "/auction.php"; } async function loadLots(marketContainer, url) { marketContainer.innerHTML = ""; if(url && getUrlParamValue(url, "cat")) { const doc = await getRequest(url); const ss2Table = extendLotsTable(doc, url, true).Table; if(ss2Table) { marketContainer.appendChild(ss2Table); } } } function showTransferDataPanel(artIndex) { const artInfo = windowObject.arts[artIndex]; const artId = artInfo.art_id; const artUid = artInfo.id; if(showPupupPanel("TransferData_" + artUid)) { return; } const fieldsMap = []; fieldsMap.push([null, createElement("span", { innerText: LocalizedString.ForAll, style: "font-weight: bold;" }), null, createElement("span", { innerText: LocalizedString.ForThis, style: "font-weight: bold;" })]); const transferGoldLabel = createElement("label", { for: "transferGoldInput", innerText: LocalizedString.Cost + "\t" }); const transferGoldInput = createElement("input", { id: "transferGoldInput", type: "number", value: GM_getValue("TransferGold" + artId, ""), onfocus: "this.select();" }); transferGoldInput.addEventListener("change", function() { gmSetOrDeleteNumber("TransferGold" + artId, this.value); }, false); const transferGoldUniqueLabel = createElement("label", { for: "transferGoldUniqueInput", innerText: LocalizedString.Cost + "\t" }); const transferGoldUniqueInput = createElement("input", { id: "transferGoldUniqueInput", type: "number", value: GM_getValue("TransferGold" + artUid, ""), onfocus: "this.select();" }); transferGoldUniqueInput.addEventListener("change", function() { gmSetOrDeleteNumber("TransferGold" + artUid, this.value); }, false); fieldsMap.push([transferGoldLabel, transferGoldInput, transferGoldUniqueLabel, transferGoldUniqueInput]); const transferDaysLabel = createElement("label", { for: "transferDaysInput", innerText: LocalizedString.Days + "\t" }); const transferDaysInput = createElement("input", { id: "transferDaysInput", type: "number", value: GM_getValue("TransferDays" + artId, ""), onfocus: "this.select();" }); transferDaysInput.addEventListener("change", function() { gmSetOrDeleteNumber("TransferDays" + artId, this.value); }, false); const transferDaysUniqueLabel = createElement("label", { for: "transferDaysUniqueInput", innerText: LocalizedString.Days + "\t" }); const transferDaysUniqueInput = createElement("input", { id: "transferDaysUniqueInput", type: "number", value: GM_getValue("TransferDays" + artUid, ""), onfocus: "this.select();" }); transferDaysUniqueInput.addEventListener("change", function() { gmSetOrDeleteNumber("TransferDays" + artUid, this.value); }, false); fieldsMap.push([transferDaysLabel, transferDaysInput, transferDaysUniqueLabel, transferDaysUniqueInput]); const transferCombatsLabel = createElement("label", { for: "transferCombatsInput", innerText: LocalizedString.Combats + "\t" }); const transferCombatsInput = createElement("input", { id: "transferCombatsInput", type: "number", value: GM_getValue("TransferCombats" + artId, ""), onfocus: "this.select();" }); transferCombatsInput.addEventListener("change", function() { gmSetOrDeleteNumber("TransferCombats" + artId, this.value); recalcTransferGold(artId, transferGoldInput); }, false); const transferCombatsUniqueLabel = createElement("label", { for: "transferCombatsUniqueInput", innerText: LocalizedString.Combats + "\t" }); const transferCombatsUniqueInput = createElement("input", { id: "transferCombatsUniqueInput", type: "number", value: GM_getValue("TransferCombats" + artUid, ""), onfocus: "this.select();" }); transferCombatsUniqueInput.addEventListener("change", function() { gmSetOrDeleteNumber("TransferCombats" + artUid, this.value); recalcTransferGold(artUid, transferGoldUniqueInput); }, false); fieldsMap.push([transferCombatsLabel, transferCombatsInput, transferCombatsUniqueLabel, transferCombatsUniqueInput]); const allowRepairingLabel = createElement("label", { for: "allowRepairingInput", innerText: LocalizedString.AllowRepairing + "\t" }); const allowRepairingInput = createElement("input", { id: "allowRepairingInput", type: "checkbox" }); allowRepairingInput.checked = gmGetBool("TransferAllowRepairing" + artId); allowRepairingInput.addEventListener("change", function() { GM_setValue("TransferAllowRepairing" + artId, this.checked); }, false); const allowRepairingUniqueLabel = createElement("label", { for: "allowRepairingUniqueInput", innerText: LocalizedString.AllowRepairing + "\t" }); const allowRepairingUniqueInput = createElement("select", { id: "allowRepairingUniqueInput", innerHTML: `<option value="0">${LocalizedString.AsForAll}</option><option value="1">${LocalizedString.Forbid}</option><option value="2">${LocalizedString.Allow}</option>` }); allowRepairingUniqueInput.value = GM_getValue("TransferAllowRepairing" + artUid, "0"); allowRepairingUniqueInput.addEventListener("change", function() { GM_setValue("TransferAllowRepairing" + artUid, this.value); }, false); fieldsMap.push([allowRepairingLabel, allowRepairingInput, allowRepairingUniqueLabel, allowRepairingUniqueInput]); const battlePriceLabel = createElement("label", { for: "battlePriceInput", innerText: `${isEn ? "Battle price" : "Цена за бой"}\t` }); const battlePriceInput = createElement("input", { id: "battlePriceInput", type: "number", value: GM_getValue(`TransferBattlePrice${artId}`, ""), onfocus: "this.select();" }); battlePriceInput.addEventListener("change", function() { gmSetOrDeleteNumber(`TransferBattlePrice${artId}`, this.value); recalcTransferGold(artId, transferGoldInput); }, false); const battlePriceUniqueLabel = createElement("label", { for: "battlePriceUniqueInput", innerText: `${isEn ? "Battle price" : "Цена за бой"}\t` }); const battlePriceUniqueInput = createElement("input", { id: "battlePriceUniqueInput", type: "number", value: GM_getValue("TransferBattlePrice" + artUid, ""), onfocus: "this.select();" }); battlePriceUniqueInput.addEventListener("change", function() { gmSetOrDeleteNumber("TransferBattlePrice" + artUid, this.value); recalcTransferGold(artUid, transferGoldUniqueInput); }, false); fieldsMap.push([battlePriceLabel, battlePriceInput, battlePriceUniqueLabel, battlePriceUniqueInput]); const customArtInfoLabel = createElement("label", { for: "CustomArtInfoInput", innerText: `${isEn ? "Info" : "Инфо"}\t` }); const customArtInfoInput = createElement("input", { id: "CustomArtInfoInput", type: "text", value: GM_getValue("CustomArtInfo" + artUid, ""), onfocus: "this.select();" }); customArtInfoInput.addEventListener("change", function() { GM_setValue("CustomArtInfo" + artUid, this.value); }, false); fieldsMap.push([null, null, customArtInfoLabel, customArtInfoInput]); createPupupPanel("TransferData_" + artUid, `${LocalizedString.TransferData} ${artInfo.name}`, fieldsMap); } function recalcTransferGold(artId, transferGoldInput) { const transferBattlePrice = parseInt(GM_getValue(`TransferBattlePrice${artId}`, 0)); const transferCombats = parseInt(GM_getValue(`TransferCombats${artId}`, 0)); if(transferBattlePrice > 0 && transferCombats > 0) { transferGoldInput.value = transferBattlePrice * transferCombats; GM_setValue("TransferGold" + artId, transferBattlePrice * transferCombats); } } function gmSetOrDeleteNumber(key, value) { if(!value || value == "" || isNaN(Number(value))) { GM_deleteValue(key); } else { GM_setValue(key, value); } } function insertReceiverName(dataListId, receiverName) { const valuesData = GM_getValue("DataList" + dataListId); let values = []; if(valuesData) { values = valuesData.split(","); } if(!values.includes(receiverName)) { values.unshift(receiverName); GM_setValue("DataList" + dataListId, values.join()); } } function createDataList(inputElement, dataListId, buttonsClass) { const datalist = createElement("datalist", { id: dataListId }); const valuesData = GM_getValue("DataList" + dataListId); let values = []; if(valuesData) { values = valuesData.split(","); } for(const value of values) { addElement("option", datalist, { value: value }); } inputElement.parentNode.insertBefore(datalist, inputElement.nextSibling); inputElement.setAttribute("list", dataListId); const clearListButton = createElement("input", { type: "button", value: "x", title: LocalizedString.ClearList, class: buttonsClass, style: "min-width: 20px; width: 20px; text-align: center; padding: 2px 2px 2px 2px;" }); clearListButton.addEventListener("click", function() { if(window.confirm(LocalizedString.ClearList)) { GM_deleteValue("DataList" + dataListId); datalist.innerHTML = ""; } }, false); inputElement.parentNode.insertBefore(clearListButton, datalist.nextSibling); return datalist; } function countExp() { if(!gmGetBool("TotalSkillsCount")) { return; } if(location.pathname=='/home.php' || location.pathname=='/pl_info.php') { const tds = document.querySelectorAll("td"); for(const td of tds) { if(td.innerHTML.includes(LocalizedString.Knight)) { var td2 = td; } if(td.innerHTML.includes(LocalizedString.CombatLevel)) { var td1 = td; } } if(td2) { let totalSkill = 0; const regex = /\(([\d\.\,]+)\)/g; for(let i = 1; i <= 10; i++) { const skillsData = regex.exec(td2.innerHTML); //console.log(skillsData); if(skillsData) { totalSkill += parseFloat(skillsData[1]); } } totalSkill = round00(totalSkill); if(td1) { const regex1 = /\(([\d\.\,]+)\)/g; const exp = parseInt(regex1.exec(td1.innerHTML)[1].replace(/,/g, "")); const br = td1.querySelector("br"); td1.insertBefore(createElement("span", { innerHTML: ` » <b>${LocalizedString.SkillsCount}: </b>${totalSkill.toLocaleString()}, ${LocalizedString.Ratio}: ${ Math.round(exp / totalSkill).toLocaleString() }` }), br.nextSibling); } } } } async function getDailyElementsPrices() { const doc = await getRequest("https://daily.heroeswm.ru/market/elements"); const elementsTable = doc.getElementById("report_1"); const takeRow = 2; const elementsPrices = { Date: parseDate(elementsTable.rows[1].cells[0].innerText) }; for(let i = 0; i < elementsTable.rows[takeRow].cells.length - 1; i++) { elementsPrices[ElementNames[i]] = elementsTable.rows[takeRow].cells[i + 1].innerText; } //console.log(elementsPrices); GM_setValue("ElementPrices", JSON.stringify(elementsPrices)); return elementsPrices; } var craftElementsAmount = 45; async function getMarketElementPrices() { const url = "/auction.php?cat=elements&sort=0"; const doc = await getRequest(url); const elementMarketInfos = extendLotsTable(doc, url, true).Arts; //console.log(elementMarketInfos); const elementsPrices = {}; for(const elementName of ElementNames) { elementsPrices[elementName] = 0; const elementMarketInfo = elementMarketInfos[elementName]; if(elementMarketInfo) { elementMarketInfo.sort((a, b) => parseFloat(a.LotPrice) - parseFloat(b.LotPrice)); //console.log(elementMarketInfo); let totalAmount = 0; let totalSum = 0; for(const lot of elementMarketInfo) { if(totalAmount < craftElementsAmount) { const addAmount = Math.min(lot.LotAmount, craftElementsAmount - totalAmount); totalSum += addAmount * lot.LotPrice; totalAmount += addAmount; } else { break; } } if(totalAmount > 0) { elementsPrices[elementName] = Math.round(totalSum / totalAmount); } //console.log(`elementName: ${elementName}, totalAmount: ${totalAmount}, totalSum: ${totalSum}`); } } //console.log(elementsPrices); GM_setValue("ElementPrices", JSON.stringify(elementsPrices)); return elementsPrices; } function getPlayerLocationNumber() { if(location.pathname == '/map.php' && location.search == '') { // Если мы на карте без параметров, т.е. на локации, где сами находимся. Если мы не в пути, тогда видим предприятия. Мы можем обновить текущее положение игрока. const minesRef = document.querySelector("a[href*='map.php?cx='][href*='&cy='][href*='&st=mn']"); // Берем из ссылки на заголовке шахт данной локации if(minesRef) { const locationNumber = getLocationNumberFromMapUrlByXy(minesRef.href); if(locationNumber) { GM_setValue("PlayerLocationNumber", locationNumber); return locationNumber; } } } return parseInt(GM_getValue("PlayerLocationNumber")); // Иначе, возьмем из кеша. Там будет пусто только при первом запуске скрипта, когда мы не просматриваем карту. } function getLocationNumberFromMapUrlByXy(href) { const x = getUrlParamValue(href, "cx"); const y = getUrlParamValue(href, "cy"); for(let locationNumber in locations) { if(x == locations[locationNumber][0] && y == locations[locationNumber][1]) { return locationNumber; } } } function today() { const now = new Date(); now.setHours(0, 0, 0, 0); return now; } function getCraftCost(craftInfo, craftType, isLogCalculation = false) { const elementsPrices = JSON.parse(GM_getValue("ElementPrices", "{}")); const elementsAmount = {}; let modsAmount = 0; // I12E12A12W12F12 if(craftType == CraftType.Weapon) { if(craftInfo.includes("I")) { const ignoreCraftLevel = parseInt(/I(\d+)/.exec(craftInfo)[1]); elementsAmount["abrasive"] = CraftLevels[ignoreCraftLevel]; elementsAmount["moon_stone"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("E")) { const ignoreCraftLevel = parseInt(/E(\d+)/.exec(craftInfo)[1]); elementsAmount["meteorit"] = CraftLevels[ignoreCraftLevel]; elementsAmount["badgrib"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("A")) { const ignoreCraftLevel = parseInt(/A(\d+)/.exec(craftInfo)[1]); elementsAmount["wind_flower"] = CraftLevels[ignoreCraftLevel]; elementsAmount["witch_flower"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("W")) { const ignoreCraftLevel = parseInt(/W(\d+)/.exec(craftInfo)[1]); elementsAmount["ice_crystal"] = CraftLevels[ignoreCraftLevel]; elementsAmount["snake_poison"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("F")) { const ignoreCraftLevel = parseInt(/F(\d+)/.exec(craftInfo)[1]); elementsAmount["fire_crystal"] = CraftLevels[ignoreCraftLevel]; elementsAmount["tiger_tusk"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } } if(craftType == CraftType.Armor) { if(craftInfo.includes("D")) { const ignoreCraftLevel = parseInt(/D(\d+)/.exec(craftInfo)[1]); elementsAmount["abrasive"] = CraftLevels[ignoreCraftLevel]; elementsAmount["moon_stone"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("E")) { const ignoreCraftLevel = parseInt(/E(\d+)/.exec(craftInfo)[1]); elementsAmount["meteorit"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("A")) { const ignoreCraftLevel = parseInt(/A(\d+)/.exec(craftInfo)[1]); elementsAmount["wind_flower"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("W")) { const ignoreCraftLevel = parseInt(/W(\d+)/.exec(craftInfo)[1]); elementsAmount["ice_crystal"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("F")) { const ignoreCraftLevel = parseInt(/F(\d+)/.exec(craftInfo)[1]); elementsAmount["fire_crystal"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } } if(craftType == CraftType.Jewelry) { if(craftInfo.includes("N")) { const ignoreCraftLevel = parseInt(/N(\d+)/.exec(craftInfo)[1]); elementsAmount["wind_flower"] = CraftLevels[ignoreCraftLevel]; elementsAmount["tiger_tusk"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("E")) { const ignoreCraftLevel = parseInt(/E(\d+)/.exec(craftInfo)[1]); elementsAmount["meteorit"] = CraftLevels[ignoreCraftLevel]; elementsAmount["tiger_tusk"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("A")) { const ignoreCraftLevel = parseInt(/A(\d+)/.exec(craftInfo)[1]); elementsAmount["wind_flower"] = CraftLevels[ignoreCraftLevel]; elementsAmount["meteorit"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("W")) { const ignoreCraftLevel = parseInt(/W(\d+)/.exec(craftInfo)[1]); elementsAmount["ice_crystal"] = CraftLevels[ignoreCraftLevel]; elementsAmount["witch_flower"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } if(craftInfo.includes("F")) { const ignoreCraftLevel = parseInt(/F(\d+)/.exec(craftInfo)[1]); elementsAmount["fire_crystal"] = CraftLevels[ignoreCraftLevel]; elementsAmount["abrasive"] = CraftLevels[ignoreCraftLevel]; modsAmount++; } } elementsAmount["fern_flower"] = fernFlowersCount(modsAmount); const craftCost = Object.keys(elementsAmount).reduce((total, key) => total + elementsAmount[key] * elementsPrices[key], 0); if(isLogCalculation) { const craftCostFormula = Object.keys(elementsAmount).map(key => `${key}: ${elementsAmount[key]}*${elementsPrices[key]} = ${elementsAmount[key] * elementsPrices[key]}`).join(" + "); console.log(`${craftInfo}, ${Object.keys(CraftType).find(key => CraftType[key] === craftType)}, ${craftCostFormula}=${craftCost}`); } return craftCost; } function fernFlowersCount(modsAmount) { let result = 0; if(modsAmount >= 1) { result += 2; } if(modsAmount >= 2) { result += 4; } if(modsAmount >= 3) { result += 6; } if(modsAmount >= 4) { result += 8; } if(modsAmount >= 5) { result += 10; } return result; } function parseDate(dateString, isFuture = false, isPast = false) { //console.log(dateString) if(!dateString) { return; } const dateStrings = dateString.split(" "); let hours = 0; let minutes = 0; let seconds = 0; const timePart = dateStrings.find(x => x.includes(":")); if(timePart) { var time = timePart.split(":"); hours = parseInt(time[0]); minutes = parseInt(time[1]); if(time.length > 2) { seconds = parseInt(time[2]); } } const now = new Date(); let year = now.getFullYear(); let month = now.getMonth(); let day = now.getDate(); const datePart = dateStrings.find(x => x.includes("-")); if(datePart) { const date = datePart.split("-"); month = parseInt(date[isEn ? (date.length == 3 ? 1 : 0) : 1]) - 1; day = parseInt(date[isEn ? (date.length == 3 ? 2 : 1) : 0]); if(date.length == 3) { year = isEn ? parseInt(date[0]) : parseInt(date[2]); if(year < 1000) { year += Math.floor((new Date()).getFullYear() / 1000) * 1000; } } else { if(isFuture && month == 0 && now.getMonth() == 11) { year += 1; } } } if(dateStrings.length > 2) { const letterDateExec = /(\d{2}):(\d{2}) (\d{2}) (.{3,4})/.exec(dateString); if(letterDateExec) { //console.log(letterDateExec) day = parseInt(letterDateExec[3]); //const monthNames = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']; const monthShortNames = ['янв', 'фев', 'март', 'апр', 'май', 'июнь', 'июль', 'авг', 'сент', 'окт', 'ноя', 'дек']; month = monthShortNames.findIndex(x => x.toLowerCase() == letterDateExec[4].toLowerCase()); if(isPast && (new Date(year, month, day, hours, minutes, seconds)).getTime() > Date.now()) { year -= 1; } } } //console.log(`year: ${year}, month: ${month}, day: ${day}, time[0]: ${time[0]}, time[1]: ${time[1]}, ${new Date(year, month, day, parseInt(time[0]), parseInt(time[1]))}`); return new Date(year, month, day, hours, minutes, seconds); } function observe(targets, handler, config = { childList: true, subtree: true }) { targets = Array.isArray(targets) ? targets : [targets]; targets = targets.map(x => { if(typeof x === 'function') { return x(document); } return x; }); // Можем передавать не элементы, а их селекторы const ob = new MutationObserver(async function(mut, observer) { //console.log(`Mutation start`); observer.disconnect(); if(handler.constructor.name === 'AsyncFunction') { await handler(); } else { handler(); } for(const target of targets) { if(target) { observer.observe(target, config); } } }); for(const target of targets) { if(target) { ob.observe(target, config); } } } // Start if(!this.GM_getValue) { this.GM_getValue = function(key, def) { return localStorage[key] || def; }; this.GM_setValue = function(key, value) { localStorage[key] = value; }; this.GM_deleteValue = function(key) { return delete localStorage[key]; }; } // ShowBigData(artefacts.reduce((t, a) => t + `, "${a.id}": { Strength: ${a.usual_dur}, RepairCost: ${a.repair_cost} }`, "")); main(); smithScheduling(); countExp(); findClanDepository(); findClanDepositoryRepair(); checkClanDepositoryNeedRepair(); showTradesToMeIndicator(); showThresholdPricesIndicator(); //console.log(Object.values(ArtifactInfo).reduce((c, e,) => Math.max(c, e.RepairCost), 0)); // Самый дорогой ремонт 64000 - 16 часов // for(let artId of Object.keys(ArtifactInfo)) { // let found = artefacts.find(x => x.id == artId); // if(found) { // ArtifactInfo[artId].CraftType = found.type; // } else { // ArtifactInfo[artId].CraftType = CraftType.Unknown; // } // } // ShowBigData(Object.keys(ArtifactInfo).reduce((t, a) => t + `, "${a}": { Strength: ${ArtifactInfo[a].Strength}, RepairCost: ${ArtifactInfo[a].RepairCost}, MarketCategory: "${ArtifactInfo[a].MarketCategory}", CraftType: ${ArtifactInfo[a].CraftType} }`, "")); //console.log(Object.values(ArtifactInfo).filter(x => x.MarketCategory == "").length); //console.log(`Script ${GM_info.script.name} work time ${millisecondsIntervalToString(Date.now() - stopwatchStartTime)}`);