您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Скрины с функционалом ниже. 1.) Показывает урон всех стеков одной стороны по одному выбранному стеку второй стороны. 2.) Если навести курсор на 1 существо, нажать 'e' (русская 'у'), сделать то же самое со вторым, то в чате появится урон первого по второму. Доп. выборы и настройка скорости анимации в настройках боя.
当前为
// ==UserScript== // @name battle_damage_tooltip // @namespace http://tampermonkey.net/ // @version 1.3.5 // @description Скрины с функционалом ниже. 1.) Показывает урон всех стеков одной стороны по одному выбранному стеку второй стороны. 2.) Если навести курсор на 1 существо, нажать 'e' (русская 'у'), сделать то же самое со вторым, то в чате появится урон первого по второму. Доп. выборы и настройка скорости анимации в настройках боя. // @author Something begins // @license None // @match https://www.heroeswm.ru/war* // @match https://my.lordswm.com/war* // @match https://www.lordswm.com/war* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant GM_setValue // @grant GM_getValue // @grant unsafeWindow // ==/UserScript== // Странные способы в некоторых местах обусловлены конфликтом со скриптом battleHelper от omne let outer_chat = document.getElementById("chat_format"); let atLaunch = true outer_chat.insertAdjacentHTML("beforeend", ` <div id="cre_distance_div" style="display: none"></div> <div id="individual_calc"></div> <div id="dmg_list_container"></div> <button id="dmg_list_refresh" style="background-color: #3d3d29; color: white; padding: 5px 10px; border: none; border-radius: 4px; font-size: 10px; cursor: pointer">Открыть</button> <select style="display : none; background-color: #333; color: white; margin: 10px" id="choose_cre"></select> <button id="change_side" style="background-color: #6b6b47; color: white; padding: 5px 10px; border: none; border-radius: 4px; font-size: 10px; cursor: pointer; display: none">Сменить сторону</button> <button id="collapse" style="background-color: #000000; color: white; padding: 5px 10px; border: none; border-radius: 4px; font-size: 10px; cursor: pointer; display: none; margin:10px">Свернуть</button> `) let calc_x, calc_y; let last_individual_calc = {} let isOpen = false let ini_weight = 10; let chosen = {side: 1, creature: "Высшие вампиры", afterSideSwitchCre: {"-1": "", "1": ""}} let chat = document.getElementById("chat_inside"); let select = document.getElementById("choose_cre") let refresh_button = document.getElementById("dmg_list_refresh") let side_button = document.getElementById("change_side") let collapse_button = document.getElementById("collapse") let individual_calc = document.querySelector("#individual_calc") let cre_distance_div = document.querySelector("#cre_distance_div") const settings_panel = document.querySelector("#webgl_settings_whole") let dmg_list_container = document.querySelector("#dmg_list_container") cre_distance_div.innerHTML = `<span>Выбранное расстояние: ${GM_getValue('cre_distance')}</span><br>` outer_chat.insertAdjacentHTML('afterbegin', `<div id = "battlehelper_div"></div>`) let battlehelper_div = document.querySelector('#battlehelper_div'); // ========= utils ============ function get_GM_value_if_exists(GM_key, default_value){ const GM_value = GM_getValue(GM_key) return GM_value!=undefined ? GM_value : default_value; } function getCurrentBattleSpeed(){ for(let i = 1; i<=3; i++){ let div = document.querySelector(`#speed${i}_button`) if (div.style.display === 'none') continue if (i === 1) return 2 else if (i === 3) return 1 else return 4 } } function setBattleSpeed(value){ if (value === 0) return value else if (value < 1) { unsafeWindow.timer_interval = Math.abs(value) * 20; return value } unsafeWindow.animspeed_def = unsafeWindow.animspeed = value unsafeWindow.animspeed_init = unsafeWindow.animspeed > 4 ? 0.5 : 2; unsafeWindow.timer_interval = Math.abs(value-20) !unsafeWindow.timer_interval && unsafeWindow.timer_interval++; return value } function individual_calc_innerHTML(atk_obj_index, def_obj_index){ if (atk_obj_index === undefined || def_obj_index === undefined) return "" let cre_collection = unsafeWindow.stage.pole.obj let attacker = cre_collection[atk_obj_index]; let defender = cre_collection[def_obj_index]; let dmg = get_dmg_info(atk_obj_index, def_obj_index) last_individual_calc.atk_obj_index = atk_obj_index; last_individual_calc.def_obj_index = def_obj_index; individual_calc.style.backgroundColor = "#000066" return ` <div id="individual_cre_heading" style="display:inline; background-color: #000066"> <span>Урон <br> </span> <span> <b>${attacker.nametxt}</b> [${attacker.nownumber}] по <b>${defender.nametxt}</b> [${defender.nownumber}]: <br> <br> </span> </div> <p id="${0}" style=" background-color: #000066"> <span style=color:#bfbfbf"></span> <b style="color:#ffffff; font-size: 120%; text-decoration: underline;">${dmg.min_killed}-${dmg.max_killed}</b> существ ( <span style="color:#ffffff">${dmg.min}-${dmg.max}</span>) </p> <br>` } function paint_coords(x,y, color){ let tile = shado[x + y*defxn] if (tile == undefined) return tile.fill(color) set_visible(tile,1) setTimeout(()=>{ tile.fill(null) set_visible(tile,0) },2077) } const observer = new MutationObserver((mutationsList, observer) => { for(const mutation of mutationsList) { if (mutation.type !== 'childList') return for (const addedNode of mutation.addedNodes) { if (!(addedNode.classList && addedNode.classList.contains('cont') || ["B", "BR"].includes(addedNode.tagName))) continue wrap_battlehelper(); battlehelper_div.style.display = battleHelper_on ? "inline" : "none"; } } }); function GM_toggle_boolean(GM_key, boolean){ boolean = !boolean GM_setValue(GM_key, boolean); return boolean } function set_Display(element_arr, displayProperty){ element_arr.forEach(element=>{ if (element == null) return element.style.display = displayProperty }) } function readjust_elements(){ chat = document.getElementById("chat_inside"); select = document.getElementById("choose_cre") refresh_button = document.getElementById("dmg_list_refresh") side_button = document.getElementById("change_side") collapse_button = document.getElementById("collapse") dmg_list_container = document.querySelector("#dmg_list_container") individual_calc = document.querySelector("#individual_calc") cre_distance_div = document.querySelector("#cre_distance_div") battlehelper_div = document.querySelector("#battlehelper_div") } // ----------------------------------- // ========= Настройки ============ let cre_distance = get_GM_value_if_exists('cre_distance', "") let cre_distance_on = get_GM_value_if_exists('cre_distance_on', false) let coeff_on = get_GM_value_if_exists('GM_coeff_on', false) let battleHelper_on = get_GM_value_if_exists('battleHelper_on', true) let animation_speed_on = get_GM_value_if_exists("animation_speed_on", false) const new_settings = ` <style> .tooltip { position: relative; display: inline-block; text-size: 150%; color: brown; text-decoration: underline; } .tooltip .tooltiptext { visibility: hidden; position: absolute; bottom: 100%; left: 50%; width: 5000%; transform: translateX(-30%); padding: 5px; background-color: #555; color: #fff; border-radius: 6px; word-wrap: break-word; } .tooltip:hover .tooltiptext { visibility: visible; } </style> <div class="info_row"> <label class="checkbox_container">коэф. урона <span class="tooltip">? <span class="tooltiptext">отношение урон/хп (т.е. у кого больше всех коэф., с того выгоднее начинать. <br>Работает в списке уронов если нажать на "Открыть" в чате)</span> </span> <input type="checkbox" checked="true" id="coeff_on"> <span class="checkbox_checkmark"></span> </label> </div> <div class="info_row"> <label class="checkbox_container">battleHelper в чате <span class="tooltip">? <span class="tooltiptext">выключает или включает начальное распределение АТБ шкалы от omne</span> </span> <input type="checkbox" checked="true" id="battleHelper_on"> <span class="checkbox_checkmark"></span> </label> </div> <div class="info_row"> <label class="checkbox_container">Расстояние между стеками <span class="tooltip">? <span class="tooltiptext">Расстояние между атакующим и защищающимся стеками. Выбирать расстояние стрелочками в текстовом поле снизу. <br> Влияет на статус урона стрелка (ближний/дальний урон, кривая/прямая стрела), разбег и прочие абилки, зависящие от расстояния. <br> Если выставить "Расстояние: 1", то стрелок будет считаться заблокированным. Если выставить расстояние больше 1, то стрелок будет считаться не заблокированным (даже если рядом с ним вражеское существо). </span> </span> <input type="checkbox" checked="true" id="cre_distance_on"> <span class="checkbox_checkmark"></span> </label> <input type="number" style="width: 4%; margin: 2px 2px 2px 80px" id="cre_distance" onkeydown="return false;" value=${cre_distance}> </div> <div class="info_row"> <label class="checkbox_container">Скорость анимации <span class="tooltip">? <span class="tooltiptext"> Скорость боевых анимаций. <br> Выбирать расстояние стрелочками в текстовом поле снизу или если зажать кнопку Alt и нажимать на стрелки клавиатуры.<br> Включить/выключить анимацию [Alt + P (русская З)].<br> Анимацию можно как ускорить, так и замедлить.<br>Верхний потолок у скорости 20, нижнего нету.<br> Негативный показатель означает скорость ниже возможной гвдшной. </span> </span> <input type="checkbox" checked="true" id="animation_speed_on"> <span class="checkbox_checkmark"></span> </label> <input type="number" style="width: 5%; margin: 2px 2px 2px 80px" id="anim_speed" onkeydown="return false;" > </div> ` settings_panel.insertAdjacentHTML("beforeend", new_settings) let settings_interval = setInterval(()=>{ if (Object.keys(unsafeWindow.stage.pole.obj).length !== 0){ document.querySelector("#coeff_on").checked = coeff_on document.querySelector("#battleHelper_on").checked = battleHelper_on document.querySelector("#cre_distance_on").checked = cre_distance_on document.querySelector("#animation_speed_on").checked = animation_speed_on let spd = get_GM_value_if_exists("anim_speed", getCurrentBattleSpeed()) document.querySelector("#anim_speed").value = spd if (GM_getValue("animation_speed_on")) setBattleSpeed(spd) clearInterval(settings_interval) } },300) const distance_counter = document.getElementById("cre_distance"); const anim_speed_counter = document.querySelector("#anim_speed") // ========= Event Listeners ============ document.body.addEventListener('input', function(event){ switch (event.target.id){ case "cre_distance": if (distance_counter.value < 1) { distance_counter.value = 1 return } if (!cre_distance_on) return GM_setValue('cre_distance', distance_counter.value) if (isOpen) refresh() individual_calc.innerHTML = individual_calc_innerHTML(last_individual_calc.atk_obj_index, last_individual_calc.def_obj_index) cre_distance_div.innerHTML = `<span>Выбранное расстояние: ${GM_getValue('cre_distance')}</span><br>` break; case "anim_speed": if (anim_speed_counter.value > 20){ anim_speed_counter.value = 20 return } GM_setValue('anim_speed', anim_speed_counter.value) if (!animation_speed_on) return setBattleSpeed(anim_speed_counter.value) break; } }); const anim_speed_input = document.querySelector('#anim_speed') document.addEventListener('keydown', event => { if (!event.altKey) return if (["P", "p", "з", "З"].includes(event.key)) { animation_speed_on = GM_toggle_boolean("animation_speed_on", GM_getValue("animation_speed_on")) document.querySelector("#animation_speed_on").checked = animation_speed_on if (animation_speed_on){ GM_setValue('anim_speed', anim_speed_counter.value) setBattleSpeed(anim_speed_counter.value); } else { setBattleSpeed(getCurrentBattleSpeed()); } } if (event.key === 'ArrowUp' || event.key === 'ArrowDown') { event.preventDefault(); const increment = event.key === 'ArrowUp' ? 1 : -1; anim_speed_input.value = parseInt(anim_speed_input.value) + increment; anim_speed_input.dispatchEvent(new Event('input', { bubbles: true })); } }); document.body.addEventListener('change', function(event) { switch (event.target.id){ case "coeff_on": coeff_on = GM_toggle_boolean("coeff_on", coeff_on) if (isOpen) refresh() break; case "battleHelper_on": battleHelper_on = GM_toggle_boolean("battleHelper_on", battleHelper_on) battlehelper_div.style.display = battleHelper_on ? "inline" : "none"; break case "choose_cre": chosen.creature = select.value refresh() break; case "cre_distance_on": cre_distance_on = GM_toggle_boolean("cre_distance_on", cre_distance_on) cre_distance_on ? GM_setValue('cre_distance', distance_counter.value): GM_setValue('cre_distance', "") if (cre_distance_on){ cre_distance_div.innerHTML = `<span>Выбранное расстояние: ${GM_getValue('cre_distance')}</span><br>` cre_distance_div.style.display = "inline" if (isOpen) refresh() individual_calc.innerHTML = individual_calc_innerHTML(last_individual_calc.atk_obj_index, last_individual_calc.def_obj_index) } else{ cre_distance_div.innerHTML = "" } if (isOpen) refresh() individual_calc.innerHTML = individual_calc_innerHTML(last_individual_calc.atk_obj_index, last_individual_calc.def_obj_index) break; case "animation_speed_on": animation_speed_on = GM_toggle_boolean("animation_speed_on", GM_getValue("animation_speed_on")) if (animation_speed_on){ GM_setValue('anim_speed', anim_speed_counter.value) setBattleSpeed(anim_speed_counter.value); } else { setBattleSpeed(getCurrentBattleSpeed()); } break; } }); document.body.addEventListener('click', function(event) { if (event.target.parentElement && /speed(.)_button/.test(event.target.parentElement.id)) { setBattleSpeed(getCurrentBattleSpeed()); document.querySelector("#animation_speed_on").checked = false GM_setValue('animation_speed_on', false) } switch(event.target.id){ case "dmg_list_refresh": readjust_elements() refresh() break case "change_side": chosen.afterSideSwitchCre[chosen.side] = chosen.creature chosen.side = - chosen.side chosen.creature = chosen.afterSideSwitchCre[chosen.side] refresh() break case "collapse": readjust_elements() isOpen = false refresh_button.innerHTML = "Открыть"; set_Display([select, side_button, collapse_button, document.querySelector("#chosen_cre_heading"), dmg_list_container, individual_calc, cre_distance_div], "none") break case "confirm_ins_img": observer.observe(outer_chat, { childList: true }); setTimeout(function() { observer.disconnect(); }, 190000); break; } }); // Урон одного стека по другому по выбору нажатием кнопки E window.addEventListener("keyup", event => { if ((document.querySelector("#chattext") !== document.activeElement) && (document.querySelector("#chattext_classic") !== document.activeElement)) { if (["e", "E", "у", "У"].includes(event.key)) { let cre_collection = unsafeWindow.stage.pole.obj if (mapobj[xr_last+yr_last*defxn] === undefined || cre_collection[mapobj[xr_last+yr_last*defxn]].rock === 1) { paint_coords(xr_last,yr_last,"#cccccc") return } if (!calc_x){ calc_x = xr_last calc_y = yr_last paint_coords(xr_last,yr_last,"#800000") } else { readjust_elements() let atk_obj_index = unsafeWindow.mapobj[calc_x+calc_y*defxn] let def_obj_index = unsafeWindow.mapobj[xr_last+yr_last*defxn] set_Display([individual_calc, collapse_button], "inline") if (cre_distance_on) { cre_distance_div.style.display = "inline"; cre_distance_div.innerHTML = `<span>Выбранное расстояние: ${GM_getValue('cre_distance')}</span><br>` } individual_calc.innerHTML = individual_calc_innerHTML(atk_obj_index, def_obj_index) calc_x = calc_y = null paint_coords(xr_last,yr_last,"blue") } } } }); // ----------------------------------- // ========= battleHelper ============ function wrap_battlehelper(){ for (const child of battlehelper_div.children) { if (child.className === "cont") return } readjust_elements(); let el_transfer = []; [...outer_chat.children].forEach(child=>{ if (["B","BR"].includes(child.tagName) || child.className == "cont"){ el_transfer.push(child) } }); for (const el of el_transfer) battlehelper_div.appendChild(el); const first_icons = battlehelper_div.querySelectorAll('br + div.cont'); let teams_text = [...outer_chat.childNodes].filter(node => (node.nodeType === node.TEXT_NODE && /Команда №(\d)/.test(node.textContent.trim()))); let i = 0 for (const img_div of first_icons){ img_div.previousSibling.insertAdjacentHTML('beforebegin', teams_text[i].textContent); i++; } for (const el of teams_text) el.remove() let title_arr = [...battlehelper_div.children].filter(child => child.textContent === "Стартовый бонус АТБ") if (battlehelper_div.children.length === 2 && title_arr.length === 1) { console.log(battlehelper_div.children) battlehelper_div.innerHTML = " " } } observer.observe(outer_chat, { childList: true }); setTimeout(function() { observer.disconnect(); }, 30000); // ----------------------------------- // Родная функция гвд с поправками на переменную l и модификаторами magic[] function attackmonster(attacker, ax, ay, x, y, defender,cre_distance, shootok, koef, inuse) { let cre_collection = unsafeWindow.stage.pole.obj var mainattack = 1; var ax1 = ax; var ay1 = ay; if (defender == 1000) return 0; if (defender <= 0) return 0; if (!cre_collection[defender]) return 0; if (cre_collection[defender]['hero']) return 0; if (cre_collection[defender]['rock']) return 0; if (koef == undefined) koef = 1; if (inuse == undefined) inuse = ''; var len = unsafeWindow.wmap2[y * defxn + x]; if ((cre_collection[attacker].x == x) && (cre_collection[attacker].y == y)) len = spd; shootok = 1; function getAdjacentAndDiagonalCoords(x, y) { const adjacentAndDiagonalCoords = []; adjacentAndDiagonalCoords.push([x + 1, y]); adjacentAndDiagonalCoords.push([x - 1, y]); adjacentAndDiagonalCoords.push([x, y + 1]); adjacentAndDiagonalCoords.push([x, y - 1]); adjacentAndDiagonalCoords.push([x + 1, y + 1]); adjacentAndDiagonalCoords.push([x - 1, y + 1]); adjacentAndDiagonalCoords.push([x + 1, y - 1]); adjacentAndDiagonalCoords.push([x - 1, y - 1]); return adjacentAndDiagonalCoords; } let attacker_adjacent_coords = getAdjacentAndDiagonalCoords(stage.pole.obj[attacker].x, stage.pole.obj[attacker].y) let enemies_list = Object.values(stage.pole.obj).filter(creature=>creature.side!=stage.pole.obj[attacker].side) enemies_list.forEach(enemy=>{ attacker_adjacent_coords.forEach(coord=>{ if (coord[0] == enemy.x && coord[1] == enemy.y) shootok = 0 }) }) if (cre_collection[attacker]['big']) { if (ax > x) { x++; }; if (ay > y) { y++; }; }; if (cre_collection[attacker]['bigx']) { if (ax > x) { x++; }; }; if (cre_collection[attacker]['bigy']) { if (ay > y) { y++; }; }; var spd = Math.max(0, Math.round((cre_collection[attacker].speed + cre_collection[attacker]['ragespeed'] + cre_collection[attacker]['speedaddon']) * cre_collection[attacker].speedmodifier)); if (unsafeWindow.magic[attacker]['ent']) { spd = 0; }; var movelen = spd - len; unsafeWindow.attacker_c = attacker; unsafeWindow.ax_c = ax; unsafeWindow.ay_c = ay; unsafeWindow.x_c = x; unsafeWindow.y_c = y; unsafeWindow.defender_c = defender; unsafeWindow.shootok_c = shootok; if ((x == 0) && (y == 0)) { x = cre_collection[attacker]['x']; y = cre_collection[attacker]['y']; }; if ((defender > 0) && (cre_collection[defender]['big'])) { if ((x - ax > 1) && (ax < x) && (defender == mapobj[ay * defxn + ax + 1])) { ax++; }; if ((y - ay > 1) && (ay < y) && (defender == mapobj[(ay + 1) * defxn + ax])) { ay++; }; if ((ax - x > 1) && (ax > x) && (defender == mapobj[ay * defxn + ax - 1])) { ax--; }; if ((ay - y > 1) && (ay > y) && (defender == mapobj[(ay - 1) * defxn + ax])) { ay--; }; }; if ((defender > 0) && (cre_collection[defender]['bigx'])) { if ((x - ax > 1) && (ax < x) && (defender == mapobj[ay * defxn + ax + 1])) { ax++; }; if ((ax - x > 1) && (ax > x) && (defender == mapobj[ay * defxn + ax - 1])) { ax--; }; }; if ((defender > 0) && (cre_collection[defender]['bigy'])) { if ((y - ay > 1) && (ay < y) && (defender == mapobj[(ay + 1) * defxn + ax])) { ay++; }; if ((ay - y > 1) && (ay > y) && (defender == mapobj[(ay - 1) * defxn + ax])) { ay--; }; }; let dx = x - ax; let dy = y - ay; l = dx * dx + dy * dy; if (movelen == undefined) movelen = 0; if (cre_distance !=="") { movelen = cre_distance l = Math.round(cre_distance * cre_distance) if (l > 2) shootok = 1 else shootok = 0 } unsafeWindow.PhysicalModifiers = 1; unsafeWindow.PhysicalModifiers *= koef; if (cre_collection[attacker]['shadowattack']) l = 0; var hera = 0; var herd = 0; len = unsafeWindow.stage.pole.obj_array.length; for (var k1 = 0; k1 < len; k1++) { unsafeWindow.k = unsafeWindow.stage.pole.obj_array[k1]; if ((cre_collection[k].hero) && (cre_collection[k].owner == cre_collection[attacker].owner)) hera = unsafeWindow.k; if ((cre_collection[k].hero) && (cre_collection[k].owner == cre_collection[defender].owner)) herd = unsafeWindow.k; }; if ((cre_collection[defender]['pirate']) && ((unsafeWindow.magic[defender]['sea']) || (unsafeWindow.gtype == 125) || (unsafeWindow.gtype == 126) || (unsafeWindow.gtype == 133))) { unsafeWindow.PhysicalModifiers *= 0.85; }; if (cre_collection[defender]['deadflesh']) { unsafeWindow.PhysicalModifiers *= 0.8; }; if (cre_collection[defender]['immaterial']) { unsafeWindow.PhysicalModifiers *= 0.65; }; if ((cre_collection[attacker]['oppressionofweak']) && (cre_collection[defender]['level'] == 1)) { unsafeWindow.PhysicalModifiers *= 1.5; }; if ((cre_collection[attacker]['fearofstrong']) && (cre_collection[defender]['level'] == 7)) { unsafeWindow.PhysicalModifiers *= 0.5; }; if ((hera > 0) && (unsafeWindow.magic[hera]['bna'])) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + unsafeWindow.magic[hera]['bna']['effect'] / 100); if ((cre_collection[defender]['mechanical']) && (unsafeWindow.magic[hera]['MEC'])) { unsafeWindow.PhysicalModifiers *= 1 + unsafeWindow.magic[hera]['MEC']['effect'] / 100; }; if ((cre_collection[attacker]['mechanical']) && (unsafeWindow.magic[hera]['mch'])) { unsafeWindow.PhysicalModifiers *= 1 + unsafeWindow.magic[hera]['mch']['effect'] / 100; }; }; if ((cre_collection[defender]['building']) && (!cre_collection[attacker]['siegewalls'])) { unsafeWindow.PhysicalModifiers *= 0.05; }; if ((defender > 0) && (cre_collection[attacker]['cruelty']) && ((cre_collection[defender]['nowhealth'] < cre_collection[defender]['maxhealth']) || (cre_collection[defender]['nownumber'] < cre_collection[defender]['maxnumber']))) { unsafeWindow.PhysicalModifiers *= 1.15; }; if ((defender > 0) && (cre_collection[attacker]['morecruelty']) && ((cre_collection[defender]['nowhealth'] < cre_collection[defender]['maxhealth']) || (cre_collection[defender]['nownumber'] < cre_collection[defender]['maxnumber']))) { unsafeWindow.PhysicalModifiers *= 1.3; }; if ((cre_collection[attacker]['giantkiller']) && (cre_collection[defender]['big'])) unsafeWindow.PhysicalModifiers *= 2; if ((cre_collection[attacker]['pygmykiller']) && (!cre_collection[defender]['big'])) unsafeWindow.PhysicalModifiers *= 1.33; if (cre_collection[attacker]['stormstrike']) unsafeWindow.PhysicalModifiers *= 2; if ((cre_collection[attacker]['undeadkiller']) && (cre_collection[defender]['undead'])) unsafeWindow.PhysicalModifiers *= 1.5; if ((cre_collection[attacker]['pirate']) && (unsafeWindow.magic[defender]['blb'])) unsafeWindow.PhysicalModifiers *= 1.5; if ((!cre_collection[attacker]['hero']) && (unsafeWindow.magic[attacker]['zat'])) { unsafeWindow.PhysicalModifiers *= 1.15; }; if ((herd > 0) && (unsafeWindow.magic[herd]['bnd'])) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers / (1 + unsafeWindow.magic[herd]['bnd']['effect'] / 100); }; if ((herd > 0) && (unsafeWindow.magic[herd]['fld'])) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 - unsafeWindow.magic[herd]['fld']['effect'] / 100); }; if ((herd > 0) && (unsafeWindow.magic[herd]['rcd']) && (monster_race[cre_collection[attacker]['id']] == unsafeWindow.magic[herd]['rcd']['effect'])) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.93; }; if (unsafeWindow.magic[attacker]['prp']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + unsafeWindow.magic[attacker]['prp']['effect'] / 100); }; if (unsafeWindow.magic[defender]['sta']) { unsafeWindow.PhysicalModifiers *= 0.5; }; if ((unsafeWindow.magic[attacker]['chd']) && (cre_collection[unsafeWindow.magic[attacker]['chd']['effect']]['nownumber'] > 0) && (unsafeWindow.magic[attacker]['chd']['effect'] != defender)) { unsafeWindow.PhysicalModifiers *= 0.55; }; unsafeWindow.PhysicalModifiers *= unsafeWindow.stage.pole.checkmembrane(defender); if (!cre_collection[attacker]['hero']) { if ((l <= 2) && (cre_collection[attacker]['shooter']) && (!cre_collection[attacker]['nopenalty']) && (!cre_collection[attacker]['warmachine'])) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5; }; if ((l > 2) && (cre_collection[attacker]['rangepenalty'])) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5; }; unsafeWindow.rangemod = 1; if ((l > 2) && (cre_collection[attacker]['shooter']) && (((cre_collection[attacker]['range'] < Math.sqrt(l)) && (!cre_collection[attacker].shadowattack)) || ((iswalls) && (!cre_collection[attacker]['hero']) && (unsafeWindow.checkwall(x, y, ax, ay))))) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5; unsafeWindow.rangemod = 0.5; }; if ((l > 2) && (cre_collection[attacker]['shooter']) && (iswalls2) && (!cre_collection[attacker]['hero']) && (((!cre_collection[attacker].siegewalls) || (btype == 118)) || (!cre_collection[defender].stone)) && (unsafeWindow.checkwall2(x, y, ax, ay, attacker))) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5; unsafeWindow.rangemod *= 0.5; }; }; var _PERK_ARCHERY = 11; var _PERK_EVASION = 22; if ((defender > 0) && (cre_collection[defender]['dodge']) && (((l <= 2) && (!cre_collection[attacker]['ballista']) && (inuse != 'ssh') && (inuse != 'mga') && (inuse != 'dcd') && (inuse != 'chs') && (!cre_collection[attacker]['hero'])) || (inuse == 'brs') || (inuse == 'cpt'))) { unsafeWindow.PhysicalModifiers *= 0.5; }; if ((shootok == 1) && (!cre_collection[attacker]['hero']) && (cre_collection[attacker]['shooter'])) { if (unsafeWindow.isperk(attacker, _PERK_ARCHERY)) unsafeWindow.PhysicalModifiers *= 1.2; if (unsafeWindow.isperk(defender, _PERK_EVASION)) unsafeWindow.PhysicalModifiers *= 0.8; if ((!cre_collection[defender]['lshield']) && (unsafeWindow.stage.pole.shieldother(defender))) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.75; }; if ((cre_collection[defender]['lshield']) || (cre_collection[defender]['hollowbones'])) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5; }; if (cre_collection[defender]['diamondarmor']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.1; }; if (cre_collection[defender]['shielded']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.75; }; if (cre_collection[defender]['unprotectedtarget']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 1.25; }; if (unsafeWindow.magic[defender]['dfm']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 - unsafeWindow.magic[defender]['dfm']['effect'] / 100); }; if (unsafeWindow.magic[attacker]['cnf']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 - unsafeWindow.magic[attacker]['cnf']['effect'] / 100); }; if (hera > 0) { if (unsafeWindow.magic[hera]['sat']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + unsafeWindow.magic[hera]['sat']['effect']) / 100; }; }; }; if ((!cre_collection[attacker]['hero']) && (unsafeWindow.isperk(attacker, _PERK_BLESS))) { unsafeWindow.PhysicalModifiers *= 1.04; }; let o = cre_collection[attacker]['owner']; if (unsafeWindow.magic[defender]['mf' + o]) { unsafeWindow.PhysicalModifiers *= 1 + unsafeWindow.magic[defender]['mf' + o]['effect'] / 100; }; if ((!cre_collection[attacker]['hero']) && (unsafeWindow.isperk(attacker, _PERK_FERVOR))) { unsafeWindow.PhysicalModifiers *= 1.03; }; if (hera > 0) { var h = hera; if ((unsafeWindow.magic[h]['nut']) && ((plid2 == -2) || (ohotnik_set_neutral()))) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + unsafeWindow.magic[h]['nut']['effect']) / 100; }; if ((unsafeWindow.magic[h]['mle']) && ((cre_collection[attacker].shooter && shootok==0)||(cre_collection[attacker].shooter!= 1) || cre_collection[attacker].shots==0)) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + unsafeWindow.magic[h]['mle']['effect']) / 100; }; if (unsafeWindow.magic[attacker]['fbd']) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + Math.floor(unsafeWindow.magic[attacker]['fbd']['effect'] / 10)) / 100; }; }; unsafeWindow.monatt = cre_collection[attacker]['attack'] + cre_collection[attacker]['attackaddon'] + cre_collection[attacker]['rageattack']; if ((defender > 0) && (cre_collection[attacker]['giantslayer']) && (cre_collection[defender]['big'])) unsafeWindow.monatt += 4; if ((!cre_collection[attacker]['undead']) && (!cre_collection[attacker]['hero']) && (!cre_collection[attacker]['perseverance'])) { unsafeWindow.frig2 = false; unsafeWindow.i = attacker; var bigx = cre_collection[i]['big']; var bigy = cre_collection[i]['big']; if (cre_collection[i]['bigx']) bigx = 1; if (cre_collection[i]['bigy']) bigy = 1; unsafeWindow.xd = cre_collection[i]['x']; unsafeWindow.yd = cre_collection[i]['y']; for (var xz = unsafeWindow.xd - 1; xz <= unsafeWindow.xd + 1 + bigx; xz++) { for (var yz = unsafeWindow.yd - 1; yz <= unsafeWindow.yd + 1 + bigy; yz++) { if ((!unsafeWindow.frig2) && (mapobj[yz * defxn + xz] > 0) && (cre_collection[mapobj[yz * defxn + xz]]['side'] != cre_collection[i]['side']) && (cre_collection[mapobj[yz * defxn + xz]]['festeringaura']) && (cre_collection[mapobj[yz * defxn + xz]]['nownumber'] > 0)) { unsafeWindow.monatt -= 4; unsafeWindow.frig2 = true; }; }; }; }; if ((unsafeWindow.magic[attacker]['bsr']) || (unsafeWindow.magic[attacker]['rof'])) { unsafeWindow.monatt += Math.floor((cre_collection[attacker]['defence'] + cre_collection[attacker]['defenceaddon'] + cre_collection[attacker]['ragedefence']) * cre_collection[attacker]['defencemodifier']); }; if (herd > 0) { h = herd; if ((unsafeWindow.magic[h]['mld']) && ((cre_collection[attacker].shooter && shootok==0)||(cre_collection[attacker].shooter!= 1) || cre_collection[attacker].shots==0)) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 - unsafeWindow.magic[h]['mld']['effect']) / 100; }; if ((unsafeWindow.magic[h]['_ia']) && (!cre_collection[attacker]['perseverance'])) { unsafeWindow.monatt *= (1 - unsafeWindow.magic[h]['_ia']['effect'] / 100); }; if ((!cre_collection[attacker]['hero']) && (cre_collection[attacker].shooter)&& (cre_collection[attacker].shots!=0) && (unsafeWindow.magic[h]['msk']) && shootok == 1) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 - unsafeWindow.magic[h]['msk']['effect']) / 100; }; }; unsafeWindow.defadd = 0; if (cre_collection[defender]['agility']) { if (!unsafeWindow.magic[defender]['agl']) unsafeWindow.defadd = cre_collection[defender]['speed'] * 2; }; if ((cre_collection[defender]['spirit']) && (!unsafeWindow.magic[defender]['spi'])) { unsafeWindow.PhysicalModifiers *= 0.5; }; if ((cre_collection[attacker]['rageagainsttheliving']) && (cre_collection[defender]['alive'])) { unsafeWindow.PhysicalModifiers *= 1.3; }; if ((cre_collection[defender]['defensivestance']) && (!unsafeWindow.magic[defender]['mvd'])) { unsafeWindow.defadd += 5; }; if ((!cre_collection[defender]['undead']) && (!cre_collection[defender]['armoured']) && (!cre_collection[defender]['organicarmor'])) { unsafeWindow.frig2 = false; unsafeWindow.i = defender; bigx = cre_collection[i]['big']; bigy = cre_collection[i]['big']; if (cre_collection[i]['bigx']) bigx = 1; if (cre_collection[i]['bigy']) bigy = 1; unsafeWindow.xd = cre_collection[i]['x']; unsafeWindow.yd = cre_collection[i]['y']; for (let xz = unsafeWindow.xd - 1; xz <= unsafeWindow.xd + 1 + bigx; xz++) { for (let yz = unsafeWindow.yd - 1; yz <= unsafeWindow.yd + 1 + bigy; yz++) { if ((!unsafeWindow.frig2) && (mapobj[yz * defxn + xz] > 0) && (cre_collection[mapobj[yz * defxn + xz]]['side'] != cre_collection[i]['side']) && (cre_collection[mapobj[yz * defxn + xz]]['festeringaura']) && (cre_collection[mapobj[yz * defxn + xz]]['nownumber'] > 0)) { unsafeWindow.defadd -= 4; unsafeWindow.frig2 = true; }; }; }; }; if ((attacker > 0) && (cre_collection[defender]['giantslayer']) && (cre_collection[attacker]['big'])) unsafeWindow.defadd += 4; unsafeWindow.mondef = Math.round((cre_collection[defender]['defence'] + cre_collection[defender]['defenceaddon'] + unsafeWindow.defadd + cre_collection[defender]['ragedefence']) * cre_collection[defender]['defencemodifier']); if (unsafeWindow.magic[defender]['bsr']) { unsafeWindow.mondef = 0; }; if ((cre_collection[attacker]['preciseshot']) && (l > 2) && (l <= 9) && (unsafeWindow.rangemod >= 1)) { unsafeWindow.mondef = 0; }; if ((cre_collection[attacker]['ignoredefence'])) { unsafeWindow.mondef *= (1 - cre_collection[attacker]['ignoredefence'] / 100); }; if (cre_collection[attacker]['crushingleadership']) { var morale_delta = unsafeWindow.stage.pole.getmorale(attacker) - unsafeWindow.stage.pole.getmorale(defender); if (morale_delta > 0) { unsafeWindow.mondef *= Math.max(0, 1 - morale_delta / 10); }; }; if (cre_collection[attacker]['sacredweapon']) { var dark_count = get_dark_count(defender); if (dark_count > 0) { unsafeWindow.mondef *= Math.max(0, 1 - 0.15 * dark_count); }; }; if (unsafeWindow.isperk(attacker, _PERK_PIERCING_LUCK)) { unsafeWindow.mondef *= 1 - Math.max(0, 0.025 * (cre_collection[attacker]['luck'] + cre_collection[attacker]['luckaddon'])); }; if ((cre_collection[defender]['ignoreattack'])) { unsafeWindow.monatt *= (1 - cre_collection[defender]['ignoreattack'] / 100); }; if ((cre_collection[attacker]['ridercharge']) && (movelen > 0)) { unsafeWindow.mondef = unsafeWindow.mondef * (5 - movelen) / 5; }; if ((cre_collection[attacker]['forcearrow']) && (!cre_collection[defender]['armoured']) && (!cre_collection[defender]['organicarmor']) && (l > 2)) { unsafeWindow.mondef *= 0.8; }; if ((cre_collection[attacker]['armorpiercing']) && (!cre_collection[defender]['armoured']) && (!cre_collection[defender]['organicarmor']) && (l > 2)) { unsafeWindow.mondef *= 0.5; }; if ((cre_collection[attacker]['jousting']) && (movelen > 0)) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + 0.05 * movelen); }; if (((cre_collection[attacker]['blindingcharge']) || (cre_collection[attacker]['charge'])) && (movelen > 0)) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + 0.1 * movelen); }; if ((cre_collection[defender]['shieldwall']) && (movelen > 0)) { unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * Math.max(0.1, 1 - 0.1 * movelen); }; if ((unsafeWindow.magic[defender]['enc']) && (unsafeWindow.magic[defender]['enc']['effect'] == 1)) { unsafeWindow.PhysicalModifiers *= 0.5; }; if ((cre_collection[attacker]['safeposition']) && (movelen == 0)) { unsafeWindow.PhysicalModifiers *= 1.5; }; if ((cre_collection[attacker]['agilesteed']) && (movelen > 0)) { unsafeWindow.PhysicalModifiers *= 1 - 0.05 * movelen; }; if (unsafeWindow.mondef < 0) { unsafeWindow.mondef = 0; }; unsafeWindow.air = 0; unsafeWindow.fire = 0; unsafeWindow.water = 0; unsafeWindow.earth = 0; if ((hera > 0) && (!cre_collection[attacker]['taran'])) { h = hera; if (unsafeWindow.magic[h]['_id']) { unsafeWindow.mondef *= (1 - unsafeWindow.magic[h]['_id']['effect'] / 100); }; if (unsafeWindow.magic[h]['_aa']) { unsafeWindow.air = unsafeWindow.magic[h]['_aa']['effect'] / 100; }; if (unsafeWindow.magic[h]['_af']) { unsafeWindow.fire = unsafeWindow.magic[h]['_af']['effect'] / 100; }; if (unsafeWindow.magic[h]['_aw']) { unsafeWindow.water = unsafeWindow.magic[h]['_aw']['effect'] / 100; }; if (unsafeWindow.magic[h]['_ae']) { unsafeWindow.earth = unsafeWindow.magic[h]['_ae']['effect'] / 100; }; }; if ((cre_collection[defender]['armoured']) || (cre_collection[defender]['organicarmor'])) { unsafeWindow.mondef = Math.round((cre_collection[defender]['defence'] + cre_collection[defender]['defenceaddon'] + cre_collection[defender]['ragedefence']) * cre_collection[defender]['defencemodifier']); }; if (unsafeWindow.monatt < 0) { unsafeWindow.monatt = 0; }; if (unsafeWindow.monatt > unsafeWindow.mondef) { unsafeWindow.AttackDefenseModifier = 1 + (unsafeWindow.monatt - unsafeWindow.mondef) * 0.05; } else { unsafeWindow.AttackDefenseModifier = 1 / (1 + (unsafeWindow.mondef - unsafeWindow.monatt) * 0.05); }; if (cre_collection[attacker]['hero']) { unsafeWindow.AttackDefenseModifier = 1; }; var _PERK_ATTACK1 = 8; var _PERK_ATTACK2 = 9; var _PERK_ATTACK3 = 10; var _PERK_DEFENSE1 = 19; var _PERK_DEFENSE2 = 20; var _PERK_DEFENSE3 = 21; if ((!cre_collection[attacker]['hero'])&& ((cre_collection[attacker].shooter && shootok == 0)||(cre_collection[attacker].shooter!= 1))) { if (unsafeWindow.isperk(attacker, _PERK_ATTACK3)) { unsafeWindow.PhysicalModifiers *= 1.3; } else { if (unsafeWindow.isperk(attacker, _PERK_ATTACK2)) { unsafeWindow.PhysicalModifiers *= 1.2; } else if (unsafeWindow.isperk(attacker, _PERK_ATTACK1)) unsafeWindow.PhysicalModifiers *= 1.1; }; if (unsafeWindow.isperk(defender, _PERK_DEFENSE3)) { unsafeWindow.PhysicalModifiers *= 0.7; } else { if (unsafeWindow.isperk(defender, _PERK_DEFENSE2)) { unsafeWindow.PhysicalModifiers *= 0.8; } else { if (unsafeWindow.isperk(defender, _PERK_DEFENSE1)) unsafeWindow.PhysicalModifiers *= 0.9; }; }; }; if ((cre_collection[attacker]['siegewalls']) && (cre_collection[defender]['stone'])) { unsafeWindow.PhysicalModifiers *= 10; }; var _PERK_COLD_STEEL = 14; var _PERK_FIERY_WRATH = 101; var _PERK_HELLFIRE_AURA = 123; var _PERK_RETRIBUTION = 16; if (unsafeWindow.isperk(attacker, _PERK_COLD_STEEL)) unsafeWindow.water = 1 - (1 - unsafeWindow.water) * (0.9); if (unsafeWindow.isperk(attacker, _PERK_FIERY_WRATH)) unsafeWindow.fire = 1 - (1 - unsafeWindow.fire) * (0.85); if (unsafeWindow.isperk(attacker, _PERK_HELLFIRE_AURA)) unsafeWindow.fire = 1 - (1 - unsafeWindow.fire) * (0.95); if (unsafeWindow.magic[attacker]['cre']) { unsafeWindow.air = 1 - (1 - unsafeWindow.air) * (1 - unsafeWindow.magic[attacker]['cre']['effect'] / 100); }; if (unsafeWindow.isperk(attacker, _PERK_RETRIBUTION)) unsafeWindow.PhysicalModifiers *= (1 + Math.min(Math.max(unsafeWindow.stage.pole.getmorale(attacker, x, y), 0), 5) / 20); if ((cre_collection[attacker]['viciousstrike']) && (Math.max(0, Math.round((cre_collection[defender]['speed'] + cre_collection[defender]['ragespeed'] + cre_collection[defender]['speedaddon']) * cre_collection[defender]['speedmodifier'])) == 0)) unsafeWindow.PhysicalModifiers *= 1.5; unsafeWindow.PhysicalModifiers *= unsafeWindow.stage.pole.magicmod(attacker, defender, unsafeWindow.fire, unsafeWindow.air, unsafeWindow.water, unsafeWindow.earth, 0.1); if ((cre_collection[attacker]['bloodfrenzy']) && (unsafeWindow.magic[defender]['fd1'])) { unsafeWindow.PhysicalModifiers *= 1.3; }; unsafeWindow.UmelkaModifiers = 1; if ((umelka[cre_collection[attacker]['owner']][0] > 0) && (umelka[cre_collection[defender]['owner']][0] > 0)) { unsafeWindow.k = umelka[cre_collection[attacker]['owner']][0]; if ((unsafeWindow.k > 0) && (unsafeWindow.k < 11)) { let j = umelka[cre_collection[defender]['owner']][k]; unsafeWindow.UmelkaModifiers = 1 - j * 0.03; }; }; unsafeWindow.NumCreatures = cre_collection[attacker]['nownumber']; let tsc = 0; bigx = cre_collection[defender]['big']; bigy = cre_collection[defender]['big']; if (cre_collection[defender]['bigx']) bigx = 1; if (cre_collection[defender]['bigy']) bigy = 1; for (var xs = cre_collection[defender]['x'] - 1; xs <= cre_collection[defender]['x'] + 1 + bigx; xs++) { for (var ys = cre_collection[defender]['y'] - 1; ys <= cre_collection[defender]['y'] + 1 + bigy; ys++) { if ((mapobj[xs + ys * defxn] > 0) && (mapobj[xs + ys * defxn] != defender) && (cre_collection[mapobj[xs + ys * defxn]]['shieldguard']) && (cre_collection[defender]['side'] == cre_collection[mapobj[xs + ys * defxn]]['side'])) { tsc++; }; }; }; unsafeWindow.PhysicalModifiers /= (tsc + 1); var minmag = 0; var maxmag = 0; if ((inuse == 'lep') && (cre_collection[attacker]['crashingleap'])) { unsafeWindow.Totalmagicdamage = 0; cre_collection[defender]['attacked'] = 1; unsafeWindow.stage.pole.attackmagic(attacker, defender, cre_collection[attacker]['nownumber'] * 4, 'cold', '', 0, 0, 0); minmag = unsafeWindow.Totalmagicdamage; unsafeWindow.Totalmagicdamage = 0; cre_collection[defender]['attacked'] = 1; unsafeWindow.stage.pole.attackmagic(attacker, defender, cre_collection[attacker]['nownumber'] * 6, 'cold', '', 0, 0, 0); maxmag = unsafeWindow.Totalmagicdamage; }; unsafeWindow.mindam = cre_collection[attacker]['mindam'] + cre_collection[attacker]['damageaddon'] + (cre_collection[attacker]['maxdam'] - cre_collection[attacker]['mindam']) * (cre_collection[attacker]['mindamaddon']) + cre_collection[attacker]['ragedamage']; unsafeWindow.maxdam = cre_collection[attacker]['maxdam'] + cre_collection[attacker]['damageaddon'] - (cre_collection[attacker]['maxdam'] - cre_collection[attacker]['mindam']) * (cre_collection[attacker]['maxdamaddon']) + cre_collection[attacker]['ragedamage']; h = hera; if ((h > 0) && (unsafeWindow.magic[h]) && (unsafeWindow.magic[h]['BLS']) && (unsafeWindow.magic[h]['BLS']['effect'] > 0)) unsafeWindow.mindam = unsafeWindow.maxdam; if ((h > 0) && (unsafeWindow.magic[h]) && (unsafeWindow.magic[h]['CRS']) && (unsafeWindow.magic[h]['CRS']['effect'] > 0)) unsafeWindow.maxdam = unsafeWindow.mindam; if ((cre_collection[attacker]['taran']) && (cre_collection[defender]['stone'])) { h = hera; unsafeWindow.mindam = Math.floor(Math.pow(cre_collection[h]['maxhealth'], 0.5) * 200 * cre_collection[attacker]['mindam']); unsafeWindow.maxdam = Math.floor(Math.pow(cre_collection[h]['maxhealth'], 0.5) * 400 * cre_collection[attacker]['maxdam']); }; if (cre_collection[attacker]['accuracy']) unsafeWindow.mindam = unsafeWindow.maxdam; unsafeWindow.BaseDamage = unsafeWindow.mindam; unsafeWindow.PhysicalDamage = unsafeWindow.NumCreatures * unsafeWindow.BaseDamage * unsafeWindow.AttackDefenseModifier * unsafeWindow.PhysicalModifiers * unsafeWindow.UmelkaModifiers + minmag; unsafeWindow.PhysicalDamage2 = unsafeWindow.NumCreatures * unsafeWindow.maxdam * unsafeWindow.AttackDefenseModifier * unsafeWindow.PhysicalModifiers * unsafeWindow.UmelkaModifiers + maxmag; if ((cre_collection[attacker]['deathstrike']) && (cre_collection[defender]['maxhealth'] < 400) && (!cre_collection[defender]['stone'])) { if ((cre_collection[defender]['nownumber'] - 1) * cre_collection[defender]['maxhealth'] + cre_collection[defender]['nowhealth'] > unsafeWindow.PhysicalDamage) { unsafeWindow.PhysicalDamage += cre_collection[defender]['maxhealth'] - unsafeWindow.PhysicalDamage % cre_collection[defender]['maxhealth']; }; if ((cre_collection[defender]['nownumber'] - 1) * cre_collection[defender]['maxhealth'] + cre_collection[defender]['nowhealth'] > unsafeWindow.PhysicalDamage2) { unsafeWindow.PhysicalDamage2 += cre_collection[defender]['maxhealth'] - unsafeWindow.PhysicalDamage2 % cre_collection[defender]['maxhealth']; }; }; if (cre_collection[attacker]['bladeofslaughter']) { unsafeWindow.PhysicalDamage += Math.min(500, cre_collection[defender]['nownumber'] * 2); unsafeWindow.PhysicalDamage2 += Math.min(500, cre_collection[defender]['nownumber'] * 2); }; if (unsafeWindow.magic[attacker]['brk']) { unsafeWindow.PhysicalDamage *= (1 + unsafeWindow.magic[attacker]['brk']['effect'] * 0.03); unsafeWindow.PhysicalDamage2 *= (1 + unsafeWindow.magic[attacker]['brk']['effect'] * 0.03); }; if (unsafeWindow.PhysicalDamage < 1) { unsafeWindow.PhysicalDamage = 1; }; if (unsafeWindow.PhysicalDamage2 < 1) { unsafeWindow.PhysicalDamage2 = 1; }; if ((cre_collection[attacker]['magicattack']) && (unsafeWindow.l > 2) && (unsafeWindow.stage.pole.issomething(defender, 'dampenmagic'))) unsafeWindow.PhysicalDamage = 0; if (unsafeWindow.magic[defender]['rag']) { unsafeWindow.PhysicalDamage = unsafeWindow.stage.pole.ragedamage(defender, unsafeWindow.PhysicalDamage); unsafeWindow.PhysicalDamage2 = unsafeWindow.stage.pole.ragedamage(defender, unsafeWindow.PhysicalDamage2); }; if ((cre_collection[attacker]['vorpalsword']) && (cre_collection[defender]['maxhealth'] < 400) && (!cre_collection[defender]['stone'])) { unsafeWindow.PhysicalDamage += cre_collection[defender]['maxhealth']; unsafeWindow.PhysicalDamage2 += cre_collection[defender]['maxhealth']; }; unsafeWindow.PhysicalDamage = Math.round(unsafeWindow.PhysicalDamage); unsafeWindow.PhysicalDamage2 = Math.round(unsafeWindow.PhysicalDamage2); if (cre_collection[defender]['pleasureinpain']) { unsafeWindow.PhysicalDamage = Math.round(unsafeWindow.PhysicalDamage * 0.9); unsafeWindow.PhysicalDamage2 = Math.round(unsafeWindow.PhysicalDamage2 * 0.9); }; if (cre_collection[defender]['raptureinagony']) { unsafeWindow.PhysicalDamage = Math.round(unsafeWindow.PhysicalDamage * 0.8); unsafeWindow.PhysicalDamage2 = Math.round(unsafeWindow.PhysicalDamage2 * 0.8); }; var totalh = (cre_collection[defender]['nownumber'] - 1) * cre_collection[defender]['maxhealth'] + cre_collection[defender]['nowhealth']; unsafeWindow.Uronkills = Math.floor(Math.min(unsafeWindow.PhysicalDamage, totalh) / cre_collection[defender]['maxhealth']); unsafeWindow.Uronkills2 = Math.floor(Math.min(unsafeWindow.PhysicalDamage2, totalh) / cre_collection[defender]['maxhealth']); var nowhealth = cre_collection[defender]['nowhealth'] - (Math.min(unsafeWindow.PhysicalDamage, totalh) - unsafeWindow.Uronkills * cre_collection[defender]['maxhealth']); var nowhealth2 = cre_collection[defender]['nowhealth'] - (Math.min(unsafeWindow.PhysicalDamage2, totalh) - unsafeWindow.Uronkills2 * cre_collection[defender]['maxhealth']); if (nowhealth <= 0) unsafeWindow.Uronkills++; if (nowhealth2 <= 0) unsafeWindow.Uronkills2++; unsafeWindow.tUronkills += unsafeWindow.Uronkills; unsafeWindow.tUronkills2 += unsafeWindow.Uronkills2; unsafeWindow.tPhysicalDamage += unsafeWindow.PhysicalDamage; unsafeWindow.tPhysicalDamage2 += unsafeWindow.PhysicalDamage2; return movelen } function get_dmg_info(attacker_obj_index, defender_obj_index){ let cre_collection = unsafeWindow.stage.pole.obj let attacker = cre_collection[attacker_obj_index] let defender = cre_collection[defender_obj_index] let dmg_dict = attackmonster(attacker_obj_index, attacker.x, attacker.y, defender.x, defender.y, defender_obj_index, GM_getValue("cre_distance")); let min_damage = unsafeWindow.PhysicalDamage let max_damage = unsafeWindow.PhysicalDamage2 let min_killed, max_killed; if (min_damage%defender.maxhealth>defender.nowhealth) min_killed = Math.floor(min_damage/defender.maxhealth) + 1 else min_killed = Math.floor(min_damage/defender.maxhealth) if (max_damage%defender.maxhealth>defender.nowhealth) max_killed = Math.floor(max_damage/defender.maxhealth) + 1 else max_killed = Math.floor(max_damage/defender.maxhealth) return {min: min_damage, max: max_damage, min_killed: min_killed, max_killed: max_killed} } let defender_obj_id = 0 let selected_id = 0 function refresh(){ isOpen = true let cre_collection = unsafeWindow.stage.pole.obj if (cre_distance_on) { cre_distance_div.style.display = "inline"; cre_distance_div.innerHTML = `<span>Выбранное расстояние: ${GM_getValue('cre_distance')}</span><br>` } set_Display([select, side_button, collapse_button, document.querySelector("#chosen_cre_heading"), dmg_list_container, individual_calc], "inline") refresh_button.innerHTML = "Обновить" let cre_list = Object.values(cre_collection); cre_list.sort(function(a, b) { return a.obj_index - b.obj_index; }); dmg_list_container.innerHTML = ""; [...select.children].forEach(child=>child.remove()) let found_defender = false cre_list.forEach(defender => { if (![0,-1].includes(defender.nownumber) && defender.nametxt!="" && defender.side == chosen.side && defender.hero == undefined){ let option_id = `cre_no${cre_list.indexOf(defender)}` select.insertAdjacentHTML("beforeend", `<option id = "${option_id}" value = "${defender.obj_index}">${defender.nametxt} [${defender.nownumber}] </option>`) if (!found_defender) { if (`${defender.obj_index}` == chosen.creature) found_defender = true defender_obj_id = defender.obj_index selected_id = [...select.children].indexOf(select.lastChild) } } }) dmg_list_container.insertAdjacentHTML("beforeend", `<div id = "chosen_cre_heading" style="display:inline;"> <span>Урон по </span><span style="color:#ffffff; font-size: 110%; font-weight: bold;">${cre_list[defender_obj_id-1].nametxt} [${cre_list[defender_obj_id-1].nownumber}] :</span> </div>`) cre_list.forEach(attacker => { if (attacker.side == -chosen.side && attacker.nownumber != 0 && attacker.nametxt != "") { let dmg = get_dmg_info(attacker.obj_index, defender_obj_id) let practical_overall_hp; if (cre_list[defender_obj_id-1].attack>attacker.defence){ practical_overall_hp = attacker.maxhealth*attacker.nownumber/(1+0.05*Math.abs(cre_list[defender_obj_id-1].attack-attacker.defence)) } else { practical_overall_hp = attacker.maxhealth*attacker.nownumber*(1+0.05*Math.abs(cre_list[defender_obj_id-1].attack-attacker.defence)) } let row_id = `row_no${cre_list.indexOf(attacker)}` let koef_string = `(коэф. урона <b>${( ((dmg.max + dmg.min) / 2) / practical_overall_hp ).toFixed(2)}</b>)` dmg_list_container.insertAdjacentHTML("beforeend", `<p id = "${row_id}"><span style = "text-decoration: underline;color:#bfbfbf" >${attacker.nametxt}</span> [${attacker.nownumber}] --> <b style = "color:#bfbfbf">${dmg.min_killed}-${dmg.max_killed}</b> существ (${dmg.min}-${dmg.max}) ${(attacker.hero == undefined&&coeff_on) ? koef_string : ""} </p>`) } }) select.options.item(selected_id).selected = true }