Greasy Fork is available in English.
Улучшенный рынок
// ==UserScript== // @name GN_Market // @namespace Gradient // @description Улучшенный рынок // @include /^https{0,1}:\/\/(www\.heroeswm\.ru|178\.248\.235\.15|my\.lordswm\.com)\/auction\.php.*/ // @exclude /.+cat=(res|elements|skeletons|dom|cert|part).*/ // @version 1.0.15 // ==/UserScript== "use strict"; //----------------------------------------------------------------------------// var script_name = 'GN_Market'; // Enter your script name here //----------------------------------------------------------------------------// (function(){ try{ // wrapper start //----------------------------------------------------------------------------// // UnifiedLibrary 1.7.0 start //----------------------------------------------------------------------------// //----------------------------------------------------------------------------// // SysUtils //----------------------------------------------------------------------------// var GN_SysUtils = new SysUtils(script_name); var SU = GN_SysUtils; //----------------------------------------------------------------------------// function SysUtils(name){ // wrapper start //----------------------------------------------------------------------------// this.show_error = function(error_string, use_alert){ if(use_alert) alert(error_string); throw new Error(error_string); }; if(arguments.length != 1) this.show_error('Wrong SysUtils arguments'); if(!arguments[0]) this.show_error('Empty SysUtils argument'); //----------------------------------------------------------------------------// this.compare = function(a, b){ return (a == b) ? 0 : (a > b ? 1 : -1); }; //----------------------------------------------------------------------------// this.save_value = function(desc, value){ var div = document.getElementById('GN_GM_Handler'); div.setAttribute('desc', desc); div.setAttribute('value', value); div.setAttribute('operation', 'save'); div.click(); if(div.getAttribute('state') != 'complete') this.show_error('Ошибка при сохранении значения'); }; //----------------------------------------------------------------------------// this.load_value = function(value, def){ var div = document.getElementById('GN_GM_Handler'); div.setAttribute('desc', value); div.setAttribute('operation', 'load'); div.click(); if(div.getAttribute('state') != 'complete') this.show_error('Ошибка при загрузке значения'); return (div.getAttribute('is_null') == 'true' ? def : div.getAttribute('value')); }; //----------------------------------------------------------------------------// var current_id = null; //----------------------------------------------------------------------------// function check_mandatory_scripts(alerter){ var persistent_storage_sign = document.getElementById('GN_GM_Handler'); var common_values_sign = document.getElementById('GN_CommonValuesSign'); var alert_sign = document.getElementById('GN_AlertSign'); if(!alert_sign){ alert_sign = document.createElement('div'); alert_sign.id = 'GN_AlertSign'; alert_sign.setAttribute('alerted', 'false'); document.body.appendChild(alert_sign); } var alerted = alert_sign.getAttribute('alerted') != 'false'; if(!persistent_storage_sign){ alert_sign.setAttribute('alerted', 'true'); alerter('Скрипт ' + name + ' требует для своей работы скрипт управления данными (GN_PersistentStorage), который должен стоять первым в порядке выполнения скриптов.\n' + 'Подробнее здесь: "https://greasyfork.org/ru/scripts/14049-Как-устанавливать-скрипты-читать-здесь"', !alerted); } if(!common_values_sign){ alert_sign.setAttribute('alerted', 'true'); alerter('Скрипт ' + name + ' требует для своей работы скрипт, хранящий данные (GN_CommonValuesFiller), который должен стоять вторым в порядке выполнения скриптов.\n' + 'Подробнее здесь: "https://greasyfork.org/ru/scripts/14049-Как-устанавливать-скрипты-читать-здесь"', !alerted); } } this.check_login = function(){ var re = /.*?pl_id=(\d+)[^\d]*?/gmi; var matches = re.exec(document.cookie.toString()); if(matches){ current_id = +matches[1]; check_mandatory_scripts(this.show_error); } }; //----------------------------------------------------------------------------// function get_char(e){ if(e.which && e.charCode){ if(e.which < 32) return null; return String.fromCharCode(+e.which) } return null; } this.number_input = function(e){ if(e.ctrlKey || e.altKey || e.metaKey) return false; var chr = get_char(e); return chr == null || (chr >= '0' && chr <= '9'); }; //----------------------------------------------------------------------------// this.show_el = function(el, visible){ el.style.display = visible ? '' : 'none'; }; //----------------------------------------------------------------------------// this.check_login(); //----------------------------------------------------------------------------// } // wrapper end //----------------------------------------------------------------------------// // CommonValues //----------------------------------------------------------------------------// var GN_CommonValues = new CommonValues(); //----------------------------------------------------------------------------// function CommonValues(){ // wrapper start //----------------------------------------------------------------------------// // Artefacts //----------------------------------------------------------------------------// // categories this.enum_ac = { unknown: 0, shop: 1, shop_gift: 2, stock: 3, hunter: 4, thief: 5, ranger: 6, tactic: 7, recruit: 8, war: 9, relict: 10, event: 11 }; this.artefacts = JSON.parse(SU.load_value('GN_CommonValues_Artefacts', '[]')); //----------------------------------------------------------------------------// this.get_artefact = function(id){ for(var i = 0; i < this.artefacts.length; ++i) if(this.artefacts[i].id == id) return this.artefacts[i]; return null; }; //----------------------------------------------------------------------------// // Elements //----------------------------------------------------------------------------// this.elements = JSON.parse(SU.load_value('GN_CommonValues_Elements', '[]')); //----------------------------------------------------------------------------// this.get_element = function(id){ for(var i = 0; i < this.elements.length; ++i) if(this.elements[i].id == id) return this.elements[i]; return null; }; //----------------------------------------------------------------------------// } // wrapper end //----------------------------------------------------------------------------// // UnifiedLibrary end //----------------------------------------------------------------------------// var show_error = SU.show_error; var load_value = SU.load_value; var save_value = SU.save_value; var compare = SU.compare; var show_el = SU.show_el; var number_input = SU.number_input; var CV = GN_CommonValues; var enum_ac = CV.enum_ac; var cats = [ { label: 'Магазин:', id: 'ShopChb', title: 'Отображать только артефакты из магазина' }, { label: 'Охота:', id: 'HunterChb', title: 'Отображать только охотничьи артефакты' }, { label: 'Ивент:', id: 'EventChb', title: 'Отображать только артефакты с ивентов' }, { label: 'Прочие', id: 'AnyOtherChb', title: 'Отображать все остальные артефакты' }, { label: 'Неизвестные:', id: 'UnknownChb', title: 'Отображать только неизвестные артефакты' } ]; var states = [ { label: 'Атака:', id: 'AttackInput' }, { label: 'Защита:', id: 'DefenceInput' }, { label: 'Сила магии:', id: 'SpellpowerInput' }, { label: 'Знания:', id: 'KnowledgeInput' }, { label: 'Инициатива:', id: 'InitiativeInput' }, { label: 'Боевой дух:', id: 'MoraleInput' }, { label: 'Удача:', id: 'LuckInput' } ]; var ex_states = [ { label: 'Защита от магии, %:', id: 'MagicProtectionInput' }, { label: 'Защита от физурона, %:', id: 'CloseCombatInput' }, { label: 'Защита от стрел, %:', id: 'RangeCombatInput' }, { label: 'Допурон в ближнем, %:', id: 'IncreaseCloseDamageInput' }, { label: 'Допурон стрелкам, %:', id: 'IncreaseRangeDamageInput' }, { label: 'Инициатива героя, %:', id: 'HeroInitiativeInput' } ]; var enum_s = { no: 0, yes: 1, all: 2 }; var selectors = [ { label: 'Прибыль:', id: 'ProfitSelect', options: [ { text: 'Только без', value: enum_s.no }, { text: 'Только с', value: enum_s.yes }, { text: 'Все', value: enum_s.all } ] }, { label: 'Повыш. прочность:', id: 'ExtendedDurabilitySelect', options: [ { text: 'Только без', value: enum_s.no }, { text: 'Только с', value: enum_s.yes }, { text: 'Все', value: enum_s.all } ] }, { label: 'Крафт:', id: 'CraftSelect', options: [ { text: 'Только без', value: enum_s.no }, { text: 'Только с', value: enum_s.yes }, { text: 'Все', value: enum_s.all } ] } ]; var options = [ { label: 'Расчет оптислома:', id: 'OptimumChb', title: 'Рассчитывать оптимальную прочность артефакта при починке у кузнецов' }, { label: 'Учитывать статы/доп.модификаторы:', id: 'ConsiderStatesChb', title: 'Учитывать стоимости статов/доп. модификаторов' }, { label: 'Сортировать по ОА/бой:', id: 'APChb', title: 'Сортировка по ОА/бой от меньшей к большей' }, { label: 'Сортировать по цзб(*):', id: 'OwnSortChb', title: 'Сортировка по цзб от меньшей к большей независимо от админской (* если включен расчет статов, сортируется по прибыли)' } ]; //----------------------------------------------------------------------------// var settings = load_settings(); var concrete_artefacts = []; var categories = []; var smith_prices = [ { efficiency : 0.9, cost : 1.0 }, { efficiency : 0.8, cost : 0.8 }, //{ efficiency : 0.7, cost : 0.65 }, //{ efficiency : 0.6, cost : 0.55 }, //{ efficiency : 0.5, cost : 0.45 }, //{ efficiency : 0.4, cost : 0.35 }, //{ efficiency : 0.3, cost : 0.2 }, //{ efficiency : 0.2, cost : 0.15 }, //{ efficiency : 0.1, cost : 0 }, ]; start_work(); //----------------------------------------------------------------------------// function start_work(){ var sel_form = document.querySelector("form[name='sel']"); if(!sel_form) show_error(script_name + ', не найдена форма выбора артефактов'); var header_next = sel_form.parentNode.parentNode.nextSibling; if(!header_next) show_error(script_name + ', не найдены заголовки таблицы продаваемых объектов'); draw_header(header_next); var own_td = header_next.nextSibling; if(!own_td) // no arts at page filter return; if(!own_td.hasAttribute('bgcolor')) own_td.id = script_name + 'OwnTd'; get_artefacts(header_next.parentNode); backup_categories(); show_proper_artefacts(); } //----------------------------------------------------------------------------// function draw_header(header_next) { var header = document.createElement('tr'); header_next.parentNode.insertBefore(header, header_next); var td = document.createElement('td'); td.setAttribute('colspan', '5'); header.appendChild(td); var table = document.createElement('table'); table.style.width = '100%'; td.appendChild(table); var tr = document.createElement('tr'); table.appendChild(tr); var expander = document.createElement('td'); expander.setAttribute('align', 'center'); var is_expanded = load_value(script_name + 'SettingsExpand', 'false') == 'true'; expander.setAttribute('expand', is_expanded ? 'true' : 'false'); expander.textContent = is_expanded ? 'Скрыть настройки' : 'Показать настройки'; expander.addEventListener('click', function(e){ e.preventDefault(); var expanded = expander.getAttribute('expand') == 'false'; show_el(settings_table, expanded); save_value(script_name + 'SettingsExpand', expanded ? 'true' : 'false'); expander.setAttribute('expand', expanded ? 'true' : 'false'); expander.textContent = expanded ? 'Скрыть настройки' : 'Показать настройки'; }); tr.appendChild(expander); tr = document.createElement('tr'); table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); var settings_table = document.createElement('table'); td.appendChild(settings_table); draw_bold_caption(settings_table, 'Уровни артефактов:'); tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); var text = document.createTextNode('Мин. уровень:'); td.appendChild(text); var min_lvl_input = document.createElement('input'); min_lvl_input.id = script_name + 'MinLvlInput'; min_lvl_input.type = 'text'; min_lvl_input.style.width = 30; min_lvl_input.value = settings.MinLvlInput; min_lvl_input.onkeypress = number_input; td.appendChild(min_lvl_input); text = document.createTextNode('Макс. уровень:'); td.appendChild(text); var max_lvl_input = document.createElement('input'); max_lvl_input.id = script_name + 'MaxLvlInput'; max_lvl_input.type = 'text'; max_lvl_input.style.width = 30; max_lvl_input.value = settings.MaxLvlInput; max_lvl_input.onkeypress = number_input; td.appendChild(max_lvl_input); draw_bold_caption(settings_table, 'Типы артефактов:'); tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); table = document.createElement('table'); td.appendChild(table); for(var i = 0; i < cats.length; i += 5){ tr = document.createElement('tr'); table.appendChild(tr); for(var j = i; j < i + 5 && j < cats.length; ++j){ td = document.createElement('td'); tr.appendChild(td); text = document.createTextNode(cats[j].label); td.appendChild(text); td = document.createElement('td'); tr.appendChild(td); var chb = document.createElement('input'); chb.type = 'checkbox'; chb.title = cats[j].title; chb.id = script_name + cats[j].id; chb.checked = settings[cats[j].id]; td.appendChild(chb); } } draw_bold_caption(settings_table, 'Стоимость статов артефактов:'); tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); states.forEach(function(current){ text = document.createTextNode(current.label); td.appendChild(text); var input = document.createElement('input'); input.id = script_name + current.id; input.type = 'text'; input.style.width = 30; input.value = settings[current.id]; input.onkeypress = number_input; td.appendChild(input); }); draw_bold_caption(settings_table, 'Стоимость доп.модификаторов артефактов:'); tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); table = document.createElement('table'); td.appendChild(table); for(var i = 0; i < ex_states.length; i += 3){ tr = document.createElement('tr'); table.appendChild(tr); for(var j = i; j < i + 3 && j < ex_states.length; ++j){ td = document.createElement('td'); tr.appendChild(td); text = document.createTextNode(ex_states[j].label); td.appendChild(text); td = document.createElement('td'); tr.appendChild(td); var input = document.createElement('input'); input.id = script_name + ex_states[j].id; input.type = 'text'; input.style.width = 30; input.value = settings[ex_states[j].id]; input.onkeypress = number_input; td.appendChild(input); } } draw_bold_caption(settings_table, 'Варианты отображения:'); tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); selectors.forEach(function(current){ text = document.createTextNode(current.label); td.appendChild(text); var select = document.createElement('select'); select.id = script_name + current.id; td.appendChild(select); var selected = settings[current.id]; current.options.forEach(function(current){ var option = document.createElement('option'); option.setAttribute('value', current.value); if(selected == current.value) option.selected = true; text = document.createTextNode(current.text); option.appendChild(text); select.appendChild(option); }); }); text = document.createTextNode('Процент крафта(от и выше):'); td.appendChild(text); var craft_input = document.createElement('input'); craft_input.id = script_name + 'CraftPercentInput'; craft_input.type = 'text'; craft_input.style.width = 30; craft_input.value = settings.CraftPercentInput; craft_input.onkeypress = number_input; td.appendChild(craft_input); draw_bold_caption(settings_table, 'Дополнительные настройки:'); tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); text = document.createTextNode('Добавочная стоимость:'); td.appendChild(text); var additional_input = document.createElement('input'); additional_input.id = script_name + 'AdditionalPriceInput'; additional_input.type = 'text'; additional_input.style.width = 60; additional_input.value = settings.AdditionalPriceInput; additional_input.onkeypress = number_input; td.appendChild(additional_input); draw_bold_caption(settings_table, 'Опции:'); tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); tr.appendChild(td); table = document.createElement('table'); td.appendChild(table); for(var i = 0; i < options.length; i += 3){ tr = document.createElement('tr'); table.appendChild(tr); for(var j = i; j < i + 3 && j < options.length; ++j){ td = document.createElement('td'); tr.appendChild(td); var text = document.createTextNode(options[j].label); td.appendChild(text); td = document.createElement('td'); tr.appendChild(td); var chb = document.createElement('input'); chb.type = 'checkbox'; chb.title = options[j].title; chb.id = script_name + options[j].id; chb.checked = settings[options[j].id]; td.appendChild(chb); } } tr = document.createElement('tr'); settings_table.appendChild(tr); td = document.createElement('td'); td.setAttribute('align', 'right'); tr.appendChild(td); var saver = document.createElement('input'); saver.type = 'button'; saver.value = 'Применить'; saver.addEventListener('click', function(e){ e.preventDefault(); save_settings(); show_proper_artefacts(); }); td.appendChild(saver); show_el(settings_table, is_expanded); } //----------------------------------------------------------------------------// function draw_bold_caption(parent, text){ var tr = document.createElement('tr'); parent.appendChild(tr); var td = document.createElement('td'); tr.appendChild(td); var b = document.createElement('b'); b.textContent = text; td.appendChild(b); } //----------------------------------------------------------------------------// function get_artefacts(parent){ var rows = parent.querySelectorAll('tr.wb'); for(var i = 0; i < rows.length; ++i){ var childs = rows[i].childNodes; if(childs[1].textContent != 'Купить сразу!') // NB another day continue; var lotid_el = childs[0].firstChild; var lotid = +lotid_el.getAttribute('name'); var id_el = lotid_el.nextSibling.querySelector('a'); var re = /art_info\.php\?id=([^&]*)/; var matches = re.exec(id_el.getAttribute('href')); if(!matches) // it`s not artefact, maybe element or another shit continue; var artefact = CV.get_artefact(matches[1]); var cur_dur = 1; var total_dur = 1; var dur_el = id_el.querySelectorAll('img')[1]; if(dur_el){ re = /Прочность: (\d{1,3})\/(\d{1,3})/; matches = re.exec(dur_el.outerHTML); cur_dur = +matches[1]; total_dur = +matches[2]; } re = /(\d{0,3},?\d{0,3},?\d{1,3}).*/; matches = re.exec(childs[2].textContent); var price = +matches[1].replace(/,/g, ''); var modificators = ''; if(dur_el){ re = /\[(.*)]/; matches = re.exec(dur_el.outerHTML); modificators = matches ? matches[1] : ''; } re = /(\d+) шт/; matches = re.exec(childs[0].innerHTML); var count = matches ? +matches[1] : 1; concrete_artefacts.push({ lotid: lotid, cur_dur: cur_dur, total_dur: total_dur, price: price, lot_price: price, count : count, modificators: modificators, dom: rows[i], art: artefact }); } } //----------------------------------------------------------------------------// function show_proper_artefacts(){ var sum = 0; for(var i = 0; i < concrete_artefacts.length; ++i){ var current = concrete_artefacts[i]; sum += current.price*current.count; // by cat if(!current.art){ if(!settings.UnknownChb){ show_el(current.dom, false); continue; } show_el(current.dom, true); } if(current.art){ switch(current.art.kind){ case enum_ac.shop: case enum_ac.stock: show_el(current.dom, settings.ShopChb); break; case enum_ac.hunter: show_el(current.dom, settings.HunterChb); break; case enum_ac.event: show_el(current.dom, settings.EventChb); break; case enum_ac.shop_gift: case enum_ac.thief: case enum_ac.ranger: case enum_ac.tactic: case enum_ac.recruit: case enum_ac.war: case enum_ac.relict: show_el(current.dom, settings.AnyOtherChb); break; } } if(current.dom.style.display == 'none') continue; current.price = current.lot_price + settings.AdditionalPriceInput; // fill desc + unknown current.ppb = current.price/current.cur_dur; var desc = current.dom.querySelector('td[valign="top"]'); var lot_link = desc.firstChild; lot_link.setAttribute('href', document.location + '#' + current.lotid); var ppb = document.getElementById(script_name + 'PPB' + current.lotid); if(!ppb){ ppb = document.createElement('p'); ppb.style.margin = '0px'; ppb.id = script_name + 'PPB' + current.lotid; desc.appendChild(ppb); } ppb.textContent = 'Цена за бой: ' + current.ppb.toFixed(2); var notes = document.getElementById(script_name + 'Notes' + current.lotid); if(!current.art){ if(!notes){ notes = document.createElement('p'); notes.style.margin = '0px'; notes.id = script_name + 'Notes' + current.lotid; var font = document.createElement('font'); font.color = 'red'; font.textContent = 'NB: неизвестен'; notes.appendChild(font); desc.appendChild(notes); } continue; } // by lvl if(current.art.lvl < settings.MinLvlInput || current.art.lvl > settings.MaxLvlInput) show_el(current.dom, false); // ppb/profit var craft_info = get_craft_info(current); current.additional_price = craft_info.price; current.craft_percent = craft_info.percent; var art_ppb = current.art.ppb; if(!art_ppb) art_ppb = NaN; //нет стандартной цены и не указана своя цена // by states var state_ppb = settings.AttackInput*current.art.states.attack + settings.DefenceInput*current.art.states.defence + settings.SpellpowerInput*current.art.states.spellpower + settings.KnowledgeInput*current.art.states.knowledge + settings.InitiativeInput*current.art.states.initiative + settings.MoraleInput*current.art.states.morale + settings.LuckInput*current.art.states.luck + settings.MagicProtectionInput*current.art.ex_states.magic_protection + settings.CloseCombatInput*current.art.ex_states.close_combat_protection + settings.RangeCombatInput*current.art.ex_states.range_combat_protection + settings.IncreaseRangeDamageInput*current.art.ex_states.increase_range_combat_damage + settings.IncreaseCloseDamageInput*current.art.ex_states.increase_close_combat_damage + settings.HeroInitiativeInput*current.art.ex_states.hero_initiative; current.profit = ((settings.ConsiderStatesChb ? state_ppb : art_ppb) - current.ppb)*current.cur_dur; // by optimum if(settings.OptimumChb){ var optimum_info = get_optimum_info(current); current.lot_ppb = current.ppb; current.ppb = optimum_info.ppb; current.profit = optimum_info.profit; ppb.textContent = 'Цена за бой: ' + current.ppb.toFixed(2); } if(settings.APChb && current.art) ppb.textContent += '[OA = ' + (current.ppb/Math.floor(current.art.ap*(1 + 0.02*current.craft_percent))).toFixed(2) + ']'; // by profit switch(settings.ProfitSelect){ case enum_s.no: show_el(current.dom, current.profit < 0); break; case enum_s.yes: show_el(current.dom, current.profit >= 0); break; } if(current.dom.style.display == 'none') continue; // by high durability switch(settings.ExtendedDurabilitySelect){ case enum_s.no: show_el(current.dom, current.total_dur <= current.art.usual_dur); break; case enum_s.yes: show_el(current.dom, current.total_dur > current.art.usual_dur); break; } if(current.dom.style.display == 'none') continue; // by craft switch(settings.CraftSelect){ case enum_s.no: show_el(current.dom, !current.modificators.length); break; case enum_s.yes: show_el(current.dom, current.modificators.length && current.craft_percent >= settings.CraftPercentInput); break; } if(current.dom.style.display == 'none') continue; // fill desc var profit = document.getElementById(script_name + 'Profit' + current.lotid); if(!profit){ profit = document.createElement('p'); profit.style.margin = '0px'; profit.id = script_name + 'Profit' + current.lotid; profit.textContent = 'Прибыль: '; var font = document.createElement('font'); font.color = 'black'; profit.appendChild(font); desc.appendChild(profit); } if(!isNaN(current.profit)){ var fix_profit = current.profit.toFixed(2); profit.lastChild.textContent = fix_profit; profit.lastChild.color = !fix_profit ? 'black' : (fix_profit < 0 ? 'red' : 'blue'); } else profit.parentNode.removeChild(profit); if(settings.OptimumChb){ if(current.cur_dur != optimum_info.battle_count){ var title = 'Чинить до 0/' + optimum_info.last_dur + ' у ' + optimum_info.smith.efficiency*100 + '/' + optimum_info.smith.cost*100 + ', боев: ' + optimum_info.battle_count + '[' + optimum_info.ppb.toFixed(2) + ']'; current.dom.setAttribute('title', title); } else { profit = document.getElementById(script_name + 'Profit' + current.lotid); if(profit) profit.parentNode.removeChild(profit); } } else current.dom.setAttribute('title', ''); } //sort if(settings.APChb){ var dom_els = []; concrete_artefacts.forEach(function(current){ if(current.dom.style.display != 'none' && current.art) dom_els.push({ ap: Math.floor(current.art.ap*(1 + 0.02*current.craft_percent)), ppb: current.ppb, dom: current.dom }); }); dom_els.sort(function(a, b){ return compare(a.ppb/a.ap, b.ppb/b.ap); }); dom_els.forEach(function(current){ var parent = current.dom.parentNode; var last = parent.lastChild; if(last != current.dom){ parent.appendChild(document.createElement('td')); parent.replaceChild(current.dom, parent.lastChild); } }); } if(settings.OwnSortChb){ var dom_els = []; concrete_artefacts.forEach(function(current){ if(current.dom.style.display != 'none' && current.art) dom_els.push({ profit: current.profit, ppb: current.ppb, dom: current.dom }); }); dom_els.sort(function(a, b){ if(settings.ConsiderStatesChb) return compare(b.profit, a.profit); return compare(a.ppb, b.ppb); }); dom_els.forEach(function(current){ var parent = current.dom.parentNode; var last = parent.lastChild; if(last != current.dom){ parent.appendChild(document.createElement('td')); parent.replaceChild(current.dom, parent.lastChild); } }); } // show sum var own_td = document.getElementById(script_name + 'OwnTd'); if(own_td) own_td.firstChild.textContent = 'Общая сумма: ' + sum; filter_categories(); } //----------------------------------------------------------------------------// function backup_categories(){ var marks = document.querySelectorAll('div[id*="mark_"] > a[href="#"]'); for(var i = 0; i < marks.length; ++i){ var mark = /mark_(.+)/.exec(marks[i].parentNode.id)[1]; categories.push({ mark: mark, closed: 'a2_' + mark, opened: 'a_' + mark}); } } //----------------------------------------------------------------------------// function get_category(mark){ for(var i = 0; i < categories.length; ++i) if(categories[i].mark == mark) return categories[i]; return null; } //----------------------------------------------------------------------------// function filter_categories(){ var marks = document.querySelectorAll('div[id*="mark_"] > a[href="#"]'); for(var i = 0; i < marks.length; ++i) show_native_category(marks[i]); marks = document.querySelectorAll('div[id*="mark_"] > a[href="#"]'); for(var i = 0; i < marks.length; ++i) hide_artefacts_in_category(marks[i]); set_current_mark_functions(); } //----------------------------------------------------------------------------// function show_native_category(el){ var mark = /mark_(.+)/.exec(el.parentNode.id)[1]; var category = get_category(mark); var closed = el.getAttribute('onclick').indexOf('a_' + mark) != -1; var invoke = closed ? category.closed : category.opened; eval(invoke)(); } //----------------------------------------------------------------------------// function hide_artefacts_in_category(el){ var mark = /mark_(.+)/.exec(el.parentNode.id)[1]; var marks = document.querySelectorAll('div[id="mark_info_' + mark + '"] > a'); for(var i = 0; i < marks.length; ++i){ var mark = /art_type=(.+)/.exec(marks[i].href)[1]; var artefact = CV.get_artefact(mark); if(!artefact) continue; if(artefact.lvl < settings.MinLvlInput || artefact.lvl > settings.MaxLvlInput){ var parent = marks[i].parentNode; if(marks[i].nextSibling){ parent.removeChild(marks[i].nextSibling); parent.removeChild(marks[i].nextSibling); // remove textNode } else parent.removeChild(marks[i].previousSibling); // remove textNode parent.removeChild(marks[i]); } } } //----------------------------------------------------------------------------// function set_current_mark_functions(){ var marks = document.querySelectorAll('div[id*="mark_"] > a[href="#"]'); for(var i = 0; i < marks.length; ++i){ var mark = /mark_(.+)/.exec(marks[i].parentNode.id)[1]; var closed = marks[i].getAttribute('onclick').indexOf('a_' + mark) != -1; if(!closed){ var inner = document.getElementById('mark_info_' + mark).innerHTML; window['a_' + mark] = function(id, content){ return function() { document.getElementById('mark_info_' + id).innerHTML = content; var a = document.getElementById('mark_' + id).querySelector('a'); a.setAttribute('onclick', 'a2_' + id + '(); return false'); } }(mark, inner); } else { var category = get_category(mark); window['a_' + mark] = function(id, cat){ return function() { cat.opened(); var a = document.querySelector('div[id="mark_' + id + '"] > a[href="#"]'); hide_artefacts_in_category(a); } }(mark, category); } } } //----------------------------------------------------------------------------// function get_optimum_info(concrete){ var smith_optimums = []; smith_prices.forEach(function(current){ smith_optimums.push({ optimum: get_optimum_by_smith(concrete, current), smith: current }); }); smith_optimums.sort(function(a, b){ return compare(a.optimum.ppb, b.optimum.ppb); }); var ppb = smith_optimums[0]; var profit = NaN; if(concrete.art.ppb && !settings.AdditionalPriceInput){ var better_ppb = (concrete.art.ppb - concrete.ppb) > 0 ? concrete.ppb : concrete.art.ppb; profit = ppb.optimum.battle_count*(better_ppb - ppb.optimum.ppb); } return { ppb: ppb.optimum.ppb, battle_count: ppb.optimum.battle_count, last_dur: ppb.optimum.last_dur, smith: ppb.smith, profit: profit }; } //----------------------------------------------------------------------------// function get_optimum_by_smith(concrete, smith){ var common_price = concrete.price; var common_durability = concrete.cur_dur; var durability = concrete.total_dur; var tmp_durability = durability; var previous_ppb = common_price/common_durability; var current_ppb = common_price/common_durability; while(current_ppb <= previous_ppb && tmp_durability > 0) { previous_ppb = current_ppb; common_durability += Math.floor(smith.efficiency*tmp_durability); common_price += (concrete.art.repair_cost*smith.cost*1.01 + 1); //комиссия current_ppb = common_price/common_durability; --tmp_durability; } ++tmp_durability; common_durability -= Math.floor(smith.efficiency*tmp_durability); return { ppb: previous_ppb, battle_count: common_durability, last_dur: tmp_durability }; } //----------------------------------------------------------------------------// function get_craft_info(concrete) { if(!concrete.modificators.length) return { price: 0, percent: 0 }; var element_count = [ 0, 1, 2, 4, 6, 9, 12, 15, 19, 24, 30, 37, 45 ]; function get_aprice(name){ return CV.get_element(name).average_price; } // 0 - weapon, 1 - armor, 2 - jewelry NB sync with art-types var element_needed = { A: [ get_aprice('wind_flower') + get_aprice('witch_flower'), get_aprice('wind_flower'), get_aprice('wind_flower') + get_aprice('meteorit') ], D: [ 0, get_aprice('moon_stone') + get_aprice('abrasive'), 0 ], E: [ get_aprice('meteorit') + get_aprice('badgrib'), get_aprice('meteorit'), get_aprice('meteorit') + get_aprice('tiger_tusk') ], F: [ get_aprice('fire_crystal') + get_aprice('tiger_tusk'), get_aprice('fire_crystal'), get_aprice('fire_crystal') + get_aprice('abrasive') ], I: [ get_aprice('moon_stone') + get_aprice('abrasive'), 0, 0 ], N: [ 0, 0, get_aprice('wind_flower') + get_aprice('tiger_tusk') ], W: [ get_aprice('ice_crystal') + get_aprice('snake_poison'), get_aprice('ice_crystal'), get_aprice('ice_crystal') + get_aprice('witch_flower') ] }; var price = 0, count = 0, percent = 0; var A, D, E, F, I, N, W; var r###lt = /A(\d+)/.exec(concrete.modificators); if(r###lt) { A = +r###lt[1]; percent += A; price += element_count[A]*element_needed.A[concrete.art.type]; ++count; } r###lt = /D(\d+)/.exec(concrete.modificators); if(r###lt) { D = +r###lt[1]; percent += D; price += element_count[D]*element_needed.D[concrete.art.type]; ++count; } r###lt = /E(\d+)/.exec(concrete.modificators); if(r###lt) { E = +r###lt[1]; percent += E; price += element_count[E]*element_needed.E[concrete.art.type]; ++count; } r###lt = /F(\d+)/.exec(concrete.modificators); if(r###lt) { F = +r###lt[1]; percent += F; price += element_count[F]*element_needed.F[concrete.art.type]; ++count; } r###lt = /I(\d+)/.exec(concrete.modificators); if(r###lt) { I = +r###lt[1]; percent += I; price += element_count[I]*element_needed.I[concrete.art.type]; ++count; } r###lt = /N(\d+)/.exec(concrete.modificators); if(r###lt) { N = +r###lt[1]; percent += N; price += element_count[N]*element_needed.N[concrete.art.type]; ++count; } r###lt = /W(\d+)/.exec(concrete.modificators); if(r###lt) { W = +r###lt[1]; percent += W; price += element_count[W]*element_needed.W[concrete.art.type]; ++count; } if(count > 4) price += get_aprice('fern_flower')*10; return { price: price, percent: percent }; } //----------------------------------------------------------------------------// function load_settings(){ var settings_ = load_value(script_name + 'Settings'); if(settings_) return JSON.parse(settings_); settings_ = { MinLvlInput: 1, MaxLvlInput: 23, CraftPercentInput: 0, AdditionalPriceInput: 0 }; cats.forEach(function(current){ settings_[current.id] = true; }); states.forEach(function(current){ settings_[current.id] = 10; }); ex_states.forEach(function(current){ settings_[current.id] = 1; }); selectors.forEach(function(current){ settings_[current.id] = enum_s.all; }); options.forEach(function(current){ settings_[current.id] = false; }); return settings_; } //----------------------------------------------------------------------------// function save_settings(){ var errors = []; var min_lvl = +document.getElementById(script_name + 'MinLvlInput').value; var max_lvl = +document.getElementById(script_name + 'MaxLvlInput').value; var craft_percent = +document.getElementById(script_name + 'CraftPercentInput').value; var additional_price = +document.getElementById(script_name + 'AdditionalPriceInput').value; if(isNaN(min_lvl) || min_lvl < 1 || min_lvl > 23) errors.push('Мин. уровень должен лежать между 1 и 23'); if(isNaN(max_lvl) || max_lvl < 1 || max_lvl > 23) errors.push('Макс. уровень должен лежать между 1 и 23'); if(min_lvl > max_lvl) errors.push('Макс. уровень не может быть меньше мин. уровня'); if(isNaN(craft_percent) || craft_percent < 0 || craft_percent > 60) errors.push('Процент крафта должен лежать между 0 и 60'); if(isNaN(additional_price) || additional_price < 0) errors.push('Добавочная стоимость должна выражаться положительным числом'); states.forEach(function(current){ var state = +document.getElementById(script_name + current.id).value; if(isNaN(state) || state < 0 || state > 100) errors.push('Стат [' + current.label + '] должен лежать между 0 и 100'); }); ex_states.forEach(function(current){ var state = +document.getElementById(script_name + current.id).value; if(isNaN(state) || state < 0 || state > 100) errors.push('Доп. модификатор [' + current.label + '] должен лежать между 0 и 100'); }); if(document.getElementById(script_name + 'OptimumChb').checked && document.getElementById(script_name + 'ConsiderStatesChb').checked) errors.push('Оптислом и подбор по статам не могут быть использованы одновременно'); if(document.getElementById(script_name + 'APChb').checked && document.getElementById(script_name + 'OwnSortChb').checked) errors.push('Сортировки по ОА и по цзб не могут быть использованы одновременно'); if(errors.length){ alert('Ошибки при сохранении:\n\n' + errors.join('\n')); return; } settings.MinLvlInput = min_lvl; settings.MaxLvlInput = max_lvl; settings.CraftPercentInput = craft_percent; settings.AdditionalPriceInput = additional_price; cats.forEach(function(current){ var chb = document.getElementById(script_name + current.id); settings[current.id] = chb.checked; }); states.forEach(function(current){ var state = +document.getElementById(script_name + current.id).value; settings[current.id] = state; }); ex_states.forEach(function(current){ var state = +document.getElementById(script_name + current.id).value; settings[current.id] = state; }); selectors.forEach(function(current){ var select = document.getElementById(script_name + current.id); var option = +select.options[select.selectedIndex].value; settings[current.id] = option; }); options.forEach(function(current){ var chb = document.getElementById(script_name + current.id); settings[current.id] = chb.checked; }); save_value(script_name + 'Settings', JSON.stringify(settings)); show_proper_artefacts(); } //----------------------------------------------------------------------------// } catch(e){ alert('Ошибка в скрипте ' + script_name + ', обратитесь к разработчику:\n' + e); throw e; }}()); // wrapper end //----------------------------------------------------------------------------//