battle_damage_tooltip

Скрины с функционалом ниже. 1.) Показывает урон всех стеков одной стороны по одному выбранному стеку второй стороны. 2.) Если навести курсор на 1 существо, нажать 'e' (русская 'у'), сделать то же самое со вторым, то в чате появится урон первого по второму. Доп. настройки в настройках боя.

目前为 2023-04-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name battle_damage_tooltip
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.9.1
  5. // @description Скрины с функционалом ниже. 1.) Показывает урон всех стеков одной стороны по одному выбранному стеку второй стороны. 2.) Если навести курсор на 1 существо, нажать 'e' (русская 'у'), сделать то же самое со вторым, то в чате появится урон первого по второму. Доп. настройки в настройках боя.
  6. // @author Something begins
  7. // @license None
  8. // @match https://www.heroeswm.ru/war*
  9. // @match https://my.lordswm.com/war*
  10. // @match https://www.lordswm.com/war*
  11. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  12. // @grant GM_setValue
  13. // @grant GM_getValue
  14. // @grant unsafeWindow
  15. // ==/UserScript==
  16. // Странные способы в некоторых местах обусловлены конфликтом со скриптом battleHelper от omne
  17. let outer_chat = document.getElementById("chat_format");
  18. outer_chat.insertAdjacentHTML("beforeend", `<div id = "individual_calc"></div><div id = "dmg_list_container"></div><br><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>
  19. <select style = "display : none; background-color: #333; color: white; margin: 10px" id = "choose_cre"></select>
  20. <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>
  21. <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>
  22. `)
  23. let calc_x, calc_y;
  24. let isOpen = false
  25. let ini_weight = 10;
  26. let chosen = {side: 1, creature: "Высшие вампиры", afterSideSwitchCre: {"-1": "", "1": ""}}
  27. let chat = document.getElementById("chat_inside");
  28. let select = document.getElementById("choose_cre")
  29. let refresh_button = document.getElementById("dmg_list_refresh")
  30. let side_button = document.getElementById("change_side")
  31. let collapse_button = document.getElementById("collapse")
  32. let individual_calc = document.querySelector("#individual_calc")
  33. const settings_panel = document.querySelector("#webgl_settings_whole")
  34. let dmg_list_container = document.querySelector("#dmg_list_container")
  35. // ========= utils ============
  36. function paint_coords(x,y, color){
  37. let tile = shado[x + y*defxn]
  38. if (tile == undefined) return
  39. tile.stroke(color)
  40. tile.fill(color)
  41. set_visible(tile,1)
  42.  
  43. setTimeout(()=>{
  44. tile.fill(null)
  45. set_visible(tile,0)
  46. },2077)
  47. }
  48. const observer = new MutationObserver((mutationsList, observer) => {
  49. for(const mutation of mutationsList) {
  50. if (mutation.type === 'childList') {
  51. for (const addedNode of mutation.addedNodes) {
  52. if (addedNode.classList && addedNode.classList.contains('cont') || ["B", "BR"].includes(addedNode.tagName)) {
  53. battleHelper_display(battleHelper_on)
  54. }
  55. }
  56. }
  57. }
  58. });
  59.  
  60. function GM_toggle_boolean(GM_key, boolean){
  61. boolean = !boolean
  62. GM_setValue(GM_key, boolean);
  63. return boolean
  64. }
  65. function set_Display(element_arr, displayProperty){
  66. element_arr.forEach(element=>{
  67. if (element == null) return
  68. element.style.display = displayProperty
  69. })
  70. }
  71. function readjust_elements(){
  72. chat = document.getElementById("chat_inside");
  73. select = document.getElementById("choose_cre")
  74. refresh_button = document.getElementById("dmg_list_refresh")
  75. side_button = document.getElementById("change_side")
  76. collapse_button = document.getElementById("collapse")
  77. dmg_list_container = document.querySelector("#dmg_list_container")
  78. individual_calc = document.querySelector("#individual_calc")
  79. }
  80. // -----------------------------------
  81. // ========= Настройки ============
  82. let coeff_on;
  83. const GM_coeff_on = GM_getValue('coeff_on')
  84. coeff_on = GM_coeff_on!=undefined ? GM_coeff_on : false;
  85.  
  86. let battleHelper_on;
  87. const GM_battleHelper_on = GM_getValue('battleHelper_on')
  88. battleHelper_on = GM_battleHelper_on!=undefined ? GM_battleHelper_on: true ;
  89. let new_settings = `<div class="info_row">
  90. <label class="checkbox_container">коэф. урона <span style = "font-size: 80%; color: grey">отношение урон/хп (т.е. у кого больше всех коэф., с того выгоднее начинать)</span><input type="checkbox" checked="true" id="coeff_on"><span class="checkbox_checkmark"></span>
  91. </label>
  92. </div>
  93. <div class="info_row">
  94. <label class="checkbox_container">battleHelper в чате <input type="checkbox" checked="true" id="battleHelper_on"><span class="checkbox_checkmark"></span>
  95. </label>
  96. </div>
  97. `
  98. settings_panel.insertAdjacentHTML("beforeend", new_settings)
  99.  
  100. let settings_interval = setInterval(()=>{
  101. let temp = document.querySelector("#coeff_on")
  102. if (temp){
  103. document.querySelector("#coeff_on").checked = coeff_on
  104. document.querySelector("#battleHelper_on").checked = battleHelper_on
  105. clearInterval(settings_interval)
  106. }
  107. },300)
  108.  
  109. document.querySelector("#win_Settings > div.fullLog_croppedArea.WinCroppedBlockHeight").addEventListener('change', function(event) {
  110. let child = event.target
  111. switch (child.id){
  112. case "coeff_on":
  113. coeff_on = GM_toggle_boolean("coeff_on", coeff_on)
  114. if (isOpen) refresh()
  115. break;
  116. case "battleHelper_on":
  117. battleHelper_on = GM_toggle_boolean("battleHelper_on", battleHelper_on)
  118. battleHelper_display(battleHelper_on)
  119. break
  120. }
  121. });
  122. // -----------------------------------
  123.  
  124. // ========= battleHelper ============
  125.  
  126. function battleHelper_display(ifDisplay){
  127. [...outer_chat.children].forEach(child=>{
  128. if (["B","BR"].includes(child.tagName) || child.className == "cont"){
  129. child.style.display = ifDisplay ? "inline" : "none"
  130. }
  131. })
  132. if (ifDisplay){
  133. if (!outer_chat.innerText.includes("Команда №1")) {
  134. let br_list = [...outer_chat.children].filter(br_element =>"BR" == br_element.tagName);
  135. let team_no = 0
  136. br_list.forEach(br_element=>{
  137. let index = br_list.indexOf(br_element)
  138. if (index%2==0 && index != br_list.length-2){
  139. team_no++;
  140. br_element.insertAdjacentHTML("afterend", `Команда ${team_no}`)
  141. }
  142. });
  143. }
  144. }
  145. else {
  146. const childNodes = outer_chat.childNodes;
  147. for (let i = 0; i < childNodes.length; i++) {
  148. const childNode = childNodes[i];
  149. if (childNode.nodeType === Node.TEXT_NODE) {
  150. const text = childNode.textContent.trim();
  151. if (text !== '') {
  152. childNode.textContent = '';
  153. }
  154. }
  155. }
  156. }
  157. }
  158. observer.observe(outer_chat, { childList: true });
  159. setTimeout(function() {
  160. observer.disconnect();
  161. }, 30000);
  162.  
  163. // -----------------------------------
  164.  
  165.  
  166. outer_chat.addEventListener('click', function(event) {
  167. let child = event.target
  168. switch(child.id){
  169. case "dmg_list_refresh":
  170. readjust_elements()
  171. refresh()
  172. break
  173. case "change_side":
  174. chosen.afterSideSwitchCre[chosen.side] = chosen.creature
  175. chosen.side = - chosen.side
  176. chosen.creature = chosen.afterSideSwitchCre[chosen.side]
  177. refresh()
  178. break
  179. case "collapse":
  180. readjust_elements()
  181. isOpen = false
  182. battleHelper_display(battleHelper_on);
  183. refresh_button.innerHTML = "Открыть";
  184. set_Display([select, side_button, collapse_button, document.querySelector("#chosen_cre_heading"), dmg_list_container, individual_calc], "none")
  185. break
  186. }
  187. })
  188. outer_chat.addEventListener('change', function() {
  189. chosen.creature = select.value
  190. refresh()
  191. });
  192. document.querySelector("#confirm_ins").addEventListener("click", event=>{
  193. observer.observe(outer_chat, { childList: true });
  194. setTimeout(function() {
  195. observer.disconnect();
  196. }, 30000);
  197. })
  198. // Урон одного стека по другому по выбору нажатием кнопки E
  199. window.addEventListener("keyup", event => {
  200. if ((document.querySelector("#chattext") !== document.activeElement) && (document.querySelector("#chattext_classic") !== document.activeElement)) {
  201. if (["e", "E", "у", "У"].includes(event.key)) {
  202. let cre_collection = unsafeWindow.stage.pole.obj
  203. if (mapobj[xr_last+yr_last*defxn] === undefined || cre_collection[mapobj[xr_last+yr_last*defxn]].rock === 1) {
  204. paint_coords(xr_last,yr_last,"#cccccc")
  205. return
  206. }
  207. if (!calc_x){
  208. calc_x = xr_last
  209. calc_y = yr_last
  210. paint_coords(xr_last,yr_last,"#800000")
  211. }
  212. else {
  213. readjust_elements()
  214. let atk_obj_index = unsafeWindow.mapobj[calc_x+calc_y*defxn]
  215. let def_obj_index = unsafeWindow.mapobj[xr_last+yr_last*defxn]
  216.  
  217. let attacker = cre_collection[atk_obj_index];
  218. let defender = cre_collection[def_obj_index];
  219. let dmg = get_dmg_info(atk_obj_index, def_obj_index)
  220. individual_calc.innerHTML = ""
  221. set_Display([individual_calc, collapse_button], "inline")
  222. individual_calc.style.backgroundColor = "#000066"
  223. individual_calc.insertAdjacentHTML("afterbegin", `<div id = "individual_cre_heading" style="display:inline; background-color: #000066">
  224. <span>Урон <br></span><span><b>${attacker.nametxt}</b> [${attacker.nownumber}] по <b>${defender.nametxt}</b> [${defender.nownumber}]: <br><br> </span>
  225. </div>`);
  226. individual_calc.insertAdjacentHTML("beforeend", `<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>`)
  227. calc_x = calc_y = null
  228. paint_coords(xr_last,yr_last,"blue")
  229. }
  230. }
  231. }
  232. })
  233.  
  234.  
  235. // Родная функция гвд с поправками на переменную l и модификаторами magic[]
  236. function attackmonster(attacker, ax, ay, x, y, defender, shootok, koef, inuse) {
  237. let cre_collection = unsafeWindow.stage.pole.obj
  238. var mainattack = 1;
  239. var ax1 = ax;
  240. var ay1 = ay;
  241. if (defender == 1000) return 0;
  242. if (defender <= 0) return 0;
  243. if (!cre_collection[defender]) return 0;
  244. if (cre_collection[defender]['hero']) return 0;
  245. if (cre_collection[defender]['rock']) return 0;
  246. if (koef == undefined) koef = 1;
  247. if (inuse == undefined) inuse = '';
  248. var len = unsafeWindow.wmap2[y * defxn + x];
  249. if ((cre_collection[attacker].x == x) && (cre_collection[attacker].y == y)) len = spd;
  250. shootok = 1;
  251. function getAdjacentAndDiagonalCoords(x, y) {
  252. const adjacentAndDiagonalCoords = [];
  253. adjacentAndDiagonalCoords.push([x + 1, y]);
  254. adjacentAndDiagonalCoords.push([x - 1, y]);
  255. adjacentAndDiagonalCoords.push([x, y + 1]);
  256. adjacentAndDiagonalCoords.push([x, y - 1]);
  257. adjacentAndDiagonalCoords.push([x + 1, y + 1]);
  258. adjacentAndDiagonalCoords.push([x - 1, y + 1]);
  259. adjacentAndDiagonalCoords.push([x + 1, y - 1]);
  260. adjacentAndDiagonalCoords.push([x - 1, y - 1]);
  261. return adjacentAndDiagonalCoords;
  262. }
  263. let attacker_adjacent_coords = getAdjacentAndDiagonalCoords(stage.pole.obj[attacker].x, stage.pole.obj[attacker].y)
  264. let enemies_list = Object.values(stage.pole.obj).filter(creature=>creature.side!=stage.pole.obj[attacker].side)
  265. enemies_list.forEach(enemy=>{
  266. attacker_adjacent_coords.forEach(coord=>{
  267. if (coord[0] == enemy.x && coord[1] == enemy.y) shootok = 0
  268. })
  269. })
  270.  
  271. if (cre_collection[attacker]['big']) {
  272. if (ax > x) {
  273. x++;
  274. };
  275. if (ay > y) {
  276. y++;
  277. };
  278. };
  279. if (cre_collection[attacker]['bigx']) {
  280. if (ax > x) {
  281. x++;
  282. };
  283. };
  284. if (cre_collection[attacker]['bigy']) {
  285. if (ay > y) {
  286. y++;
  287. };
  288. };
  289. var spd = Math.max(0, Math.round((cre_collection[attacker].speed + cre_collection[attacker]['ragespeed'] + cre_collection[attacker]['speedaddon']) * cre_collection[attacker].speedmodifier));
  290. if (unsafeWindow.magic[attacker]['ent']) {
  291. spd = 0;
  292. };
  293. var movelen = spd - len;
  294. unsafeWindow.attacker_c = attacker;
  295. unsafeWindow.ax_c = ax;
  296. unsafeWindow.ay_c = ay;
  297. unsafeWindow.x_c = x;
  298. unsafeWindow.y_c = y;
  299. unsafeWindow.defender_c = defender;
  300. unsafeWindow.shootok_c = shootok;
  301. if ((x == 0) && (y == 0)) {
  302. x = cre_collection[attacker]['x'];
  303. y = cre_collection[attacker]['y'];
  304. };
  305. if ((defender > 0) && (cre_collection[defender]['big'])) {
  306. if ((x - ax > 1) && (ax < x) && (defender == mapobj[ay * defxn + ax + 1])) {
  307. ax++;
  308. };
  309. if ((y - ay > 1) && (ay < y) && (defender == mapobj[(ay + 1) * defxn + ax])) {
  310. ay++;
  311. };
  312. if ((ax - x > 1) && (ax > x) && (defender == mapobj[ay * defxn + ax - 1])) {
  313. ax--;
  314. };
  315. if ((ay - y > 1) && (ay > y) && (defender == mapobj[(ay - 1) * defxn + ax])) {
  316. ay--;
  317. };
  318. };
  319. if ((defender > 0) && (cre_collection[defender]['bigx'])) {
  320. if ((x - ax > 1) && (ax < x) && (defender == mapobj[ay * defxn + ax + 1])) {
  321. ax++;
  322. };
  323. if ((ax - x > 1) && (ax > x) && (defender == mapobj[ay * defxn + ax - 1])) {
  324. ax--;
  325. };
  326. };
  327. if ((defender > 0) && (cre_collection[defender]['bigy'])) {
  328. if ((y - ay > 1) && (ay < y) && (defender == mapobj[(ay + 1) * defxn + ax])) {
  329. ay++;
  330. };
  331. if ((ay - y > 1) && (ay > y) && (defender == mapobj[(ay - 1) * defxn + ax])) {
  332. ay--;
  333. };
  334. };
  335. let dx = x - ax;
  336. let dy = y - ay;
  337. l = dx * dx + dy * dy;
  338.  
  339. if (movelen == undefined) movelen = 0;;
  340. unsafeWindow.PhysicalModifiers = 1;
  341. unsafeWindow.PhysicalModifiers *= koef;
  342. if (cre_collection[attacker]['shadowattack']) l = 0;
  343.  
  344. var hera = 0;
  345. var herd = 0;
  346. len = unsafeWindow.stage.pole.obj_array.length;
  347. for (var k1 = 0; k1 < len; k1++) {
  348. unsafeWindow.k = unsafeWindow.stage.pole.obj_array[k1];
  349.  
  350. if ((cre_collection[k].hero) && (cre_collection[k].owner == cre_collection[attacker].owner)) hera = unsafeWindow.k;
  351. if ((cre_collection[k].hero) && (cre_collection[k].owner == cre_collection[defender].owner)) herd = unsafeWindow.k;
  352. };
  353. if ((cre_collection[defender]['pirate']) && ((unsafeWindow.magic[defender]['sea']) || (unsafeWindow.gtype == 125) || (unsafeWindow.gtype == 126) || (unsafeWindow.gtype == 133))) {
  354. unsafeWindow.PhysicalModifiers *= 0.85;
  355. };
  356. if (cre_collection[defender]['deadflesh']) {
  357. unsafeWindow.PhysicalModifiers *= 0.8;
  358. };
  359. if (cre_collection[defender]['immaterial']) {
  360. unsafeWindow.PhysicalModifiers *= 0.65;
  361. };
  362. if ((cre_collection[attacker]['oppressionofweak']) && (cre_collection[defender]['level'] == 1)) {
  363. unsafeWindow.PhysicalModifiers *= 1.5;
  364. };
  365. if ((cre_collection[attacker]['fearofstrong']) && (cre_collection[defender]['level'] == 7)) {
  366. unsafeWindow.PhysicalModifiers *= 0.5;
  367. };
  368. if ((hera > 0) && (unsafeWindow.magic[hera]['bna'])) {
  369. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + unsafeWindow.magic[hera]['bna']['effect'] / 100);
  370. if ((cre_collection[defender]['mechanical']) && (unsafeWindow.magic[hera]['MEC'])) {
  371. unsafeWindow.PhysicalModifiers *= 1 + unsafeWindow.magic[hera]['MEC']['effect'] / 100;
  372. };
  373. if ((cre_collection[attacker]['mechanical']) && (unsafeWindow.magic[hera]['mch'])) {
  374. unsafeWindow.PhysicalModifiers *= 1 + unsafeWindow.magic[hera]['mch']['effect'] / 100;
  375. };
  376. };
  377. if ((cre_collection[defender]['building']) && (!cre_collection[attacker]['siegewalls'])) {
  378. unsafeWindow.PhysicalModifiers *= 0.05;
  379. };
  380. if ((defender > 0) && (cre_collection[attacker]['cruelty']) && ((cre_collection[defender]['nowhealth'] < cre_collection[defender]['maxhealth']) || (cre_collection[defender]['nownumber'] < cre_collection[defender]['maxnumber']))) {
  381. unsafeWindow.PhysicalModifiers *= 1.15;
  382. };
  383. if ((defender > 0) && (cre_collection[attacker]['morecruelty']) && ((cre_collection[defender]['nowhealth'] < cre_collection[defender]['maxhealth']) || (cre_collection[defender]['nownumber'] < cre_collection[defender]['maxnumber']))) {
  384. unsafeWindow.PhysicalModifiers *= 1.3;
  385. };
  386. if ((cre_collection[attacker]['giantkiller']) && (cre_collection[defender]['big'])) unsafeWindow.PhysicalModifiers *= 2;
  387. if ((cre_collection[attacker]['pygmykiller']) && (!cre_collection[defender]['big'])) unsafeWindow.PhysicalModifiers *= 1.33;
  388. if (cre_collection[attacker]['stormstrike']) unsafeWindow.PhysicalModifiers *= 2;
  389. if ((cre_collection[attacker]['undeadkiller']) && (cre_collection[defender]['undead'])) unsafeWindow.PhysicalModifiers *= 1.5;
  390. if ((cre_collection[attacker]['pirate']) && (unsafeWindow.magic[defender]['blb'])) unsafeWindow.PhysicalModifiers *= 1.5;
  391. if ((!cre_collection[attacker]['hero']) && (unsafeWindow.magic[attacker]['zat'])) {
  392. unsafeWindow.PhysicalModifiers *= 1.15;
  393. };
  394. if ((herd > 0) && (unsafeWindow.magic[herd]['bnd'])) {
  395. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers / (1 + unsafeWindow.magic[herd]['bnd']['effect'] / 100);
  396. };
  397. if ((herd > 0) && (unsafeWindow.magic[herd]['fld'])) {
  398. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 - unsafeWindow.magic[herd]['fld']['effect'] / 100);
  399. };
  400. if ((herd > 0) && (unsafeWindow.magic[herd]['rcd']) && (monster_race[cre_collection[attacker]['id']] == unsafeWindow.magic[herd]['rcd']['effect'])) {
  401. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.93;
  402. };
  403. if (unsafeWindow.magic[attacker]['prp']) {
  404. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + unsafeWindow.magic[attacker]['prp']['effect'] / 100);
  405. };
  406. if (unsafeWindow.magic[defender]['sta']) {
  407. unsafeWindow.PhysicalModifiers *= 0.5;
  408. };
  409. if ((unsafeWindow.magic[attacker]['chd']) && (cre_collection[unsafeWindow.magic[attacker]['chd']['effect']]['nownumber'] > 0) && (unsafeWindow.magic[attacker]['chd']['effect'] != defender)) {
  410. unsafeWindow.PhysicalModifiers *= 0.55;
  411. };
  412. unsafeWindow.PhysicalModifiers *= unsafeWindow.stage.pole.checkmembrane(defender);
  413. if (!cre_collection[attacker]['hero']) {
  414. if ((l <= 2) && (cre_collection[attacker]['shooter']) && (!cre_collection[attacker]['nopenalty']) && (!cre_collection[attacker]['warmachine'])) {
  415. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5;
  416. };
  417. if ((l > 2) && (cre_collection[attacker]['rangepenalty'])) {
  418. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5;
  419. };
  420. unsafeWindow.rangemod = 1;
  421. 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))))) {
  422. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5;
  423. unsafeWindow.rangemod = 0.5;
  424. };
  425. 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))) {
  426. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5;
  427. unsafeWindow.rangemod *= 0.5;
  428. };
  429. };
  430. var _PERK_ARCHERY = 11;
  431. var _PERK_EVASION = 22;
  432. 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'))) {
  433. unsafeWindow.PhysicalModifiers *= 0.5;
  434. };
  435. if (((l > 2) || (shootok == 1)) && (!cre_collection[attacker]['hero']) && (cre_collection[attacker]['shooter'])) {
  436. if (unsafeWindow.isperk(attacker, _PERK_ARCHERY)) unsafeWindow.PhysicalModifiers *= 1.2;
  437. if (unsafeWindow.isperk(defender, _PERK_EVASION)) unsafeWindow.PhysicalModifiers *= 0.8;
  438. if ((!cre_collection[defender]['lshield']) && (unsafeWindow.stage.pole.shieldother(defender))) {
  439. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.75;
  440. };
  441. if ((cre_collection[defender]['lshield']) || (cre_collection[defender]['hollowbones'])) {
  442. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.5;
  443. };
  444. if (cre_collection[defender]['diamondarmor']) {
  445. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.1;
  446. };
  447. if (cre_collection[defender]['shielded']) {
  448. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 0.75;
  449. };
  450. if (cre_collection[defender]['unprotectedtarget']) {
  451. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * 1.25;
  452. };
  453. if (unsafeWindow.magic[defender]['dfm']) {
  454. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 - unsafeWindow.magic[defender]['dfm']['effect'] / 100);
  455. };
  456. if (unsafeWindow.magic[attacker]['cnf']) {
  457. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 - unsafeWindow.magic[attacker]['cnf']['effect'] / 100);
  458. };
  459.  
  460. if (hera > 0) {
  461. if (unsafeWindow.magic[hera]['sat']) {
  462. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + unsafeWindow.magic[hera]['sat']['effect']) / 100;
  463. };
  464. };
  465. };
  466. if ((!cre_collection[attacker]['hero']) && (unsafeWindow.isperk(attacker, _PERK_BLESS))) {
  467. unsafeWindow.PhysicalModifiers *= 1.04;
  468. };
  469. let o = cre_collection[attacker]['owner'];
  470. if (unsafeWindow.magic[defender]['mf' + o]) {
  471. unsafeWindow.PhysicalModifiers *= 1 + unsafeWindow.magic[defender]['mf' + o]['effect'] / 100;
  472. };
  473. if ((!cre_collection[attacker]['hero']) && (unsafeWindow.isperk(attacker, _PERK_FERVOR))) {
  474. unsafeWindow.PhysicalModifiers *= 1.03;
  475. };
  476. if (hera > 0) {
  477. var h = hera;
  478. if ((unsafeWindow.magic[h]['nut']) && ((plid2 == -2) || (ohotnik_set_neutral()))) {
  479. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + unsafeWindow.magic[h]['nut']['effect']) / 100;
  480. };
  481. if ((unsafeWindow.magic[h]['mle']) && ((cre_collection[attacker].shooter && shootok==0)||(cre_collection[attacker].shooter!= 1) || cre_collection[attacker].shots==0)) {
  482. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + unsafeWindow.magic[h]['mle']['effect']) / 100;
  483. };
  484. if (unsafeWindow.magic[attacker]['fbd']) {
  485. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 + Math.floor(unsafeWindow.magic[attacker]['fbd']['effect'] / 10)) / 100;
  486. };
  487. };
  488. unsafeWindow.monatt = cre_collection[attacker]['attack'] + cre_collection[attacker]['attackaddon'] + cre_collection[attacker]['rageattack'];
  489. if ((defender > 0) && (cre_collection[attacker]['giantslayer']) && (cre_collection[defender]['big'])) unsafeWindow.monatt += 4;
  490. if ((!cre_collection[attacker]['undead']) && (!cre_collection[attacker]['hero']) && (!cre_collection[attacker]['perseverance'])) {
  491. unsafeWindow.frig2 = false;
  492. unsafeWindow.i = attacker;
  493. var bigx = cre_collection[i]['big'];
  494. var bigy = cre_collection[i]['big'];
  495. if (cre_collection[i]['bigx']) bigx = 1;
  496. if (cre_collection[i]['bigy']) bigy = 1;
  497. unsafeWindow.xd = cre_collection[i]['x'];
  498. unsafeWindow.yd = cre_collection[i]['y'];
  499. for (var xz = unsafeWindow.xd - 1; xz <= unsafeWindow.xd + 1 + bigx; xz++) {
  500. for (var yz = unsafeWindow.yd - 1; yz <= unsafeWindow.yd + 1 + bigy; yz++) {
  501. 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)) {
  502. unsafeWindow.monatt -= 4;
  503. unsafeWindow.frig2 = true;
  504. };
  505. };
  506. };
  507. };
  508.  
  509. if ((unsafeWindow.magic[attacker]['bsr']) || (unsafeWindow.magic[attacker]['rof'])) {
  510. unsafeWindow.monatt += Math.floor((cre_collection[attacker]['defence'] + cre_collection[attacker]['defenceaddon'] + cre_collection[attacker]['ragedefence']) * cre_collection[attacker]['defencemodifier']);
  511. };
  512. if (herd > 0) {
  513. h = herd;
  514. if ((unsafeWindow.magic[h]['mld']) && ((cre_collection[attacker].shooter && shootok==0)||(cre_collection[attacker].shooter!= 1) || cre_collection[attacker].shots==0)) {
  515. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 - unsafeWindow.magic[h]['mld']['effect']) / 100;
  516. };
  517. if ((unsafeWindow.magic[h]['_ia']) && (!cre_collection[attacker]['perseverance'])) {
  518. unsafeWindow.monatt *= (1 - unsafeWindow.magic[h]['_ia']['effect'] / 100);
  519. };
  520. if ((!cre_collection[attacker]['hero']) && (cre_collection[attacker].shooter)&& (cre_collection[attacker].shots!=0) && (unsafeWindow.magic[h]['msk']) && shootok == 1) {
  521. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (100 - unsafeWindow.magic[h]['msk']['effect']) / 100;
  522. };
  523. };
  524. unsafeWindow.defadd = 0;
  525. if (cre_collection[defender]['agility']) {
  526. if (!unsafeWindow.magic[defender]['agl']) unsafeWindow.defadd = cre_collection[defender]['speed'] * 2;
  527. };
  528. if ((cre_collection[defender]['spirit']) && (!unsafeWindow.magic[defender]['spi'])) {
  529. unsafeWindow.PhysicalModifiers *= 0.5;
  530. };
  531. if ((cre_collection[attacker]['rageagainsttheliving']) && (cre_collection[defender]['alive'])) {
  532. unsafeWindow.PhysicalModifiers *= 1.3;
  533. };
  534. if ((cre_collection[defender]['defensivestance']) && (!unsafeWindow.magic[defender]['mvd'])) {
  535. unsafeWindow.defadd += 5;
  536. };
  537. if ((!cre_collection[defender]['undead']) && (!cre_collection[defender]['armoured']) && (!cre_collection[defender]['organicarmor'])) {
  538. unsafeWindow.frig2 = false;
  539. unsafeWindow.i = defender;
  540. bigx = cre_collection[i]['big'];
  541. bigy = cre_collection[i]['big'];
  542. if (cre_collection[i]['bigx']) bigx = 1;
  543. if (cre_collection[i]['bigy']) bigy = 1;
  544. unsafeWindow.xd = cre_collection[i]['x'];
  545. unsafeWindow.yd = cre_collection[i]['y'];
  546. for (let xz = unsafeWindow.xd - 1; xz <= unsafeWindow.xd + 1 + bigx; xz++) {
  547. for (let yz = unsafeWindow.yd - 1; yz <= unsafeWindow.yd + 1 + bigy; yz++) {
  548. 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)) {
  549. unsafeWindow.defadd -= 4;
  550. unsafeWindow.frig2 = true;
  551. };
  552. };
  553. };
  554. };
  555. if ((attacker > 0) && (cre_collection[defender]['giantslayer']) && (cre_collection[attacker]['big'])) unsafeWindow.defadd += 4;
  556. unsafeWindow.mondef = Math.round((cre_collection[defender]['defence'] + cre_collection[defender]['defenceaddon'] + unsafeWindow.defadd + cre_collection[defender]['ragedefence']) * cre_collection[defender]['defencemodifier']);
  557. if (unsafeWindow.magic[defender]['bsr']) {
  558. unsafeWindow.mondef = 0;
  559. };
  560.  
  561. if ((cre_collection[attacker]['preciseshot']) && (l > 2) && (l <= 9) && (unsafeWindow.rangemod >= 1)) {
  562. unsafeWindow.mondef = 0;
  563. };
  564. if ((cre_collection[attacker]['ignoredefence'])) {
  565. unsafeWindow.mondef *= (1 - cre_collection[attacker]['ignoredefence'] / 100);
  566. };
  567. if (cre_collection[attacker]['crushingleadership']) {
  568. var morale_delta = unsafeWindow.stage.pole.getmorale(attacker) - unsafeWindow.stage.pole.getmorale(defender);
  569. if (morale_delta > 0) {
  570. unsafeWindow.mondef *= Math.max(0, 1 - morale_delta / 10);
  571. };
  572. };
  573. if (cre_collection[attacker]['sacredweapon']) {
  574. var dark_count = get_dark_count(defender);
  575. if (dark_count > 0) {
  576. unsafeWindow.mondef *= Math.max(0, 1 - 0.15 * dark_count);
  577. };
  578. };
  579. if (unsafeWindow.isperk(attacker, _PERK_PIERCING_LUCK)) {
  580. unsafeWindow.mondef *= 1 - Math.max(0, 0.025 * (cre_collection[attacker]['luck'] + cre_collection[attacker]['luckaddon']));
  581. };
  582. if ((cre_collection[defender]['ignoreattack'])) {
  583. unsafeWindow.monatt *= (1 - cre_collection[defender]['ignoreattack'] / 100);
  584. };
  585. if ((cre_collection[attacker]['ridercharge']) && (movelen > 0)) {
  586. unsafeWindow.mondef = unsafeWindow.mondef * (5 - movelen) / 5;
  587. };
  588. if ((cre_collection[attacker]['forcearrow']) && (!cre_collection[defender]['armoured']) && (!cre_collection[defender]['organicarmor']) && (l > 2)) {
  589. unsafeWindow.mondef *= 0.8;
  590. };
  591. if ((cre_collection[attacker]['armorpiercing']) && (!cre_collection[defender]['armoured']) && (!cre_collection[defender]['organicarmor']) && (l > 2)) {
  592. unsafeWindow.mondef *= 0.5;
  593. };
  594. if ((cre_collection[attacker]['jousting']) && (movelen > 0)) {
  595. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + 0.05 * movelen);
  596. };
  597. if (((cre_collection[attacker]['blindingcharge']) || (cre_collection[attacker]['charge'])) && (movelen > 0)) {
  598. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * (1 + 0.1 * movelen);
  599. };
  600. if ((cre_collection[defender]['shieldwall']) && (movelen > 0)) {
  601. unsafeWindow.PhysicalModifiers = unsafeWindow.PhysicalModifiers * Math.max(0.1, 1 - 0.1 * movelen);
  602. };
  603. if ((unsafeWindow.magic[defender]['enc']) && (unsafeWindow.magic[defender]['enc']['effect'] == 1)) {
  604. unsafeWindow.PhysicalModifiers *= 0.5;
  605. };
  606. if ((cre_collection[attacker]['safeposition']) && (movelen == 0)) {
  607. unsafeWindow.PhysicalModifiers *= 1.5;
  608. };
  609. if ((cre_collection[attacker]['agilesteed']) && (movelen > 0)) {
  610. unsafeWindow.PhysicalModifiers *= 1 - 0.05 * movelen;
  611. };
  612. if (unsafeWindow.mondef < 0) {
  613. unsafeWindow.mondef = 0;
  614. };
  615.  
  616. unsafeWindow.air = 0;
  617. unsafeWindow.fire = 0;
  618. unsafeWindow.water = 0;
  619. unsafeWindow.earth = 0;
  620. if ((hera > 0) && (!cre_collection[attacker]['taran'])) {
  621. h = hera;
  622. if (unsafeWindow.magic[h]['_id']) {
  623. unsafeWindow.mondef *= (1 - unsafeWindow.magic[h]['_id']['effect'] / 100);
  624. };
  625. if (unsafeWindow.magic[h]['_aa']) {
  626. unsafeWindow.air = unsafeWindow.magic[h]['_aa']['effect'] / 100;
  627. };
  628. if (unsafeWindow.magic[h]['_af']) {
  629. unsafeWindow.fire = unsafeWindow.magic[h]['_af']['effect'] / 100;
  630. };
  631. if (unsafeWindow.magic[h]['_aw']) {
  632. unsafeWindow.water = unsafeWindow.magic[h]['_aw']['effect'] / 100;
  633. };
  634. if (unsafeWindow.magic[h]['_ae']) {
  635. unsafeWindow.earth = unsafeWindow.magic[h]['_ae']['effect'] / 100;
  636. };
  637. };
  638. if ((cre_collection[defender]['armoured']) || (cre_collection[defender]['organicarmor'])) {
  639. unsafeWindow.mondef = Math.round((cre_collection[defender]['defence'] + cre_collection[defender]['defenceaddon'] + cre_collection[defender]['ragedefence']) * cre_collection[defender]['defencemodifier']);
  640. };
  641. if (unsafeWindow.monatt < 0) {
  642. unsafeWindow.monatt = 0;
  643. };
  644. if (unsafeWindow.monatt > unsafeWindow.mondef) {
  645. unsafeWindow.AttackDefenseModifier = 1 + (unsafeWindow.monatt - unsafeWindow.mondef) * 0.05;
  646. } else {
  647. unsafeWindow.AttackDefenseModifier = 1 / (1 + (unsafeWindow.mondef - unsafeWindow.monatt) * 0.05);
  648. };
  649. if (cre_collection[attacker]['hero']) {
  650. unsafeWindow.AttackDefenseModifier = 1;
  651. };
  652. var _PERK_ATTACK1 = 8;
  653. var _PERK_ATTACK2 = 9;
  654. var _PERK_ATTACK3 = 10;
  655. var _PERK_DEFENSE1 = 19;
  656. var _PERK_DEFENSE2 = 20;
  657. var _PERK_DEFENSE3 = 21;
  658.  
  659. if ((!cre_collection[attacker]['hero'])&& ((cre_collection[attacker].shooter && shootok == 0)||(cre_collection[attacker].shooter!= 1))) {
  660. if (unsafeWindow.isperk(attacker, _PERK_ATTACK3)) {
  661. unsafeWindow.PhysicalModifiers *= 1.3;
  662. } else {
  663. if (unsafeWindow.isperk(attacker, _PERK_ATTACK2)) {
  664. unsafeWindow.PhysicalModifiers *= 1.2;
  665. } else
  666. if (unsafeWindow.isperk(attacker, _PERK_ATTACK1)) unsafeWindow.PhysicalModifiers *= 1.1;
  667. };
  668. if (unsafeWindow.isperk(defender, _PERK_DEFENSE3)) {
  669. unsafeWindow.PhysicalModifiers *= 0.7;
  670. } else {
  671. if (unsafeWindow.isperk(defender, _PERK_DEFENSE2)) {
  672. unsafeWindow.PhysicalModifiers *= 0.8;
  673. } else {
  674. if (unsafeWindow.isperk(defender, _PERK_DEFENSE1)) unsafeWindow.PhysicalModifiers *= 0.9;
  675. };
  676. };
  677. };
  678. if ((cre_collection[attacker]['siegewalls']) && (cre_collection[defender]['stone'])) {
  679. unsafeWindow.PhysicalModifiers *= 10;
  680. };
  681. var _PERK_COLD_STEEL = 14;
  682. var _PERK_FIERY_WRATH = 101;
  683. var _PERK_HELLFIRE_AURA = 123;
  684. var _PERK_RETRIBUTION = 16;
  685.  
  686. if (unsafeWindow.isperk(attacker, _PERK_COLD_STEEL)) unsafeWindow.water = 1 - (1 - unsafeWindow.water) * (0.9);
  687. if (unsafeWindow.isperk(attacker, _PERK_FIERY_WRATH)) unsafeWindow.fire = 1 - (1 - unsafeWindow.fire) * (0.85);
  688. if (unsafeWindow.isperk(attacker, _PERK_HELLFIRE_AURA)) unsafeWindow.fire = 1 - (1 - unsafeWindow.fire) * (0.95);
  689.  
  690. if (unsafeWindow.magic[attacker]['cre']) {
  691. unsafeWindow.air = 1 - (1 - unsafeWindow.air) * (1 - unsafeWindow.magic[attacker]['cre']['effect'] / 100);
  692. };
  693.  
  694. if (unsafeWindow.isperk(attacker, _PERK_RETRIBUTION)) unsafeWindow.PhysicalModifiers *= (1 + Math.min(Math.max(unsafeWindow.stage.pole.getmorale(attacker, x, y), 0), 5) / 20);
  695. 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;
  696. unsafeWindow.PhysicalModifiers *= unsafeWindow.stage.pole.magicmod(attacker, defender, unsafeWindow.fire, unsafeWindow.air, unsafeWindow.water, unsafeWindow.earth, 0.1);
  697. if ((cre_collection[attacker]['bloodfrenzy']) && (unsafeWindow.magic[defender]['fd1'])) {
  698. unsafeWindow.PhysicalModifiers *= 1.3;
  699. };
  700. unsafeWindow.UmelkaModifiers = 1;
  701.  
  702. if ((umelka[cre_collection[attacker]['owner']][0] > 0) && (umelka[cre_collection[defender]['owner']][0] > 0)) {
  703. unsafeWindow.k = umelka[cre_collection[attacker]['owner']][0];
  704. if ((unsafeWindow.k > 0) && (unsafeWindow.k < 11)) {
  705. let j = umelka[cre_collection[defender]['owner']][k];
  706. unsafeWindow.UmelkaModifiers = 1 - j * 0.03;
  707. };
  708. };
  709. unsafeWindow.NumCreatures = cre_collection[attacker]['nownumber'];
  710. let tsc = 0;
  711.  
  712. bigx = cre_collection[defender]['big'];
  713. bigy = cre_collection[defender]['big'];
  714. if (cre_collection[defender]['bigx']) bigx = 1;
  715. if (cre_collection[defender]['bigy']) bigy = 1;
  716. for (var xs = cre_collection[defender]['x'] - 1; xs <= cre_collection[defender]['x'] + 1 + bigx; xs++) {
  717. for (var ys = cre_collection[defender]['y'] - 1; ys <= cre_collection[defender]['y'] + 1 + bigy; ys++) {
  718. 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'])) {
  719. tsc++;
  720. };
  721. };
  722. };
  723.  
  724.  
  725. unsafeWindow.PhysicalModifiers /= (tsc + 1);
  726.  
  727. var minmag = 0;
  728. var maxmag = 0;
  729. if ((inuse == 'lep') && (cre_collection[attacker]['crashingleap'])) {
  730. unsafeWindow.Totalmagicdamage = 0;
  731. cre_collection[defender]['attacked'] = 1;
  732. unsafeWindow.stage.pole.attackmagic(attacker, defender, cre_collection[attacker]['nownumber'] * 4, 'cold', '', 0, 0, 0);
  733. minmag = unsafeWindow.Totalmagicdamage;
  734. unsafeWindow.Totalmagicdamage = 0;
  735. cre_collection[defender]['attacked'] = 1;
  736. unsafeWindow.stage.pole.attackmagic(attacker, defender, cre_collection[attacker]['nownumber'] * 6, 'cold', '', 0, 0, 0);
  737. maxmag = unsafeWindow.Totalmagicdamage;
  738. };
  739.  
  740. 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'];
  741. 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'];
  742. h = hera;
  743. if ((h > 0) && (unsafeWindow.magic[h]) && (unsafeWindow.magic[h]['BLS']) && (unsafeWindow.magic[h]['BLS']['effect'] > 0)) unsafeWindow.mindam = unsafeWindow.maxdam;
  744. if ((h > 0) && (unsafeWindow.magic[h]) && (unsafeWindow.magic[h]['CRS']) && (unsafeWindow.magic[h]['CRS']['effect'] > 0)) unsafeWindow.maxdam = unsafeWindow.mindam;
  745. if ((cre_collection[attacker]['taran']) && (cre_collection[defender]['stone'])) {
  746. h = hera;
  747. unsafeWindow.mindam = Math.floor(Math.pow(cre_collection[h]['maxhealth'], 0.5) * 200 * cre_collection[attacker]['mindam']);
  748. unsafeWindow.maxdam = Math.floor(Math.pow(cre_collection[h]['maxhealth'], 0.5) * 400 * cre_collection[attacker]['maxdam']);
  749. };
  750. if (cre_collection[attacker]['accuracy']) unsafeWindow.mindam = unsafeWindow.maxdam;
  751. unsafeWindow.BaseDamage = unsafeWindow.mindam;
  752. unsafeWindow.PhysicalDamage = unsafeWindow.NumCreatures * unsafeWindow.BaseDamage * unsafeWindow.AttackDefenseModifier * unsafeWindow.PhysicalModifiers * unsafeWindow.UmelkaModifiers + minmag;
  753. unsafeWindow.PhysicalDamage2 = unsafeWindow.NumCreatures * unsafeWindow.maxdam * unsafeWindow.AttackDefenseModifier * unsafeWindow.PhysicalModifiers * unsafeWindow.UmelkaModifiers + maxmag;
  754. if ((cre_collection[attacker]['deathstrike']) && (cre_collection[defender]['maxhealth'] < 400) && (!cre_collection[defender]['stone'])) {
  755. if ((cre_collection[defender]['nownumber'] - 1) * cre_collection[defender]['maxhealth'] + cre_collection[defender]['nowhealth'] > unsafeWindow.PhysicalDamage) {
  756. unsafeWindow.PhysicalDamage += cre_collection[defender]['maxhealth'] - unsafeWindow.PhysicalDamage % cre_collection[defender]['maxhealth'];
  757. };
  758. if ((cre_collection[defender]['nownumber'] - 1) * cre_collection[defender]['maxhealth'] + cre_collection[defender]['nowhealth'] > unsafeWindow.PhysicalDamage2) {
  759. unsafeWindow.PhysicalDamage2 += cre_collection[defender]['maxhealth'] - unsafeWindow.PhysicalDamage2 % cre_collection[defender]['maxhealth'];
  760. };
  761. };
  762.  
  763. if (cre_collection[attacker]['bladeofslaughter']) {
  764. unsafeWindow.PhysicalDamage += Math.min(500, cre_collection[defender]['nownumber'] * 2);
  765. unsafeWindow.PhysicalDamage2 += Math.min(500, cre_collection[defender]['nownumber'] * 2);
  766. };
  767. if (unsafeWindow.magic[attacker]['brk']) {
  768. unsafeWindow.PhysicalDamage *= (1 + unsafeWindow.magic[attacker]['brk']['effect'] * 0.03);
  769. unsafeWindow.PhysicalDamage2 *= (1 + unsafeWindow.magic[attacker]['brk']['effect'] * 0.03);
  770. };
  771. if (unsafeWindow.PhysicalDamage < 1) {
  772. unsafeWindow.PhysicalDamage = 1;
  773. };
  774. if (unsafeWindow.PhysicalDamage2 < 1) {
  775. unsafeWindow.PhysicalDamage2 = 1;
  776. };
  777. if ((cre_collection[attacker]['magicattack']) && (unsafeWindow.l > 2) && (unsafeWindow.stage.pole.issomething(defender, 'dampenmagic'))) unsafeWindow.PhysicalDamage = 0;
  778. if (unsafeWindow.magic[defender]['rag']) {
  779. unsafeWindow.PhysicalDamage = unsafeWindow.stage.pole.ragedamage(defender, unsafeWindow.PhysicalDamage);
  780. unsafeWindow.PhysicalDamage2 = unsafeWindow.stage.pole.ragedamage(defender, unsafeWindow.PhysicalDamage2);
  781. };
  782. if ((cre_collection[attacker]['vorpalsword']) && (cre_collection[defender]['maxhealth'] < 400) && (!cre_collection[defender]['stone'])) {
  783. unsafeWindow.PhysicalDamage += cre_collection[defender]['maxhealth'];
  784. unsafeWindow.PhysicalDamage2 += cre_collection[defender]['maxhealth'];
  785. };
  786.  
  787. unsafeWindow.PhysicalDamage = Math.round(unsafeWindow.PhysicalDamage);
  788. unsafeWindow.PhysicalDamage2 = Math.round(unsafeWindow.PhysicalDamage2);
  789. if (cre_collection[defender]['pleasureinpain']) {
  790. unsafeWindow.PhysicalDamage = Math.round(unsafeWindow.PhysicalDamage * 0.9);
  791. unsafeWindow.PhysicalDamage2 = Math.round(unsafeWindow.PhysicalDamage2 * 0.9);
  792. };
  793. if (cre_collection[defender]['raptureinagony']) {
  794. unsafeWindow.PhysicalDamage = Math.round(unsafeWindow.PhysicalDamage * 0.8);
  795. unsafeWindow.PhysicalDamage2 = Math.round(unsafeWindow.PhysicalDamage2 * 0.8);
  796. };
  797. var totalh = (cre_collection[defender]['nownumber'] - 1) * cre_collection[defender]['maxhealth'] + cre_collection[defender]['nowhealth'];
  798. unsafeWindow.Uronkills = Math.floor(Math.min(unsafeWindow.PhysicalDamage, totalh) / cre_collection[defender]['maxhealth']);
  799. unsafeWindow.Uronkills2 = Math.floor(Math.min(unsafeWindow.PhysicalDamage2, totalh) / cre_collection[defender]['maxhealth']);
  800. var nowhealth = cre_collection[defender]['nowhealth'] - (Math.min(unsafeWindow.PhysicalDamage, totalh) - unsafeWindow.Uronkills * cre_collection[defender]['maxhealth']);
  801. var nowhealth2 = cre_collection[defender]['nowhealth'] - (Math.min(unsafeWindow.PhysicalDamage2, totalh) - unsafeWindow.Uronkills2 * cre_collection[defender]['maxhealth']);
  802. if (nowhealth <= 0) unsafeWindow.Uronkills++;
  803. if (nowhealth2 <= 0) unsafeWindow.Uronkills2++;
  804. unsafeWindow.tUronkills += unsafeWindow.Uronkills;
  805. unsafeWindow.tUronkills2 += unsafeWindow.Uronkills2;
  806. unsafeWindow.tPhysicalDamage += unsafeWindow.PhysicalDamage;
  807. unsafeWindow.tPhysicalDamage2 += unsafeWindow.PhysicalDamage2;
  808. }
  809. function get_dmg_info(attacker_obj_index, defender_obj_index){
  810. let cre_collection = unsafeWindow.stage.pole.obj
  811. let attacker = cre_collection[attacker_obj_index]
  812. let defender = cre_collection[defender_obj_index]
  813. let dmg_dict = attackmonster(attacker_obj_index, attacker.x, attacker.y, defender.x, defender.y, defender_obj_index);
  814. let min_damage = unsafeWindow.PhysicalDamage
  815. let max_damage = unsafeWindow.PhysicalDamage2
  816. let min_killed, max_killed;
  817. if (min_damage%defender.maxhealth>defender.nowhealth) min_killed = Math.floor(min_damage/defender.maxhealth) + 1
  818. else min_killed = Math.floor(min_damage/defender.maxhealth)
  819. if (max_damage%defender.maxhealth>defender.nowhealth) max_killed = Math.floor(max_damage/defender.maxhealth) + 1
  820. else max_killed = Math.floor(max_damage/defender.maxhealth)
  821. return {min: min_damage, max: max_damage, min_killed: min_killed, max_killed: max_killed}
  822.  
  823. }
  824.  
  825. let defender_obj_id = 0
  826. let selected_id = 0
  827. function refresh(){
  828. isOpen = true
  829. let cre_collection = unsafeWindow.stage.pole.obj
  830. battleHelper_display(battleHelper_on)
  831. set_Display([select, side_button, collapse_button, document.querySelector("#chosen_cre_heading"), dmg_list_container, individual_calc], "inline")
  832. refresh_button.innerHTML = "Обновить"
  833. let cre_list = Object.values(cre_collection);
  834. cre_list.sort(function(a, b) {
  835. return a.obj_index - b.obj_index;
  836. });
  837. dmg_list_container.innerHTML = "";
  838. [...select.children].forEach(child=>child.remove())
  839. let found_defender = false
  840. cre_list.forEach(defender => {
  841. if (![0,-1].includes(defender.nownumber) && defender.nametxt!="" && defender.side == chosen.side && defender.hero == undefined){
  842. let option_id = `cre_no${cre_list.indexOf(defender)}`
  843. select.insertAdjacentHTML("beforeend", `<option id = "${option_id}" value = "${defender.obj_index}">${defender.nametxt} [${defender.nownumber}] </option>`)
  844. if (!found_defender) {
  845. if (`${defender.obj_index}` == chosen.creature) found_defender = true
  846. defender_obj_id = defender.obj_index
  847. selected_id = [...select.children].indexOf(select.lastChild)
  848. }
  849. }
  850. })
  851. dmg_list_container.insertAdjacentHTML("beforeend", `<div id = "chosen_cre_heading" style="display:inline;">
  852. <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>
  853. </div>`)
  854. cre_list.forEach(attacker => {
  855. if (attacker.side == -chosen.side && attacker.nownumber != 0 && attacker.nametxt != "") {
  856. let dmg = get_dmg_info(attacker.obj_index, defender_obj_id)
  857. let practical_overall_hp;
  858. if (cre_list[defender_obj_id-1].attack>attacker.defence){
  859. practical_overall_hp = attacker.maxhealth*attacker.nownumber/(1+0.05*Math.abs(cre_list[defender_obj_id-1].attack-attacker.defence))
  860. }
  861. else {
  862. practical_overall_hp = attacker.maxhealth*attacker.nownumber*(1+0.05*Math.abs(cre_list[defender_obj_id-1].attack-attacker.defence))
  863. }
  864. let row_id = `row_no${cre_list.indexOf(attacker)}`
  865. let koef_string = `(коэф. урона <b>${( ((dmg.max + dmg.min) / 2) / practical_overall_hp ).toFixed(2)}</b>)`
  866. 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>`)
  867. }
  868. })
  869. select.options.item(selected_id).selected = true
  870. }