// ==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 result = /A(\d+)/.exec(concrete.modificators);
if(result)
{
A = +result[1];
percent += A;
price += element_count[A]*element_needed.A[concrete.art.type];
++count;
}
result = /D(\d+)/.exec(concrete.modificators);
if(result)
{
D = +result[1];
percent += D;
price += element_count[D]*element_needed.D[concrete.art.type];
++count;
}
result = /E(\d+)/.exec(concrete.modificators);
if(result)
{
E = +result[1];
percent += E;
price += element_count[E]*element_needed.E[concrete.art.type];
++count;
}
result = /F(\d+)/.exec(concrete.modificators);
if(result)
{
F = +result[1];
percent += F;
price += element_count[F]*element_needed.F[concrete.art.type];
++count;
}
result = /I(\d+)/.exec(concrete.modificators);
if(result)
{
I = +result[1];
percent += I;
price += element_count[I]*element_needed.I[concrete.art.type];
++count;
}
result = /N(\d+)/.exec(concrete.modificators);
if(result)
{
N = +result[1];
percent += N;
price += element_count[N]*element_needed.N[concrete.art.type];
++count;
}
result = /W(\d+)/.exec(concrete.modificators);
if(result)
{
W = +result[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
//----------------------------------------------------------------------------//