HWHExtension

Extension for HeroWarsHelper script

安装此脚本
作者推荐脚本

您可能也喜欢HeroWarsHelper

安装此脚本
  1. // ==UserScript==
  2. // @name HWHExtension
  3. // @name:en HWHExtension
  4. // @name:ru HWHExtension
  5. // @namespace HWHExtension
  6. // @version 1.0.1
  7. // @description Extension for HeroWarsHelper script
  8. // @description:en Extension for HeroWarsHelper script
  9. // @description:ru Расширение для скрипта HeroWarsHelper
  10. // @author ZingerY
  11. // @license Copyright ZingerY
  12. // @homepage https://zingery.ru/scripts/HWHExtension.user.js
  13. // @icon https://zingery.ru/scripts/VaultBoyIco16.ico
  14. // @icon64 https://zingery.ru/scripts/VaultBoyIco64.png
  15. // @match https://www.hero-wars.com/*
  16. // @match https://apps-1701433570146040.apps.fbsbx.com/*
  17. // @run-at document-start
  18. // ==/UserScript==
  19.  
  20. (function () {
  21.  
  22. if (!this.HWHClasses) {
  23. console.log('%cObject for extension not found', 'color: red');
  24. return;
  25. }
  26.  
  27. console.log('%cStart Extension ' + GM_info.script.name + ', v' + GM_info.script.version + ' by ' + GM_info.script.author, 'color: red');
  28. const { addExtentionName } = HWHFuncs;
  29. addExtentionName(GM_info.script.name, GM_info.script.version, GM_info.script.author);
  30.  
  31. const {
  32. getInput,
  33. setProgress,
  34. hideProgress,
  35. I18N,
  36. send,
  37. getTimer,
  38. countdownTimer,
  39. getUserInfo,
  40. getSaveVal,
  41. setSaveVal,
  42. popup,
  43. setIsCancalBattle,
  44. random,
  45. } = HWHFuncs;
  46.  
  47. function executeDungeon(resolve, reject) {
  48. let countPredictionCard = 0;
  49. let dungeonActivity = 0;
  50. let startDungeonActivity = 0;
  51. let maxDungeonActivity = 150;
  52. let limitDungeonActivity = 30180;
  53. let countShowStats = 1;
  54. //let fastMode = isChecked('fastMode');
  55. let end = false;
  56.  
  57. let countTeam = [];
  58. let timeDungeon = {
  59. all: new Date().getTime(),
  60. findAttack: 0,
  61. attackNeutral: 0,
  62. attackEarthOrFire: 0,
  63. };
  64.  
  65. let titansStates = {};
  66. let bestBattle = {};
  67.  
  68. let teams = {
  69. neutral: [],
  70. water: [],
  71. earth: [],
  72. fire: [],
  73. hero: [],
  74. };
  75.  
  76. //тест
  77. let talentMsg = '';
  78. let talentMsgReward = '';
  79.  
  80. let callsExecuteDungeon = {
  81. calls: [
  82. {
  83. name: 'dungeonGetInfo',
  84. args: {},
  85. ident: 'dungeonGetInfo',
  86. },
  87. {
  88. name: 'teamGetAll',
  89. args: {},
  90. ident: 'teamGetAll',
  91. },
  92. {
  93. name: 'teamGetFavor',
  94. args: {},
  95. ident: 'teamGetFavor',
  96. },
  97. {
  98. name: 'clanGetInfo',
  99. args: {},
  100. ident: 'clanGetInfo',
  101. },
  102. {
  103. name: 'inventoryGet',
  104. args: {},
  105. ident: 'inventoryGet',
  106. },
  107. ],
  108. };
  109.  
  110. this.start = async function (titanit) {
  111. //maxDungeonActivity = titanit > limitDungeonActivity ? limitDungeonActivity : titanit;
  112. maxDungeonActivity = titanit || getInput('countTitanit');
  113. send(JSON.stringify(callsExecuteDungeon), startDungeon);
  114. };
  115.  
  116. /** Получаем данные по подземелью */
  117. function startDungeon(e) {
  118. stopDung = false; // стоп подземка
  119. let res = e.results;
  120. let dungeonGetInfo = res[0].result.response;
  121. if (!dungeonGetInfo) {
  122. endDungeon('noDungeon', res);
  123. return;
  124. }
  125. console.log('Начинаем копать на фулл: ', new Date());
  126. let teamGetAll = res[1].result.response;
  127. let teamGetFavor = res[2].result.response;
  128. dungeonActivity = res[3].result.response.stat.todayDungeonActivity;
  129. startDungeonActivity = res[3].result.response.stat.todayDungeonActivity;
  130. countPredictionCard = res[4].result.response.consumable[81];
  131. titansStates = dungeonGetInfo.states.titans;
  132.  
  133. teams.hero = {
  134. favor: teamGetFavor.dungeon_hero,
  135. heroes: teamGetAll.dungeon_hero.filter((id) => id < 6000),
  136. teamNum: 0,
  137. };
  138. let heroPet = teamGetAll.dungeon_hero.filter((id) => id >= 6000).pop();
  139. if (heroPet) {
  140. teams.hero.pet = heroPet;
  141. }
  142. teams.neutral = getTitanTeam('neutral');
  143. teams.water = {
  144. favor: {},
  145. heroes: getTitanTeam('water'),
  146. teamNum: 0,
  147. };
  148. teams.earth = {
  149. favor: {},
  150. heroes: getTitanTeam('earth'),
  151. teamNum: 0,
  152. };
  153. teams.fire = {
  154. favor: {},
  155. heroes: getTitanTeam('fire'),
  156. teamNum: 0,
  157. };
  158.  
  159. checkFloor(dungeonGetInfo);
  160. }
  161.  
  162. function getTitanTeam(type) {
  163. switch (type) {
  164. case 'neutral':
  165. return [4023, 4022, 4012, 4021, 4011, 4010, 4020];
  166. case 'water':
  167. return [4000, 4001, 4002, 4003].filter((e) => !titansStates[e]?.isDead);
  168. case 'earth':
  169. return [4020, 4022, 4021, 4023].filter((e) => !titansStates[e]?.isDead);
  170. case 'fire':
  171. return [4010, 4011, 4012, 4013].filter((e) => !titansStates[e]?.isDead);
  172. }
  173. }
  174.  
  175. /** Создать копию объекта */
  176. function clone(a) {
  177. return JSON.parse(JSON.stringify(a));
  178. }
  179.  
  180. /** Находит стихию на этаже */
  181. function findElement(floor, element) {
  182. for (let i in floor) {
  183. if (floor[i].attackerType === element) {
  184. return i;
  185. }
  186. }
  187. return undefined;
  188. }
  189.  
  190. /** Проверяем этаж */
  191. async function checkFloor(dungeonInfo) {
  192. if (!('floor' in dungeonInfo) || dungeonInfo.floor?.state == 2) {
  193. saveProgress();
  194. return;
  195. }
  196. checkTalent(dungeonInfo);
  197. // console.log(dungeonInfo, dungeonActivity);
  198. maxDungeonActivity = getInput('countTitanit');
  199. setProgress(`${I18N('DUNGEON')}: ${I18N('TITANIT')} ${dungeonActivity}/${maxDungeonActivity} ${talentMsg}`);
  200. //setProgress('Dungeon: Титанит ' + dungeonActivity + '/' + maxDungeonActivity);
  201. if (dungeonActivity >= maxDungeonActivity) {
  202. endDungeon('Стоп подземка,', 'набрано титанита: ' + dungeonActivity + '/' + maxDungeonActivity);
  203. return;
  204. }
  205. let activity = dungeonActivity - startDungeonActivity;
  206. titansStates = dungeonInfo.states.titans;
  207. if (stopDung) {
  208. endDungeon('Стоп подземка,', 'набрано титанита: ' + dungeonActivity + '/' + maxDungeonActivity);
  209. return;
  210. }
  211. /*if (activity / 1000 > countShowStats) {
  212. countShowStats++;
  213. showStats();
  214. }*/
  215. bestBattle = {};
  216. let floorChoices = dungeonInfo.floor.userData;
  217. if (floorChoices.length > 1) {
  218. for (let element in teams) {
  219. let teamNum = findElement(floorChoices, element);
  220. if (!!teamNum) {
  221. if (element == 'earth') {
  222. teamNum = await chooseEarthOrFire(floorChoices);
  223. if (teamNum < 0) {
  224. endDungeon('Невозможно победить без потери Титана!', dungeonInfo);
  225. return;
  226. }
  227. }
  228. chooseElement(floorChoices[teamNum].attackerType, teamNum);
  229. return;
  230. }
  231. }
  232. } else {
  233. chooseElement(floorChoices[0].attackerType, 0);
  234. }
  235. }
  236. //тест черепахи
  237. async function checkTalent(dungeonInfo) {
  238. const talent = dungeonInfo.talent;
  239. if (!talent) {
  240. return;
  241. }
  242. const dungeonFloor = +dungeonInfo.floorNumber;
  243. const talentFloor = +talent.floorRandValue;
  244. let doorsAmount = 3 - talent.conditions.doorsAmount;
  245.  
  246. if (dungeonFloor === talentFloor && (!doorsAmount || !talent.conditions?.farmedDoors[dungeonFloor])) {
  247. const reward = await Send({
  248. calls: [
  249. { name: 'heroTalent_getReward', args: { talentType: 'tmntDungeonTalent', reroll: false }, ident: 'group_0_body' },
  250. { name: 'heroTalent_farmReward', args: { talentType: 'tmntDungeonTalent' }, ident: 'group_1_body' },
  251. ],
  252. }).then((e) => e.results[0].result.response);
  253. const type = Object.keys(reward).pop();
  254. const itemId = Object.keys(reward[type]).pop();
  255. const count = reward[type][itemId];
  256. const itemName = cheats.translate(`LIB_${type.toUpperCase()}_NAME_${itemId}`);
  257. talentMsgReward += `<br> ${count} ${itemName}`;
  258. doorsAmount++;
  259. }
  260. talentMsg = `<br>TMNT Talent: ${doorsAmount}/3 ${talentMsgReward}<br>`;
  261. }
  262.  
  263. /** Выбираем огнем или землей атаковать */
  264. async function chooseEarthOrFire(floorChoices) {
  265. bestBattle.recovery = -11;
  266. let selectedTeamNum = -1;
  267. for (let attempt = 0; selectedTeamNum < 0 && attempt < 4; attempt++) {
  268. for (let teamNum in floorChoices) {
  269. let attackerType = floorChoices[teamNum].attackerType;
  270. selectedTeamNum = await attemptAttackEarthOrFire(teamNum, attackerType, attempt);
  271. }
  272. }
  273. console.log('Выбор команды огня или земли: ', selectedTeamNum < 0 ? 'не сделан' : floorChoices[selectedTeamNum].attackerType);
  274. return selectedTeamNum;
  275. }
  276.  
  277. /** Попытка атаки землей и огнем */
  278. async function attemptAttackEarthOrFire(teamNum, attackerType, attempt) {
  279. let start = new Date();
  280. let team = clone(teams[attackerType]);
  281. let startIndex = team.heroes.length + attempt - 4;
  282. if (startIndex >= 0) {
  283. team.heroes = team.heroes.slice(startIndex);
  284. let recovery = await getBestRecovery(teamNum, attackerType, team, 25);
  285. if (recovery > bestBattle.recovery) {
  286. bestBattle.recovery = recovery;
  287. bestBattle.selectedTeamNum = teamNum;
  288. bestBattle.team = team;
  289. }
  290. }
  291. let workTime = new Date().getTime() - start.getTime();
  292. timeDungeon.attackEarthOrFire += workTime;
  293. if (bestBattle.recovery < -10) {
  294. return -1;
  295. }
  296. return bestBattle.selectedTeamNum;
  297. }
  298.  
  299. /** Выбираем стихию для атаки */
  300. async function chooseElement(attackerType, teamNum) {
  301. let result;
  302. switch (attackerType) {
  303. case 'hero':
  304. case 'water':
  305. result = await startBattle(teamNum, attackerType, teams[attackerType]);
  306. break;
  307. case 'earth':
  308. case 'fire':
  309. result = await attackEarthOrFire(teamNum, attackerType);
  310. break;
  311. case 'neutral':
  312. result = await attackNeutral(teamNum, attackerType);
  313. }
  314. if (!!result && attackerType != 'hero') {
  315. let recovery = (!!!bestBattle.recovery ? 10 * getRecovery(result) : bestBattle.recovery) * 100;
  316. let titans = result.progress[0].attackers.heroes;
  317. console.log('Проведен бой: ' + attackerType + ', recovery = ' + (recovery > 0 ? '+' : '') + Math.round(recovery) + '% \r\n', titans);
  318. }
  319. endBattle(result);
  320. }
  321.  
  322. /** Атакуем Землей или Огнем */
  323. async function attackEarthOrFire(teamNum, attackerType) {
  324. if (!!!bestBattle.recovery) {
  325. bestBattle.recovery = -11;
  326. let selectedTeamNum = -1;
  327. for (let attempt = 0; selectedTeamNum < 0 && attempt < 4; attempt++) {
  328. selectedTeamNum = await attemptAttackEarthOrFire(teamNum, attackerType, attempt);
  329. }
  330. if (selectedTeamNum < 0) {
  331. endDungeon('Невозможно победить без потери Титана!', attackerType);
  332. return;
  333. }
  334. }
  335. return findAttack(teamNum, attackerType, bestBattle.team);
  336. }
  337.  
  338. /** Находим подходящий результат для атаки */
  339. async function findAttack(teamNum, attackerType, team) {
  340. let start = new Date();
  341. let recovery = -1000;
  342. let iterations = 0;
  343. let result;
  344. let correction = 0.01;
  345. for (let needRecovery = bestBattle.recovery; recovery < needRecovery; needRecovery -= correction, iterations++) {
  346. result = await startBattle(teamNum, attackerType, team);
  347. recovery = getRecovery(result);
  348. }
  349. bestBattle.recovery = recovery;
  350. let workTime = new Date().getTime() - start.getTime();
  351. timeDungeon.findAttack += workTime;
  352. return result;
  353. }
  354.  
  355. /** Атакуем Нейтральной командой */
  356. async function attackNeutral(teamNum, attackerType) {
  357. let start = new Date();
  358. let factors = calcFactor();
  359. bestBattle.recovery = -0.2;
  360. await findBestBattleNeutral(teamNum, attackerType, factors, true);
  361. if (bestBattle.recovery < 0 || (bestBattle.recovery < 0.2 && factors[0].value < 0.5)) {
  362. let recovery = 100 * bestBattle.recovery;
  363. console.log(
  364. 'Не удалось найти удачный бой в быстром режиме: ' +
  365. attackerType +
  366. ', recovery = ' +
  367. (recovery > 0 ? '+' : '') +
  368. Math.round(recovery) +
  369. '% \r\n',
  370. bestBattle.attackers
  371. );
  372. await findBestBattleNeutral(teamNum, attackerType, factors, false);
  373. }
  374. let workTime = new Date().getTime() - start.getTime();
  375. timeDungeon.attackNeutral += workTime;
  376. if (!!bestBattle.attackers) {
  377. let team = getTeam(bestBattle.attackers);
  378. return findAttack(teamNum, attackerType, team);
  379. }
  380. endDungeon('Не удалось найти удачный бой!', attackerType);
  381. return undefined;
  382. }
  383.  
  384. /** Находит лучшую нейтральную команду */
  385. async function findBestBattleNeutral(teamNum, attackerType, factors, mode) {
  386. let countFactors = factors.length < 4 ? factors.length : 4;
  387. let aradgi = !titansStates['4013']?.isDead;
  388. let edem = !titansStates['4023']?.isDead;
  389. let dark = [4032, 4033].filter((e) => !titansStates[e]?.isDead);
  390. let light = [4042].filter((e) => !titansStates[e]?.isDead);
  391. let actions = [];
  392. if (mode) {
  393. for (let i = 0; i < countFactors; i++) {
  394. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(factors[i].id)));
  395. }
  396. if (countFactors > 1) {
  397. let firstId = factors[0].id;
  398. let secondId = factors[1].id;
  399. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4001, secondId)));
  400. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4002, secondId)));
  401. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4003, secondId)));
  402. }
  403. if (aradgi) {
  404. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(4013)));
  405. if (countFactors > 0) {
  406. let firstId = factors[0].id;
  407. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4000, 4013)));
  408. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4001, 4013)));
  409. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4002, 4013)));
  410. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4003, 4013)));
  411. }
  412. if (edem) {
  413. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(4023, 4000, 4013)));
  414. }
  415. }
  416. } else {
  417. if (mode) {
  418. for (let i = 0; i < factors.length; i++) {
  419. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(factors[i].id)));
  420. }
  421. } else {
  422. countFactors = factors.length < 2 ? factors.length : 2;
  423. }
  424. for (let i = 0; i < countFactors; i++) {
  425. let mainId = factors[i].id;
  426. if (aradgi && (mode || i > 0)) {
  427. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4000, 4013)));
  428. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4001, 4013)));
  429. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4002, 4013)));
  430. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4003, 4013)));
  431. }
  432. for (let i = 0; i < dark.length; i++) {
  433. let darkId = dark[i];
  434. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4001, darkId)));
  435. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4002, darkId)));
  436. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4003, darkId)));
  437. }
  438. for (let i = 0; i < light.length; i++) {
  439. let lightId = light[i];
  440. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4001, lightId)));
  441. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4002, lightId)));
  442. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4003, lightId)));
  443. }
  444. let isFull = mode || i > 0;
  445. for (let j = isFull ? i + 1 : 2; j < factors.length; j++) {
  446. let extraId = factors[j].id;
  447. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4000, extraId)));
  448. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4001, extraId)));
  449. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(mainId, 4002, extraId)));
  450. }
  451. }
  452. if (aradgi) {
  453. if (mode) {
  454. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(4013)));
  455. }
  456. for (let i = 0; i < dark.length; i++) {
  457. let darkId = dark[i];
  458. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(darkId, 4001, 4013)));
  459. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(darkId, 4002, 4013)));
  460. }
  461. for (let i = 0; i < light.length; i++) {
  462. let lightId = light[i];
  463. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(lightId, 4001, 4013)));
  464. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(lightId, 4002, 4013)));
  465. }
  466. }
  467. for (let i = 0; i < dark.length; i++) {
  468. let firstId = dark[i];
  469. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId)));
  470. for (let j = i + 1; j < dark.length; j++) {
  471. let secondId = dark[j];
  472. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4001, secondId)));
  473. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4002, secondId)));
  474. }
  475. }
  476. for (let i = 0; i < light.length; i++) {
  477. let firstId = light[i];
  478. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId)));
  479. for (let j = i + 1; j < light.length; j++) {
  480. let secondId = light[j];
  481. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4001, secondId)));
  482. actions.push(startBattle(teamNum, attackerType, getNeutralTeam(firstId, 4002, secondId)));
  483. }
  484. }
  485. }
  486. for (let result of await Promise.all(actions)) {
  487. let recovery = getRecovery(result);
  488. if (recovery > bestBattle.recovery) {
  489. bestBattle.recovery = recovery;
  490. bestBattle.attackers = result.progress[0].attackers.heroes;
  491. }
  492. }
  493. }
  494.  
  495. /** Получаем нейтральную команду */
  496. function getNeutralTeam(id, swapId, addId) {
  497. let neutralTeam = clone(teams.water);
  498. let neutral = neutralTeam.heroes;
  499. if (neutral.length == 4) {
  500. if (!!swapId) {
  501. for (let i in neutral) {
  502. if (neutral[i] == swapId) {
  503. neutral[i] = addId;
  504. }
  505. }
  506. }
  507. } else if (!!addId) {
  508. neutral.push(addId);
  509. }
  510. neutral.push(id);
  511. return neutralTeam;
  512. }
  513.  
  514. /** Получить команду титанов */
  515. function getTeam(titans) {
  516. return {
  517. favor: {},
  518. heroes: Object.keys(titans).map((id) => parseInt(id)),
  519. teamNum: 0,
  520. };
  521. }
  522.  
  523. /** Вычисляем фактор боеготовности титанов */
  524. function calcFactor() {
  525. let neutral = teams.neutral;
  526. let factors = [];
  527. for (let i in neutral) {
  528. let titanId = neutral[i];
  529. let titan = titansStates[titanId];
  530. let factor = !!titan ? titan.hp / titan.maxHp + titan.energy / 10000.0 : 1;
  531. if (factor > 0) {
  532. factors.push({ id: titanId, value: factor });
  533. }
  534. }
  535. factors.sort(function (a, b) {
  536. return a.value - b.value;
  537. });
  538. return factors;
  539. }
  540.  
  541. /** Возвращает наилучший результат из нескольких боев */
  542. async function getBestRecovery(teamNum, attackerType, team, countBattle) {
  543. let bestRecovery = -1000;
  544. let actions = [];
  545. for (let i = 0; i < countBattle; i++) {
  546. actions.push(startBattle(teamNum, attackerType, team));
  547. }
  548. for (let result of await Promise.all(actions)) {
  549. let recovery = getRecovery(result);
  550. if (recovery > bestRecovery) {
  551. bestRecovery = recovery;
  552. }
  553. }
  554. return bestRecovery;
  555. }
  556.  
  557. /** Возвращает разницу в здоровье атакующей команды после и до битвы и проверяет здоровье титанов на необходимый минимум*/
  558. function getRecovery(result) {
  559. if (result.result.stars < 3) {
  560. return -100;
  561. }
  562. let beforeSumFactor = 0;
  563. let afterSumFactor = 0;
  564. let beforeTitans = result.battleData.attackers;
  565. let afterTitans = result.progress[0].attackers.heroes;
  566. for (let i in afterTitans) {
  567. let titan = afterTitans[i];
  568. let percentHP = titan.hp / beforeTitans[i].hp;
  569. let energy = titan.energy;
  570. let factor = checkTitan(i, energy, percentHP) ? getFactor(i, energy, percentHP) : -100;
  571. afterSumFactor += factor;
  572. }
  573. for (let i in beforeTitans) {
  574. let titan = beforeTitans[i];
  575. let state = titan.state;
  576. beforeSumFactor += !!state ? getFactor(i, state.energy, state.hp / titan.hp) : 1;
  577. }
  578. return afterSumFactor - beforeSumFactor;
  579. }
  580.  
  581. /** Возвращает состояние титана*/
  582. function getFactor(id, energy, percentHP) {
  583. let elemantId = id.slice(2, 3);
  584. let isEarthOrFire = elemantId == '1' || elemantId == '2';
  585. let energyBonus = id == '4020' && energy == 1000 ? 0.1 : energy / 20000.0;
  586. let factor = percentHP + energyBonus;
  587. return isEarthOrFire ? factor : factor / 10;
  588. }
  589.  
  590. /** Проверяет состояние титана*/
  591. function checkTitan(id, energy, percentHP) {
  592. switch (id) {
  593. case '4020':
  594. return percentHP > 0.25 || (energy == 1000 && percentHP > 0.05);
  595. break;
  596. case '4010':
  597. return percentHP + energy / 2000.0 > 0.63;
  598. break;
  599. case '4000':
  600. return percentHP > 0.62 || (energy < 1000 && ((percentHP > 0.45 && energy >= 400) || (percentHP > 0.3 && energy >= 670)));
  601. }
  602. return true;
  603. }
  604.  
  605. /** Начинаем бой */
  606. function startBattle(teamNum, attackerType, args) {
  607. return new Promise(function (resolve, reject) {
  608. args.teamNum = teamNum;
  609. let startBattleCall = {
  610. calls: [
  611. {
  612. name: 'dungeonStartBattle',
  613. args,
  614. ident: 'body',
  615. },
  616. ],
  617. };
  618. send(JSON.stringify(startBattleCall), resultBattle, {
  619. resolve,
  620. teamNum,
  621. attackerType,
  622. });
  623. });
  624. }
  625.  
  626. /** Возращает результат боя в промис */
  627. /*function resultBattle(resultBattles, args) {
  628. if (!!resultBattles && !!resultBattles.results) {
  629. let battleData = resultBattles.results[0].result.response;
  630. let battleType = "get_tower";
  631. if (battleData.type == "dungeon_titan") {
  632. battleType = "get_titan";
  633. }
  634. battleData.progress = [{ attackers: { input: ["auto", 0, 0, "auto", 0, 0] } }];//тест подземка правки
  635. BattleCalc(battleData, battleType, function (result) {
  636. result.teamNum = args.teamNum;
  637. result.attackerType = args.attackerType;
  638. args.resolve(result);
  639. });
  640. } else {
  641. endDungeon('Потеряна связь с сервером игры!', 'break');
  642. }
  643. }*/
  644. function resultBattle(resultBattles, args) {
  645. battleData = resultBattles.results[0].result.response;
  646. battleType = 'get_tower';
  647. if (battleData.type == 'dungeon_titan') {
  648. battleType = 'get_titan';
  649. }
  650. battleData.progress = [{ attackers: { input: ['auto', 0, 0, 'auto', 0, 0] } }];
  651. BattleCalc(battleData, battleType, function (result) {
  652. result.teamNum = args.teamNum;
  653. result.attackerType = args.attackerType;
  654. args.resolve(result);
  655. });
  656. }
  657.  
  658. /** Заканчиваем бой */
  659.  
  660. ////
  661. async function endBattle(battleInfo) {
  662. if (!!battleInfo) {
  663. const args = {
  664. result: battleInfo.result,
  665. progress: battleInfo.progress,
  666. };
  667. if (battleInfo.result.stars < 3) {
  668. endDungeon('Герой или Титан мог погибнуть в бою!', battleInfo);
  669. return;
  670. }
  671. if (countPredictionCard > 0) {
  672. args.isRaid = true;
  673. countPredictionCard--;
  674. } else {
  675. const timer = getTimer(battleInfo.battleTime);
  676. console.log(timer);
  677. await countdownTimer(timer, `${I18N('DUNGEON')}: ${I18N('TITANIT')} ${dungeonActivity}/${maxDungeonActivity} ${talentMsg}`);
  678. }
  679. const calls = [
  680. {
  681. name: 'dungeonEndBattle',
  682. args,
  683. ident: 'body',
  684. },
  685. ];
  686. lastDungeonBattleData = null;
  687. send(JSON.stringify({ calls }), resultEndBattle);
  688. } else {
  689. endDungeon('dungeonEndBattle win: false\n', battleInfo);
  690. }
  691. }
  692. /** Получаем и обрабатываем результаты боя */
  693. function resultEndBattle(e) {
  694. if (!!e && !!e.results) {
  695. let battleResult = e.results[0].result.response;
  696. if ('error' in battleResult) {
  697. endDungeon('errorBattleResult', battleResult);
  698. return;
  699. }
  700. let dungeonGetInfo = battleResult.dungeon ?? battleResult;
  701. dungeonActivity += battleResult.reward.dungeonActivity ?? 0;
  702. checkFloor(dungeonGetInfo);
  703. } else {
  704. endDungeon('Потеряна связь с сервером игры!', 'break');
  705. }
  706. }
  707.  
  708. /** Добавить команду титанов в общий список команд */
  709. function addTeam(team) {
  710. for (let i in countTeam) {
  711. if (equalsTeam(countTeam[i].team, team)) {
  712. countTeam[i].count++;
  713. return;
  714. }
  715. }
  716. countTeam.push({ team: team, count: 1 });
  717. }
  718.  
  719. /** Сравнить команды на равенство */
  720. function equalsTeam(team1, team2) {
  721. if (team1.length == team2.length) {
  722. for (let i in team1) {
  723. if (team1[i] != team2[i]) {
  724. return false;
  725. }
  726. }
  727. return true;
  728. }
  729. return false;
  730. }
  731.  
  732. function saveProgress() {
  733. let saveProgressCall = {
  734. calls: [
  735. {
  736. name: 'dungeonSaveProgress',
  737. args: {},
  738. ident: 'body',
  739. },
  740. ],
  741. };
  742. send(JSON.stringify(saveProgressCall), resultEndBattle);
  743. }
  744.  
  745. /** Выводит статистику прохождения подземелья */
  746. function showStats() {
  747. let activity = dungeonActivity - startDungeonActivity;
  748. let workTime = clone(timeDungeon);
  749. workTime.all = new Date().getTime() - workTime.all;
  750. for (let i in workTime) {
  751. workTime[i] = Math.round(workTime[i] / 1000);
  752. }
  753. countTeam.sort(function (a, b) {
  754. return b.count - a.count;
  755. });
  756. console.log(titansStates);
  757. console.log('Собрано титанита: ', activity);
  758. console.log('Скорость сбора: ' + Math.round((3600 * activity) / workTime.all) + ' титанита/час');
  759. console.log('Время раскопок: ');
  760. for (let i in workTime) {
  761. let timeNow = workTime[i];
  762. console.log(
  763. i + ': ',
  764. Math.round(timeNow / 3600) + ' ч. ' + Math.round((timeNow % 3600) / 60) + ' мин. ' + (timeNow % 60) + ' сек.'
  765. );
  766. }
  767. console.log('Частота использования команд: ');
  768. for (let i in countTeam) {
  769. let teams = countTeam[i];
  770. console.log(teams.team + ': ', teams.count);
  771. }
  772. }
  773.  
  774. /** Заканчиваем копать подземелье */
  775. function endDungeon(reason, info) {
  776. if (!end) {
  777. end = true;
  778. console.log(reason, info);
  779. showStats();
  780. if (info == 'break') {
  781. setProgress(
  782. 'Dungeon stoped: Титанит ' + dungeonActivity + '/' + maxDungeonActivity + '\r\nПотеряна связь с сервером игры!',
  783. false,
  784. hideProgress
  785. );
  786. } else {
  787. setProgress('Dungeon completed: Титанит ' + dungeonActivity + '/' + maxDungeonActivity, false, hideProgress);
  788. }
  789. setTimeout(cheats.refreshGame, 1000);
  790. resolve();
  791. }
  792. }
  793. }
  794.  
  795. this.HWHClasses.executeDungeon = executeDungeon;
  796.  
  797. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址