// ==UserScript== // @name HWHNewCharacterExt // @name:en HWHNewCharacterExt // @name:ru HWHNewCharacterExt // @namespace HWHNewCharacterExt // @version 2.16 // @description Extension for HeroWarsHelper script // @description:en Extension for HeroWarsHelper script // @description:ru Расширение для скрипта HeroWarsHelper // @author ZingerY, Green // @license Copyright Green // @icon https://i.ibb.co/xtmhK7zS/icon.png // @match https://www.hero-wars.com/* // @match https://apps-1701433570146040.apps.fbsbx.com/* // @run-at document-start // @downloadURL none // ==/UserScript== (function () { if (!this.HWHClasses) { console.log('%cObject for extension not found', 'color: red'); return; } console.log('%cStart Extension ' + GM_info.script.name + ', v' + GM_info.script.version + ' by ' + GM_info.script.author, 'color: red'); const { addExtentionName } = HWHFuncs; addExtentionName(GM_info.script.name, GM_info.script.version, GM_info.script.author); const { popup, confShow, setProgress, I18N, countdownTimer } = HWHFuncs; const { i18nLangData } = HWHData; const { WinFixBattle } = HWHClasses; const i18nLangDataEn = { NEW_CHARACTER: 'New Character', NEW_CHARACTER_TITLE: 'Complete quests for a new hero or titan', NEW_CHARACTER_NO_EVENT: 'The event is not active', NEW_CHARACTER_SOMETHING_WENT_WRONG: ' Something went wrong
Please try again', NEW_CHARACTER_SELECT_ACTION: 'Select an action', NT_TITAN_EVENT: ' The Titan Awakens
', NT_COLLECT_TITANS: 'Сollect the Titans', NT_COLLECT_TITANS_TITLE: 'Сollecting the Titans of the maximum rank by purchasing fragments in the store', NT_COLLECT_HEROES: 'Сollect the Heroes', NT_COLLECT_HEROES_TITLE: 'Сollecting the Heroes of the maximum rank by purchasing fragments in the store', NT_COLLECT_TOTEM_SKILLS: 'Сollect totem skills', NT_COLLECT_TOTEM_SKILLS_TITLE: 'Get the influence skill of the maximum rank by purchasing fragments in the store', NT_COLLECT_TITANS_PROGRESS: ' {counter} titans left to collect', NT_TITANS_COLLECTED: 'All titans have been collected', NT_TOTEM_SKILLS_COLLECTED: 'All influence skills have been collected', NT_TITANS_AND_TOTEM_SKILLS_COLLECTED: 'Titans and Totem influence skills have been collected', NT_COLLECT_TOTEM_SKILLS_PROGRESS: ' {counter} influence skills left to collect
Collecting...', NT_CHAPTER_NOT_AVAILABLE: ' Chapter unavailable
Complete the previous chapter', NT_COLLECT_HEROES_PROGRESS: ' {counter} heroes left to collect
Collecting...', NT_HEROES_COLLECTED: 'All heroes have been collected', NT_COLLECT_EVERYTHING: 'Collect everything', NT_COLLECT_EVERYTHING_TITLE: 'Collect heroes, titans, totems, pets', NT_BOSS_WAS_KILLED: 'The Chapter {chapterNumber} boss didn\'t appreciate our health-conscious approach... to his health.', NT_BOSS_WAS_KILLED_SET_PROGRESS_1: 'All done. Boss defeated. Collecting trophies...', NT_BOSS_WAS_KILLED_SET_PROGRESS_2: '
Oh no, our loot is too much for this humble bag\'s capacity.', NT_BOSS_WAS_KILLED_SET_PROGRESS_3: '
Urgently calling the porters guild.', NT_BOSS_WAS_KILLED_SET_PROGRESS_4: '
All of it!', NT_BOSS_WAS_KILLED_SET_PROGRESS_5: '
Stand by. Arrival in approximately seconds ', NT_BOSS_WAS_NOT_KILLED: 'The Chapter {chapterNumber} boss was not killed
Reload the game and try to kill the boss yourself', NT_COMPLETE_CHAPTER: 'Complete the chapter', NT_COMPLETE_CHAPTER_TITLE: 'Complete an available chapter', NT_ALL_CHAPTERS_COMPLETED: 'All chapters completed', NT_NOT_ENOUGH_BUFF: `Not enough buff to complete Chapter {chapterNumber} You have: {buffAmount}
You need: {invasionBuff} `, NT_ENTER_TITAN_IDS: `Chapter {chapterNumber} is available for completion
Enter 5 titan IDs separated by commas or dashes`, NT_ENTER_HERO_IDS: `Chapter {chapterNumber} is available for completion
Enter 5 hero IDs separated by commas or dashes`, NT_MUST_FIVE_TITANS: 'There must be 5 titans', NT_MUST_FIVE_HEROES: 'There must be 5 heroes', NT_MUST_ONLY_NUMBERS: 'The list must contain only numbers and commas', NT_LETS_START: 'Let\'s start...', NT_OUTDATED_VERSION_OF_SCRIPT: ` Outdated version of HeroWarsHelper
Please update the script`, NT_MISSION_PROGRESS: 'Taking out {missionNumber} enemy team', NT_MISSION_PROGRESS_BOSS: 'Let\'s wipe the boss as a team!', NT_GET_TITAN_IDS: 'Titan IDs', NT_GET_TITAN_IDS_TITLE: 'Get a list of titan IDs', NT_WATER_TITANS: 'Water Titans', NT_EARTH_TITANS: 'Earth Titans', NT_FIRE_TITANS: 'Fire Titans', NT_LIGHT_TITANS: 'Light Titans', NT_DARK_TITANS: 'Dark Titans', NHR_NOTHING_HERE: 'There\'s nothing here yet. Please wait.', NHR_HERO_EVENT: 'Rise of a New Hero
', NHR_COMPLETE_TASKS: 'Complete the tasks', NHR_COMPLETE_TASKS_TITLE: 'Complete event tasks: collect heroes, buy pets, spend coins', NHR_TASKS_COMPLETED: 'The tasks have been completed', NHR_LIVES_ARE_OVER: 'Failed to complete chapter {chapterNumber} . Lives are over. Try again', NHR_SHOPPING: 'Make purchases...', NHR_NOTHING_HERE_1: 'What\'s this? Where is it? When? Booooooooooosss...', NHR_NOTHING_HERE_2: 'Nobody\'s heeere! ', NHR_NOTHING_HERE_3: 'And nobody here either.', NHR_NOTHING_HERE_4: 'If he\'s not there, then what\'s supposed to be here?', NHR_COMPLETE_CHAPTER_N1: 'Raid for Chapter I', NHR_COMPLETE_CHAPTER_N1_TITLE: 'Complete chapter I one time', NHR_COMPLETE_CHAPTER_N1_COMPLETED: 'Chapter I raid completed', NHR_CHAPTER_N1_RAID: 'Starting {raidNumber} raid of first chapter', NHR_MAKE_OTHER_TASKS: '
Moving on to other quests', NHR_GET_HERO_IDS: 'Hero IDs', NHR_GET_HERO_IDS_TITLE: 'Get a list of hero IDs', NHR_GET_HERO_IDS_MESSAGE: 'ID - Name', NHR_SPEND_VALOR_COINS: 'Spend Valor Coins', NHR_SPEND_VALOR_COINS_TITLE: 'Spend all available Valor Coins', NHR_NOT_ENOUGH_COINS: 'Not enough coins
No money, no honey ', NHR_SPEND_VALOR_COINS_RESULT: `Valor Coin Exchange Result:

Sapphire Medallion: {sapphireMedallion}
Soul stones: {fragmentHero}`, NHR_SPEND_VALOR_COINS_MESSAGE: 'Exchange all available Coins of Valor?', NHR_APPLY: 'Exchange', NHR_NOT_APPLY: 'Thanks, but no thanks. Real Heroes don\'t need help!', }; i18nLangData['en'] = Object.assign(i18nLangData['en'], i18nLangDataEn); const i18nLangDataRu = { NEW_CHARACTER: 'Новый персонаж', NEW_CHARACTER_TITLE: 'Выполнять задания для нового героя или титана', NEW_CHARACTER_NO_EVENT: 'Ивент не активен', NEW_CHARACTER_SOMETHING_WENT_WRONG: ' Что-то пошло не так
Попробуйте заново', NEW_CHARACTER_SELECT_ACTION: 'Выберите действие', NT_TITAN_EVENT: ' Пробуждение Титана
', NT_COLLECT_TITANS: 'Собрать титанов', NT_COLLECT_TITANS_TITLE: 'Собрать титанов максимального ранга, покупая фрагменты в магазине', NT_COLLECT_HEROES: 'Собрать героев', NT_COLLECT_HEROES_TITLE: 'Собрать героев максимального ранга, покупая фрагменты в магазине', NT_COLLECT_TOTEM_SKILLS: 'Собрать тотемы', NT_COLLECT_TOTEM_SKILLS_TITLE: 'Собрать навыки тотемов максимального ранга, покупая фрагменты в магазине', NT_COLLECT_TITANS_PROGRESS: 'Осталось собрать титанов: {counter} шт.', NT_TITANS_COLLECTED: 'Титаны собраны', NT_TOTEM_SKILLS_COLLECTED: 'Все навыки влияния собраны', NT_TITANS_AND_TOTEM_SKILLS_COLLECTED: 'Титаны и навыки влияния тотемов собраны', NT_COLLECT_TOTEM_SKILLS_PROGRESS: 'Осталось собрать навыков тотемов: {counter} шт.
Собираем...', NT_CHAPTER_NOT_AVAILABLE: ' Глава не доступна
Завершите предыдущую главу', NT_COLLECT_HEROES_PROGRESS: 'Осталось собрать героев: {counter} шт.
Собираем...', NT_HEROES_COLLECTED: 'Все герои собраны', NT_COLLECT_EVERYTHING: 'Собрать все', NT_COLLECT_EVERYTHING_TITLE: 'Собрать героев, титанов, тотемы, питомцев', NT_BOSS_WAS_KILLED: 'Босс {chapterNumber} главы не пережил нашего искреннего интереса к его здоровью', NT_BOSS_WAS_KILLED_SET_PROGRESS_1: 'Готовенько. Босс повержен. Собираем трофеи...', NT_BOSS_WAS_KILLED_SET_PROGRESS_2: '
О нет, размеры добычи превосходят скромные возможности этого мешка.', NT_BOSS_WAS_KILLED_SET_PROGRESS_3: '
Срочно вызываем гильдию носильщиков!', NT_BOSS_WAS_KILLED_SET_PROGRESS_4: '
Всю!', NT_BOSS_WAS_KILLED_SET_PROGRESS_5: '
Ожидайте. Прибытие, примерно секунд через ', NT_BOSS_WAS_NOT_KILLED: 'Босса {chapterNumber} главы не убили
Перезагрузите игру, и попробуйте убить босса самостоятельно', NT_COMPLETE_CHAPTER: 'Пройти главу', NT_COMPLETE_CHAPTER_TITLE: 'Пройти доступную главу', NT_ALL_CHAPTERS_COMPLETED: 'Все главы пройдены', NT_NOT_ENOUGH_BUFF: `Недостаточно усиления для прохождения {chapterNumber} главы
У вас: {buffAmount}
Необходимо: {invasionBuff} `, NT_ENTER_TITAN_IDS: `Для прохождения доступна {chapterNumber} глава
Введите 5 id титанов через запятые или дефисы`, NT_ENTER_HERO_IDS: `Для прохождения доступна {chapterNumber} глава
Введите 5 id героев через запятые или дефисы`, NT_MUST_FIVE_TITANS:'Должно быть 5 титанов', NT_MUST_FIVE_HEROES:'Должно быть 5 героев', NT_MUST_ONLY_NUMBERS: 'Список должен содержать только цифры и запятые', NT_LETS_START: 'Начинаем начинать...', NT_OUTDATED_VERSION_OF_SCRIPT: ` Устаревшая версия HeroWarsHelper
Пожалуйста, обновите скрипт`, NT_MISSION_PROGRESS: 'Сносим {missionNumber} команду противника', NT_MISSION_PROGRESS_BOSS: 'Пакуем босса всем коллективом!', NT_GET_TITAN_IDS: 'Id титанов', NT_GET_TITAN_IDS_TITLE: 'Получить список Id титанов', NT_WATER_TITANS: 'Титаны Воды', NT_EARTH_TITANS: 'Титаны Земли', NT_FIRE_TITANS: 'Титаны Огня', NT_LIGHT_TITANS: 'Титаны Света', NT_DARK_TITANS: 'Титаны Тьмы', NHR_NOTHING_HERE: 'Здесь пока ничего нет. Ожидайте', NHR_HERO_EVENT: 'Восхождение Нового Героя
', NHR_COMPLETE_TASKS: 'Выполнить задания', NHR_COMPLETE_TASKS_TITLE: 'Выполнить задания ивента: собрать героев, купить питомцев, потратить монеты', NHR_TASKS_COMPLETED: 'Задания выполнены', NHR_LIVES_ARE_OVER: `Дорогой дневник, мне не подобрать слов, чтобы описать боль и унижение, которые были получены при походе на босса {chapterNumber} главы. Наши богатыри были втянуты в яростный бой, точнее не бой, а именно пиздилку, мочилово, где всё равнялось, даже морды с асфальтом. И после нескольких дней этого хаоса и резни наступил бесславный и постыдный конец нашему походу.

Конец. Конец. Концы в воду! Давай по новой!`, NHR_SHOPPING: 'Шопимся, шопимся, шопимся...', NHR_NOTHING_HERE_1: 'А чё это? А где? А когда? Хазяяяяяяяииинн...', NHR_NOTHING_HERE_2: 'Здеся никого нет!', NHR_NOTHING_HERE_3: 'И здесь тоже нет.', NHR_NOTHING_HERE_4: 'Если там нет, то чё здесь должно быть?', NHR_COMPLETE_CHAPTER_N1: 'Рейд I главы', NHR_COMPLETE_CHAPTER_N1_TITLE: 'Пройти I главу 1 раз', NHR_COMPLETE_CHAPTER_N1_COMPLETED: 'Рейд I главы выполнен', NHR_CHAPTER_N1_RAID: 'Выполняем {raidNumber} рейд первой главы', NHR_MAKE_OTHER_TASKS: '
Приступаем к выполнению других заданий', NHR_GET_HERO_IDS: 'Id героев', NHR_GET_HERO_IDS_TITLE: 'Получить список Id героев', NHR_GET_HERO_IDS_MESSAGE: 'ID - Имя', NHR_SPEND_VALOR_COINS: 'Потратить монеты доблести', NHR_SPEND_VALOR_COINS_TITLE: 'Потратить все имеющиеся монеты доблести', NHR_NOT_ENOUGH_COINS: 'Нэт Монэт
Ноу мани - ноу хани', NHR_SPEND_VALOR_COINS_RESULT: `Результат обмена монет доблести:

3 магнитoфoна, 3 кинoкамеры заграничных, 3 пoртсигара отечественных, куртка замшевая - три куртки, сапфировый медальон - {sapphireMedallion}, камни души - {fragmentHero}`, NHR_SPEND_VALOR_COINS_MESSAGE: 'Потратить все имеющиеся монеты доблести?', NHR_APPLY: 'Потратить', NHR_NOT_APPLY: 'Спасибо, не надо. Настоящим Героям помощь не нужна!', }; i18nLangData['ru'] = Object.assign(i18nLangData['ru'], i18nLangDataRu); const romanNumerals = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X']; /////////////////////////////////////////////////////////////////////////////////////////////// // Добавление кнопоки в окно Разное const { othersPopupButtons } = HWHData; othersPopupButtons.push({ get msg() { return I18N('NEW_CHARACTER'); }, get title() { return I18N('NEW_CHARACTER_TITLE'); }, result: async function () { if (compareVersions(scriptInfo.version, '2.390') < 0) { confShow(`${I18N('NT_OUTDATED_VERSION_OF_SCRIPT')}`); return; } console.log(scriptInfo.version); let invasionInfo = await Caller.send('invasion_getInfo'); //if (true) { if (invasionInfo) { let invasionInfoId = invasionInfo.id; let chapters = Object.values(lib.data.invasion.chapter).filter((e) => e.invasionId === invasionInfoId); //const startDate = new Date("2025-11-14 14:00:00".replace(' ', 'T') + 'Z'); const startDate = new Date((chapters[0].startDate).replace(' ', 'T') + 'Z'); const todayDate = Date.now(); console.log(startDate); console.log(todayDate); if (todayDate < startDate) { confShow(`${I18N('NEW_CHARACTER_NO_EVENT')}`); return; } let titanIvent = false; for (let chapter of chapters) { if (chapter.settings.unitType === 'titan') { titanIvent = true; break; } } if (titanIvent) { //if (true) { await onClickNewTitanButton(); } else { await onClickNewHeroButton(); } } else { confShow(`${I18N('NEW_CHARACTER_NO_EVENT')}`); } }, color: 'pink', }); async function onClickNewHeroButton() { const popupButtons = [ { get msg() { return I18N('NHR_COMPLETE_TASKS'); }, get title() { return I18N('NHR_COMPLETE_TASKS_TITLE'); }, result: async function () { //confShow(I18N('NHR_NOTHING_HERE')); //Получить список героев, которых нужно собрать let heroIdsToBuy = await getHeroIdsToBuy(); //let heroIdsToBuy = [60] if (heroIdsToBuy.length != 0) { let spendCoins = true; await collectHeroes(spendCoins); setProgress(`${I18N('NT_HEROES_COLLECTED')} ${I18N('NHR_MAKE_OTHER_TASKS')}`, false); await new Promise((e) => setTimeout(e, 2000)); for (let i = 1; i <= 4; i++) { setProgress(I18N('NHR_CHAPTER_N1_RAID', {raidNumber:i}), false); await new Promise((e) => setTimeout(e, 2000)); await firstHeroicChapterRaid(); } } setProgress('', true); confShow(I18N('NHR_TASKS_COMPLETED')); }, color: 'green', }, { get msg() { return I18N('NT_COMPLETE_CHAPTER'); }, get title() { return I18N('NT_COMPLETE_CHAPTER_TITLE'); }, result: async function () { //confShow(I18N('NHR_NOTHING_HERE')); await completeChapter(); }, color: 'blue', }, { get msg() { return I18N('NHR_COMPLETE_CHAPTER_N1'); }, get title() { return I18N('NHR_COMPLETE_CHAPTER_N1_TITLE'); }, result: async function () { await firstHeroicChapterRaid(); setProgress('', true); confShow(I18N('NHR_COMPLETE_CHAPTER_N1_COMPLETED')); }, color: 'pink', }, { get msg() { return I18N('NHR_GET_HERO_IDS'); }, get title() { return I18N('NHR_GET_HERO_IDS_TITLE'); }, result: function () { getAllHeroIDs(); }, color: 'pink', }, { get msg() { return I18N('NHR_SPEND_VALOR_COINS'); }, get title() { return I18N('NHR_SPEND_VALOR_COINS_TITLE'); }, result: async function () { await spendValorCoins(); }, color: 'pink', }, ]; popupButtons.push({ result: false, isClose: true }); const answer = await popup.confirm(I18N('NHR_HERO_EVENT'), popupButtons); if (typeof answer === 'function') { answer(); } } async function onClickNewTitanButton() { const popupButtons = [ { get msg() { return I18N('NT_COLLECT_TITANS'); }, get title() { return I18N('NT_COLLECT_TITANS_TITLE'); }, result: async function () { confShow(I18N('NHR_NOTHING_HERE_1')); //await collectTitansAndTotemFragments(); }, color: 'green', }, { get msg() { return I18N('NT_COLLECT_HEROES'); }, get title() { return I18N('NT_COLLECT_HEROES_TITLE'); }, result: async function () { confShow(I18N('NHR_NOTHING_HERE_2')); /*let farmedChapters = await Caller.send('invasion_getInfo').then((e) => e.farmedChapters); if (farmedChapters.length >= 1) { await collectHeroes(); } else { confShow(`${I18N('NT_CHAPTER_NOT_AVAILABLE')}`); }*/ }, color: 'green', }, { get msg() { return I18N('NHR_COMPLETE_TASKS'); }, get title() { return I18N('NHR_COMPLETE_TASKS_TITLE'); }, result: async function () { confShow(I18N('NHR_NOTHING_HERE_3')); /* await collectTitansAndTotemFragments(); await new Promise((e) => setTimeout(e, 3000)); let farmedChapters = await Caller.send('invasion_getInfo').then((e) => e.farmedChapters); if (farmedChapters.length == 0) { await firstTitanChapterRaid(); await new Promise((e) => setTimeout(e, 3000)); } await collectHeroes(); */ }, color: 'green', }, { get msg() { return I18N('NT_COMPLETE_CHAPTER'); }, get title() { return I18N('NT_COMPLETE_CHAPTER_TITLE'); }, result: async function () { confShow(I18N('NHR_NOTHING_HERE_4')); //await completeChapter(); }, color: 'blue', }, { get msg() { return I18N('NHR_GET_HERO_IDS'); }, get title() { return I18N('NHR_GET_HERO_IDS_TITLE'); }, result: function () { getAllHeroIDs(); }, color: 'pink', }, { get msg() { return I18N('NT_GET_TITAN_IDS'); }, get title() { return I18N('NT_GET_TITAN_IDS_TITLE'); }, result: function () { getAllTitanIDs(); }, color: 'pink', }, { get msg() { return I18N('NHR_SPEND_VALOR_COINS'); }, get title() { return I18N('NHR_SPEND_VALOR_COINS_TITLE'); }, result: async function () { await spendValorCoins(); }, color: 'pink', }, ]; popupButtons.push({ result: false, isClose: true }); const answer = await popup.confirm(I18N('NT_TITAN_EVENT'), popupButtons); if (typeof answer === 'function') { answer(); } } //**************************************************************************************************** //**************************************************************************************************** //**************************************************************************************************** //**************************************************************************************************** async function firstHeroicChapterRaid() { let spendCoins = true; let missionRaid = true; await completeChapter(spendCoins, missionRaid); } async function firstTitanChapterRaid() { let spendCoins = false; let missionRaid = true; await completeChapter(spendCoins, missionRaid); } async function completeChapter(spendCoins = false, missionRaid = false) { //Получить состояние на карте let invasionInfo = await Caller.send('invasion_getInfo'); let invasionInfoId = invasionInfo.id; let farmedChapters = invasionInfo.farmedChapters; let buffAmount = invasionInfo.buffAmount; console.log('invasionInfoId ' + invasionInfoId); console.log('farmedChapters ', JSON.stringify(farmedChapters)); console.log('buffAmount ' + buffAmount); //Получить id главы для атаки let chapters = Object.values(lib.data.invasion.chapter).filter((e) => e.invasionId === invasionInfoId); console.log(chapters); let chapterId = 0; let invasionBuff = 0; let titanOrHero = ''; let chapterNumber = 0; if (missionRaid == false) { if (chapters.length == farmedChapters.length) { confShow(I18N('NT_ALL_CHAPTERS_COMPLETED')); } for (let chapter of chapters) { if (!farmedChapters.includes(chapter.id)) { chapterId = chapter.id; if (chapter.requirements?.invasionBuff) { invasionBuff = chapter.requirements.invasionBuff; } titanOrHero = chapter.settings.unitType; chapterNumber = chapters.indexOf(chapter)+1; break; } } } //Рейд первой мисси if (missionRaid == true) { chapterId = chapters[0].id; titanOrHero = chapters[0].settings.unitType; chapterNumber = 1; } console.log('chapterId ' + chapterId); console.log('invasionBuff ' + invasionBuff); console.log('titanOrHero ' + titanOrHero); console.log('chapterNumber ' + chapterNumber); if (buffAmount < invasionBuff) { confShow(I18N('NT_NOT_ENOUGH_BUFF', { chapterNumber: romanNumerals[chapterNumber], buffAmount, invasionBuff})); return; } if (titanOrHero === 'hero' ) { await completeHeroesChapter(chapters, chapterId, chapterNumber, spendCoins, missionRaid); } if (titanOrHero === 'titan' ) { await completeTitansChapter(chapters, chapterId, chapterNumber, missionRaid); } } async function completeHeroesChapter(chapters, chapterId, chapterNumber, spendCoins = false, missionRaid = false) { /*Питомцы 6000 - Фенрис //6005 - Альбрус 6001 - Оливер //6006 - Аксель 6002 - Мерлин //6007 - Бисквит 6003 - Мара //6008 - Хорус 6004 - Каин //6009 - Векс*/ //Атакующие герои: Галахад, Тристан, Лирия, Кира, Себастьян. //let heroAttackingTeams = {heroes: [2, 54, 67, 3, 48], pets: [6005,6000,6001,6006]}; //Атакующие герои: Электра, Каскад + Тея, Криста + Ларс. //let heroAttackingTeams = {heroes: [70, 69, 7, 33, 34], pets: [6005, 6001, 6002, 6003, 6006]}; //Атакующие герои: Электра + Орион, Каскад, Криста + Ларс. //let heroAttackingTeams = {heroes: [70, 13, 69, 33, 34], pets: [6005, 6001, 6002, 6003, 6006]}; //Атакующие герои: Электра, Каскад, Криста + Ларс, Хайди. let heroAttackingTeams = {heroes: [70, 69, 33, 34, 9], pets: [6005, 6001, 6002, 6003, 6006]}; //Атакующие герои: Электра, Каскад, Айрис, Хайди, Дориан. //let heroAttackingTeams = {heroes: [70, 69, 55, 9, 29], pets: [6005, 6001, 6002, 6003, 6006]}; let titanOrHero = 'hero'; let heroIds = heroAttackingTeams.heroes; if (missionRaid == false) { //Кнопка ввод Id героев, что необходимо собрать console.log("chapterNumber chapterNumber" + chapterNumber); heroIds = await getTeamButton(heroAttackingTeams.heroes, chapterNumber, titanOrHero); console.log('heroIds ', JSON.stringify(heroIds)); if (!heroIds) { return; } } setProgress(I18N('NT_LETS_START'), false); await new Promise((e) => setTimeout(e, 3000)); //Активировать главу let chapterInfo = await Caller.send({ name: 'invasion_setActiveChapter', args: { chapterId: chapterId } }); let haveHeroFragments = chapterInfo.invasion.fragments; console.log('haveHeroFragments ', JSON.stringify(haveHeroFragments)); //Получить id магазина let shopId = await getShopId(chapters, titanOrHero); //1078; // Магазин титанов console.log('Id магазина ' + shopId); //Id миссии let firstMissionId = chapterInfo.invasion.actions[0].payload.id; let missionId = firstMissionId; //Жизни let lives = chapterInfo.invasion.lives; console.log('firstMissionId ' + firstMissionId); console.log('missionId ' + missionId); console.log('lives ' + lives); //Фрагменты героев let heroFragments = [0, 0, 0, 0, 0]; for (let i = 0; i < 5; i++) { if (haveHeroFragments[heroIds[i]]) { heroFragments[i] = haveHeroFragments[heroIds[i]]; } } console.log('shopId ' + shopId); console.log(heroIds); console.log('heroFragments ', JSON.stringify(heroFragments)); //Питомцы, что необходимо купить let pets = heroAttackingTeams.pets; while (lives > 0 && missionId <= firstMissionId + 7) { //Купить героев setProgress(I18N('NHR_SHOPPING'), false); let result = await buyHeroesAndPets(shopId, heroIds, heroFragments, pets, spendCoins); //Текущая миссия босс или нет let boss = false; //Произвести атаку босса if (missionId == firstMissionId + 7) { if (missionRaid == true) { return; } boss = true; } //Получить атакующую команду let heroes = []; let havePets = []; let pet; let allHeroes = []; let petsFavor = {}; await getAttackingTeam(heroes, havePets, allHeroes); const haveAllAttackingTeams = (arr, values) => { return values.every(v => arr.includes(v)); }; if (haveAllAttackingTeams(allHeroes, heroIds)) { heroes = heroIds; } console.log('allHeroes ', JSON.stringify(allHeroes)); console.log('heroes ', JSON.stringify(heroes)); if (havePets.length > 0) { //Основной питомец первый в списке питомцев let mainPet = heroAttackingTeams.pets[0]; if (havePets.includes(mainPet)) { pet = mainPet; } else { pet = havePets[0]; } //Покровительство const petLib = lib.getData('pet'); for (let heroId of heroes) { /** Поиск питомца для героя */ for (let petId of havePets) { if (petLib[petId].favorHeroes.includes(heroId)) { petsFavor[heroId] = petId; havePets = havePets.filter((e) => e != petId); break; }; } } } //Проходим миссию if (!boss) { setProgress(I18N('NT_MISSION_PROGRESS', {missionNumber: 1 + missionId - firstMissionId}), false); } else { setProgress(I18N('NT_MISSION_PROGRESS_BOSS'), false); } await new Promise((e) => setTimeout(e, 2000)); await attackHeroMission(missionId, chapterId, heroes, pet, boss, petsFavor); //Результат атаки let invasionInfo = await Caller.send('invasion_getInfo'); let missions = Object.values(invasionInfo.actions); for (let mission of missions) { if (mission.payload.wins == 0) { missionId = mission.payload.id; break; } } //Результат атаки босса if (boss) { if (invasionInfo.farmedChapters.includes(chapterId)) { confShow(I18N('NT_BOSS_WAS_KILLED', { chapterNumber: romanNumerals[chapterNumber]})); } else { confShow(I18N('NT_BOSS_WAS_NOT_KILLED', { chapterNumber: romanNumerals[chapterNumber]})); } return; } lives = invasionInfo.lives; console.log('missionId ' + missionId); console.log('lives ' + lives); } if (lives == 0) { setProgress('', true); confShow(I18N('NHR_LIVES_ARE_OVER', { chapterNumber: romanNumerals[chapterNumber]})); return; } } async function completeTitansChapter(chapters, chapterId, chapterNumber, missionRaid = false) { //Атакующие титаны: Ияри, Солярис, Молох, Игнис, Араджи /*Навыки тотемов: elemental primal 4500 - Последний Всполох 4506 - Пульс Древних 4502 - Ледниковый Период 4507 - Первородное Рвение 4503 - Гнев Недр 4508 - Эгида Эха 4509 - Танец Пламени 4514 - Тройной Круговорот 4510 - Шепот Глубин 4515 - Зов Стихий 4511 - Гул Скал */ const elementalSkils = [4500,4502,4503,4509,4510,4511]; const primalSkils = [4506,4507,4508,4514,4515]; let titanAttackingTeams = {heroes: [4042, 4043, 4010, 4012, 4013], titanSkilsIds: [4500, 4507]}; let titanOrHero = 'titan'; let titanIds = titanAttackingTeams.heroes; if (missionRaid == false) { //Id титанов, что необходимо собрать titanIds = await getTeamButton(titanAttackingTeams.heroes, chapterNumber, titanOrHero); console.log('titanIds ', JSON.stringify(titanIds)); if (!titanIds) { return; } } setProgress(I18N('NT_LETS_START'), false); await new Promise((e) => setTimeout(e, 3000)); //Активировать главу let chapterInfo = await Caller.send({ name: 'invasion_setActiveChapter', args: { chapterId: chapterId } }); let haveTitanFragments = chapterInfo.invasion.fragments; console.log('haveTitanFragments ', JSON.stringify(haveTitanFragments)); //Получить id магазина let shopId = await getShopId(chapters, titanOrHero); //1073; // Магазин титанов console.log('Id магазина ' + shopId); //Id миссии let firstMissionId = chapterInfo.invasion.actions[0].payload.id; let missionId = firstMissionId; //Жизни let lives = chapterInfo.invasion.lives; console.log('firstMissionId ' + firstMissionId); console.log('missionId ' + missionId); console.log('lives ' + lives); //Фрагменты титанов let titanFragments = [0, 0, 0, 0, 0]; for (let i = 0; i < 5; i++) { if (haveTitanFragments[titanIds[i]]) { titanFragments[i] = haveTitanFragments[titanIds[i]]; } } console.log('shopId ' + shopId); console.log(titanIds); console.log('titanFragments ', JSON.stringify(titanFragments)); //Навыки тотемов, что необходимо собрать let titanSkilsIds = titanAttackingTeams.titanSkilsIds; //Фрагменты навыков тотемов let titanSkilFragments = []; for (let i = 0; i < titanSkilsIds.length; i++){ titanSkilFragments.push(0); } while (lives > 0 && missionId <= firstMissionId + 7) { setProgress(I18N('NHR_SHOPPING'), false); //Купить титанов и фрагменты тотемов let result = await buyTitansAndTotemSkils(shopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments); //Текущая миссия босс или нет let boss = false; //Произвести атаку босса if (missionId == firstMissionId + 7) { boss = true; } //Получить атакующую команду let heroes = []; let titanSkil = []; let allHeroes = []; await getAttackingTeam(heroes, titanSkil, allHeroes); console.log('heroes ', JSON.stringify(heroes)); let spiritSkills = new Array(); if (titanSkil.length > 0) { for (let ts of titanSkil) { if (elementalSkils.includes(ts)) { spiritSkills.push(['elemental', ts]); } if (primalSkils.includes(ts)) { spiritSkills.push(['primalSkils', ts]); } } } let firstSpiritSkills = Object.fromEntries(spiritSkills); //Проходим миссию if (!boss) { setProgress(I18N('NT_MISSION_PROGRESS', {missionNumber: 1 + missionId - firstMissionId}), false); } else { setProgress(I18N('NT_MISSION_PROGRESS_BOSS'), false); } await new Promise((e) => setTimeout(e, 2000)); await attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills, boss); //Результат атаки let invasionInfo = await Caller.send('invasion_getInfo'); let missions = Object.values(invasionInfo.actions); for (let mission of missions) { if (mission.payload.wins == 0) { missionId = mission.payload.id; break; } } //Результат атаки босса if (boss) { if (invasionInfo.farmedChapters.includes(chapterId)) { confShow(I18N('NT_BOSS_WAS_KILLED', { chapterNumber: romanNumerals[chapterNumber]})); } else { confShow(I18N('NT_BOSS_WAS_NOT_KILLED', { chapterNumber: romanNumerals[chapterNumber]})); } return; } lives = invasionInfo.lives; console.log('missionId ' + missionId); console.log('lives ' + lives); } if (lives == 0) { setProgress('', true); confShow(I18N('NHR_LIVES_ARE_OVER', { chapterNumber: romanNumerals[chapterNumber]})); return; } } async function collectTitansAndTotemFragments() { //Получить состояние на карте let invasionInfo = await Caller.send('invasion_getInfo'); let invasionInfoId = invasionInfo.id; let farmedChapters = invasionInfo.farmedChapters; console.log('invasionInfoId ' + invasionInfoId); console.log('farmedChapters ', JSON.stringify(farmedChapters)); //Получить id первой главый let chapters = Object.values(lib.data.invasion.chapter).filter((e) => e.invasionId === invasionInfoId); let chapterId = getChapterId(chapters, 'titan'); console.log('chapterId ' + chapterId); let cycle = true; while (cycle) { //Титаны, что необходимо собрать let titanIdsToBuy = await getTitanIdsToBuy(); //Навыки тотемов, что необходимо собрать let titanSkilsIds = await getTitanSkillIdsToBuy(); if (titanIdsToBuy.length == 0 && titanSkilsIds.length == 0) { setProgress('', true); confShow(I18N('NT_TITANS_AND_TOTEM_SKILLS_COLLECTED')); cycle = false; return; } setProgress( I18N('NT_COLLECT_TITANS_PROGRESS', { counter: titanIdsToBuy.length }) + '
' + I18N('NT_COLLECT_TOTEM_SKILLS_PROGRESS', { counter: titanSkilsIds.length }), false ); //Активировать главу let chapterInfo = await Caller.send({ name: 'invasion_setActiveChapter', args: { chapterId: chapterId } }); let haveTitanFragments = chapterInfo.invasion.fragments; //Получить id магазина let shopId = await getShopId(chapters, 'titan'); //1073; // Магазин титанов console.log('Id магазина титанов ' + shopId); //Id миссии let firstMissionId = chapterInfo.invasion.actions[0].payload.id; let missionId = firstMissionId; //Жизни let lives = chapterInfo.invasion.lives; console.log('firstMissionId ' + firstMissionId); console.log('missionId ' + missionId); console.log('lives ' + lives); //Id титанов, что необходимо собрать let titanIds = [0, 0]; //Резервные титаны, для добавления в покупки: Солярис, Ияри let reserveTitans = [4043, 4042]; if (titanIdsToBuy.length >= 2) { titanIds = [titanIdsToBuy[0], titanIdsToBuy[1]]; } if (titanIdsToBuy.length == 1) { if (reserveTitans.includes(titanIdsToBuy[0])) { titanIds = reserveTitans; } else { titanIds[0] = titanIdsToBuy[0]; titanIds[1] = reserveTitans[0]; } } if (titanIdsToBuy.length == 0) { titanIds = reserveTitans; } //Фрагменты титанов let titanFragments = [0, 0]; for (let i = 0; i < titanFragments.length; i++){ if (haveTitanFragments[titanIds[i]]) { titanFragments[i] = haveTitanFragments[titanIds[i]]; } } //Фрагменты навыков тотемов let titanSkilFragments = [0, 0]; if (titanSkilsIds.length <= 1) { titanSkilFragments = [0]; } console.log('shopId ' + shopId); console.log(titanIds); console.log(titanFragments); while (lives > 0 && missionId <= firstMissionId + 7) { setProgress(I18N('NHR_SHOPPING'), false); //Купить титанов и фрагменты тотемов let result = await buyTitansAndTotemSkils(shopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments); //Выйти, если босс побежден и полностью собрали титанов и тотемы. if (result && farmedChapters.includes(chapterId)) { break; } //Текущая миссия босс или нет let boss = false; //Произвести атаку босса, если его ни разу не убили if (!farmedChapters.includes(chapterId)) { if (missionId == firstMissionId + 7) { boss = true; console.log('%cАтакуем босса ', 'color: green; font-weight: bold;'); } } else { //Не атаковать босса, если его уже убили if (missionId == firstMissionId + 7) { break; } } //Получить атакующую команду let heroes = []; let titanSkil = []; let allHeroes = []; await getAttackingTeam(heroes, titanSkil, allHeroes); let firstSpiritSkills = {}; //Проходим миссию if (!boss) { setProgress(I18N('NT_MISSION_PROGRESS', {missionNumber: 1 + missionId - firstMissionId}), false); } else { setProgress(I18N('NT_MISSION_PROGRESS_BOSS'), false); } await new Promise((e) => setTimeout(e, 2000)); await attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills, boss); //Убили / не убили босса, вышли с "while" if (boss == true) { break; } //Результат атаки let invasionInfo = await Caller.send('invasion_getInfo'); farmedChapters = invasionInfo.farmedChapters; let missions = Object.values(invasionInfo.actions); for (let mission of missions) { if (mission.payload.wins == 0) { missionId = mission.payload.id; break; } } lives = invasionInfo.lives; console.log('missionId ' + missionId); console.log('lives ' + lives); } } } async function collectHeroes(spendCoins = false) { //Получить состояние на карте let invasionInfo = await Caller.send('invasion_getInfo'); let invasionInfoId = invasionInfo.id; let farmedChapters = invasionInfo.farmedChapters; console.log('invasionInfoId ' + invasionInfoId); console.log('farmedChapters ', JSON.stringify(farmedChapters)); //Получить id главы let chapters = Object.values(lib.data.invasion.chapter).filter((e) => e.invasionId === invasionInfoId); let chapterId = getChapterId(chapters, 'hero'); console.log('chapterId ' + chapterId); //Питомцы, что необходимо купить let pets = [6008, 6005];// [6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6009]; let cycle = true; while (cycle) { //Получить героев, которых нужно собрать let heroIdsToBuy = await getHeroIdsToBuy(); if (heroIdsToBuy.length == 0) { if (spendCoins == false) { setProgress('', true); confShow(I18N('NT_HEROES_COLLECTED')); } cycle = false; return; } console.log(heroIdsToBuy); setProgress(I18N('NT_COLLECT_HEROES_PROGRESS', { counter: heroIdsToBuy.length }), false); await new Promise((e) => setTimeout(e, 3000)); //Активировать главу let chapterInfo = await Caller.send({ name: 'invasion_setActiveChapter', args: { chapterId: chapterId } }); let haveHeroFragments = chapterInfo.invasion.fragments; //Получить id магазина let shopId = await getShopId(chapters, 'hero'); //1078; // Магазин героев console.log('Id магазина героев ' + shopId); //Id миссии let firstMissionId = chapterInfo.invasion.actions[0].payload.id; let missionId = firstMissionId; //Жизни let lives = chapterInfo.invasion.lives; console.log('firstMissionId ' + firstMissionId); console.log('missionId ' + missionId); console.log('lives ' + lives); //Id героев, что будем покупить let heroIds = [0, 0, 0]; //Резервные герои, для добавления в покупки: Галахад, Тристан, Лирия //let reserveHeroes = [2, 54, 67]; //Резервные герои, для добавления в покупки: Электра, Каскад + Тея let reserveHeroes = [70, 69, 7]; //Собирать по 3 нужных героя if (heroIdsToBuy.length >= 3) { heroIds = [heroIdsToBuy[0], heroIdsToBuy[1], heroIdsToBuy[2]]; } if (heroIdsToBuy.length == 2) { heroIds[0] = heroIdsToBuy[0]; heroIds[1] = heroIdsToBuy[1]; for (let r of reserveHeroes) { if (r != heroIds[0] && r != heroIds[1]) { heroIds[2] = r; break; } } } if (heroIdsToBuy.length == 1) { if (reserveHeroes.includes(heroIdsToBuy[0])) { heroIds = reserveHeroes; } else { heroIds[0] = heroIdsToBuy[0]; heroIds[1] = reserveHeroes[0]; heroIds[2] = reserveHeroes[1]; } } //Фрагменты героев let heroFragments = [0, 0, 0]; for (let i = 0; i < heroFragments.length; i++){ if (haveHeroFragments[heroIds[i]]) { heroFragments[i] = haveHeroFragments[heroIds[i]]; } } console.log(heroIds); console.log(heroFragments); while (lives > 0 && missionId <= firstMissionId + 7) { setProgress(I18N('NHR_SHOPPING'), false); //Купить героев let result = await buyHeroesAndPets(shopId, heroIds, heroFragments, pets, spendCoins); //Выйти, если босс побежден и полностью собрали три героя if (result && farmedChapters.includes(chapterId)) { break; } //Текущая миссия босс или нет let boss = false; //Произвести атаку босса, если его ни разу не убили if (!farmedChapters.includes(chapterId)) { if (missionId == firstMissionId + 7) { boss = true; console.log('%cАтакуем босса ', 'color: green; font-weight: bold;'); } } else { //Не атаковать босса, если его уже убили if (missionId == firstMissionId + 7) { break; } } //Получить атакующую команду let heroes = []; let havePets = []; let pet; let petsFavor = {}; await getAttackingTeam(heroes, havePets); console.log('heroes ', JSON.stringify(heroes)); if (havePets.length > 0) { //Основной питомец 6005 - Альбрус let mainPet = 6005; if (havePets.includes(mainPet)) { pet = mainPet; } else { pet = havePets[0]; } //Покровительство const petLib = lib.getData('pet'); for (let heroId of heroes) { /** Поиск питомца для героя */ for (let petId of havePets) { if (petLib[petId].favorHeroes.includes(heroId)) { petsFavor[heroId] = petId; havePets = havePets.filter((e) => e != petId); break; }; } } } console.log('Атакующие герои ' + heroes); //Проходим миссию if (!boss) { setProgress(I18N('NT_MISSION_PROGRESS', {missionNumber: 1 + missionId - firstMissionId}), false); } else { setProgress(I18N('NT_MISSION_PROGRESS_BOSS'), false); } await new Promise((e) => setTimeout(e, 2000)); await attackHeroMission(missionId, chapterId, heroes, pet, boss, petsFavor); //Убили / не убили босса, вышли с "while" if (boss == true) { break; } //Результат атаки let invasionInfo = await Caller.send('invasion_getInfo'); farmedChapters = invasionInfo.farmedChapters; let missions = Object.values(invasionInfo.actions); for (let mission of missions) { if (mission.payload.wins == 0) { missionId = mission.payload.id; break; } } lives = invasionInfo.lives; console.log('missionId ' + missionId); console.log('lives ' + lives); } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// async function getHeroIdsToBuy() { const quest = await Caller.send('questGetAll'); const heroIds = quest .filter((e) => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === 'invasionStallHeroFragments') .map((e) => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId); return heroIds; } async function getTitanIdsToBuy() { const quest = await Caller.send('questGetAll'); const titanIds = quest .filter((e) => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === 'invasionStallFragmentsTitans') .map((e) => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId); return titanIds; } async function getTitanSkillIdsToBuy() { const quest = await Caller.send('questGetAll'); const titanSkillIds = quest .filter((e) => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === 'invasionStallFragmentsTitanSkills') .map((e) => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId); return titanSkillIds; } async function getShopId(chapters, titanOrHero) { if (chapters[0].settings?.stallShopId) { for (let chapter of chapters) { if (chapter.settings.unitType === titanOrHero) { return chapter.settings.stallShopId; } } } const result = await Caller.send('shopGetAll'); const shops = Object.values(result).filter(e => e.slots[1].cost?.coin); for (let shop of shops){ if (shop.slots[1].cost.coin[1080]){ return shop.id; } } return false; } function getChapterId(chapters, titanOrHero) { for (let chapter of chapters) { if (chapter.settings.unitType === titanOrHero) { return chapter.id; } } return false; } function compareVersions(version1, version2) { const v1 = version1.split('.').map(Number); const v2 = version2.split('.').map(Number); const maxLength = Math.max(v1.length, v2.length); for (let i = 0; i < maxLength; i++) { const num1 = v1[i] || 0; const num2 = v2[i] || 0; if (num1 > num2) return 1; if (num1 < num2) return -1; } return 0; } function getAllHeroIDs() { let heroIds = Object.values(lib.data.hero).filter(e => e.type === 'hero' && !e.roleExtended.includes('boss')); heroIds = heroIds.filter((e) => e.id != 63 && e.id != 65); const heroIdsConsole = heroIds.map(e => `${e.id} - ` + cheats.translate(`LIB_HERO_NAME_${e.id}`)).join('\n'); console.log(heroIdsConsole); popup.customPopup(async (complete) => { popup.custom.insertAdjacentHTML( 'beforeend', '' ); popup.setMsgText(I18N('NHR_GET_HERO_IDS_MESSAGE')); popup.addButton({ isClose: true }, () => { complete(false); popup.hide(); }); popup.show(); }); } function getAllTitanIDs() { let waterTitans = Object.values(lib.data.hero).filter(e => e.type === 'titan' && e.id < 4010);; let fireTitans = Object.values(lib.data.hero).filter(e => e.type === 'titan' && e.id >= 4010 && e.id < 4020); let earthTitans = Object.values(lib.data.hero).filter(e => e.type === 'titan' && e.id >= 4020 && e.id < 4030); let darknessTitans = Object.values(lib.data.hero).filter(e => e.type === 'titan' && e.id >= 4030 && e.id < 4040); let lightTitans = Object.values(lib.data.hero).filter(e => e.type === 'titan' && e.id >= 4040 && e.id < 4050); let message = ''; const heroIdsConsole = Object.values(lib.data.hero).filter(e => e.type === 'titan').map(e => `${e.id} - ` + cheats.translate(`LIB_HERO_NAME_${e.id}`)).join('\n'); console.log(heroIdsConsole); message += `
` + waterTitans.map((e) => `').join('') + '
'; message += `` + fireTitans.map((e) => `').join('') + '
'; message += `` + earthTitans.map((e) => `').join('') + '
'; message += `` + darknessTitans.map((e) => `').join('') + '
'; message += `` + lightTitans.map((e) => `').join(''); popup.customPopup(async (complete) => { popup.custom.insertAdjacentHTML( 'beforeend', message ); popup.setMsgText(I18N('NHR_GET_HERO_IDS_MESSAGE')); popup.addButton({ isClose: true }, () => { complete(false); popup.hide(); }); popup.show(); }); } async function getAttackingTeam (heroes, other = [], allHeroes = []) { let haveFragments = Object.entries(await Caller.send('invasion_getInfo').then((e) => e.fragments)).map(e => ({id:e[0],count:e[1]})).sort((a, b) => b.count - a.count); console.log(haveFragments); for (let m of haveFragments) { //Отделяем питомцев и фрагменты тотемов if (Number(m.id) < 4400) { allHeroes.push(Number(m.id)); if (heroes.length < 5) { heroes.push(Number(m.id)); } } if (Number(m.id) > 4400) { other.push(Number(m.id)); } } } async function getTeamButton (titanAttackingTeams, chapterNumber, titanOrHero) { let message = ''; if (titanOrHero === 'titan' ) { message = I18N('NT_ENTER_TITAN_IDS', { chapterNumber: romanNumerals[chapterNumber] }); } if (titanOrHero === 'hero' ) { message = I18N('NT_ENTER_HERO_IDS', { chapterNumber: romanNumerals[chapterNumber] }); } const answer = await popup.confirm(message, [ { msg: I18N('NT_COMPLETE_CHAPTER'), placeholder: '1,2,3,4,5,6', isInput: true, default: titanAttackingTeams, color: 'green', }, { msg: I18N('BTN_CANCEL'), result: false, isCancel: true, color: 'red', }, ]); if (!answer) { return false; } let team = answer.split(','); if (team.length != 5) { team = answer.split('-'); } if (team.length != 5) { if (titanOrHero === 'hero' ) { confShow(I18N('NT_MUST_FIVE_HEROES')); } if (titanOrHero === 'titan' ) { confShow(I18N('NT_MUST_FIVE_TITANS')); } return false; } for (let p in team) { team[p] = +team[p].trim() if (Number.isNaN(team[p])) { confShow(I18N('NT_MUST_ONLY_NUMBERS')); return false; } } return team; } async function spendValorCoins() { let answer = await popup.confirm( I18N('NHR_SPEND_VALOR_COINS_MESSAGE'), [ { msg: I18N('NHR_APPLY'), result: true, color: 'green' }, { msg: I18N('NHR_NOT_APPLY'), result: false, isCancel: true, color: 'red' }, ], ); if (!answer) { return; } let [invasionInfo, inventoryGet, workshopBuffInfo] = await Caller.send(['invasion_getInfo', 'inventoryGet', 'workshopBuff_getInfo']); let invasionInfoId = invasionInfo.id; let chapters = Object.values(lib.data.invasion.chapter).filter((e) => e.invasionId === invasionInfoId); let coins = chapters[0].completeReward.coin; let valorCoinId = 0; let sapphireMedallionId = 0; for (let coin in coins) { if(coins[coin] > 10) { valorCoinId = coin; } if(coins[coin] < 10) { sapphireMedallionId = coin; } } console.log('valorCoinId ' + valorCoinId); let valorCoins = 0; if (inventoryGet.coin[valorCoinId]) { valorCoins = inventoryGet.coin[valorCoinId]; } console.log('valorCoins ' + valorCoins); let grailId = Object.entries(lib.data.workshop.relic).find(([key, item]) => item.invasionId === invasionInfoId && item.effect?.type === "gachaReward_change")[0]; let grailLvl = workshopBuffInfo.find(e => e.id == grailId ).level; console.log('grailId ' + grailId); console.log('grailLvl ' + grailLvl); if (valorCoins < (2800 - grailLvl * 100)) { confShow(I18N('NHR_NOT_ENOUGH_COINS')); return; } let amount = Math.floor(valorCoins/(2800 - grailLvl * 100)); console.log('amount ' + amount); let offerId = lib.data.invasion.list[invasionInfoId].clientData.festival.lootBoxSpecialOfferId; let boxName = Object.keys((await Caller.send('specialOffer_getAll')).find(e => e.id == offerId).offerData.lootBoxes)[0]; console.log('offerId ' + offerId); console.log('boxName ' + boxName); let result = await Caller.send({name:"lootBoxBuy",args:{box:boxName,offerId:offerId,price:"openCoin",amount:amount}}) let sapphireMedallion = 0; let fragmentHero = 0; if (result) { for (let r of result) { if (r.coin?.[sapphireMedallionId]) { sapphireMedallion += Number(r.coin[sapphireMedallionId]); } if (r.fragmentHero) { fragmentHero += Number(Object.values(r.fragmentHero)[0]); } } } confShow(I18N('NHR_SPEND_VALOR_COINS_RESULT', {sapphireMedallion:sapphireMedallion, fragmentHero:fragmentHero })); console.log(sapphireMedallion); console.log(fragmentHero); } async function buyTitansAndTotemSkils (shopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments) { console.log('Зашли в магазин'); console.log('titanIds ', JSON.stringify(titanIds)); console.log('titanFragments ', JSON.stringify(titanFragments)); console.log('titanSkilsIds ', JSON.stringify(titanSkilsIds)); console.log('titanSkilFragments ', JSON.stringify(titanSkilFragments)); let coins = await Caller.send('inventoryGet').then((e) => e.coin[1080]); console.log('Монеты: ' + coins); let shopSlots = null; while (coins >= 9) { try { //Получить состояние магазина if (!shopSlots) { shopSlots = await Caller.send([{ name: 'shopGet', args: { shopId: shopId } }]).then((e) => Object.values(e.slots)); } for (let slot of shopSlots) { //Пропустить скрытые лоты if (slot.reward.invasionFragmentTitanRand || slot.reward.invasionFragmentSkillRand) { continue; } let boughtTitan = false; //Купить титанов for (let t = 0; t < titanIds.length; t++) { if (slot.reward.invasionFragmentTitan?.[titanIds[t]] && titanFragments[t] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: shopId, slot: slot.id } }); console.log('%cКуплен титан ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; titanFragments[t] += slot.reward.invasionFragmentTitan?.[titanIds[t]]; //Если c первым титаном есть другой for (let i = t+1; i < titanIds.length; i++) { if (slot.reward.invasionFragmentTitan?.[titanIds[i]]) { console.log('%cВторой титан в комплекте ', 'color: green; font-weight: bold;'); titanFragments[i] += slot.reward.invasionFragmentTitan?.[titanIds[i]]; break; } } } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: shopId, slotId: slot.id } }); } boughtTitan = true; break; } } //Купить навыки тотема if (!boughtTitan) { for (let s = 0; s < titanSkilsIds.length; s++) { if (slot.reward.invasionFragmentSkill?.[titanSkilsIds[s]] && titanSkilFragments[s] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: shopId, slot: slot.id } }); console.log('%cКуплена часть навыка тотема ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; titanSkilFragments[s] += slot.reward.invasionFragmentSkill?.[titanSkilsIds[s]]; } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: shopId, slotId: slot.id } }); } break; } } } //Проверить, собраны ли титаны и тотемы let titanF = false; let titanS = false; for (let tf of titanFragments) { if (tf < 7) { titanF = false; break; } titanF = true; } for (let ts of titanSkilFragments) { if (ts < 7) { titanS = false; break; } titanS = true; } //Выйти, если титаны и тотемы собраны if ( titanF && titanS) { return true; } } } catch (e) { console.log('%cПроизошла ошибка', 'color: red; font-weight: bold;'); coins = await Caller.send('inventoryGet').then((e) => e.coin[1080]); } //Обновить магазин if (coins >= 12) { try { shopSlots = await Caller.send([{ name: 'shopRefresh', args: { shopId: shopId } }]).then((e) => Object.values(e.slots)); coins -= 3; console.log('Обновили магазин. Осталось монет: ' + coins); } catch (e) { shopSlots = await Caller.send([{ name: 'shopRefresh', args: { shopId: shopId } }]).then((e) => Object.values(e.slots)); coins = await Caller.send('inventoryGet').then((e) => e.coin[1080]); } } else { break; } } return false; } async function buyHeroesAndPets (shopId, heroIds, heroFragments, pets, spendCoins = false) { console.log('Зашли в магазин'); console.log('heroIds ', JSON.stringify(heroIds)); console.log('heroFragments ', JSON.stringify(heroFragments)); console.log('pets ', JSON.stringify(pets)); let coins = await Caller.send('inventoryGet').then((e) => e.coin[1080]); console.log('Монеты: ' + coins); let shopSlots = null; let boughtAllHeroes = false; while (coins >= 12) { try { //Получить состояние магазина if (!shopSlots) { shopSlots = await Caller.send([{ name: 'shopGet', args: { shopId: shopId } }]).then((e) => Object.values(e.slots)); } //Если куплены все герои, питомци, и нет задания на трату монет, выйти и заменить героев для покупки if (boughtAllHeroes && pets.length == 0 && !spendCoins ) { return true; } //Если куплены все герои, питомци, и есть задание на трату монет if (boughtAllHeroes && pets.length == 0 && spendCoins ) { console.log('%cТратим монеты ', 'color: red; font-weight: bold;'); for (let slot of shopSlots) { if (coins >= slot.cost.coin[1080]) { await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: shopId, slot: slot.id } }); coins -= slot.cost.coin[1080]; } } } //Купить героев if (!boughtAllHeroes) { for (let slot of shopSlots) { //Пропустить скрытые лоты и питомцев if (slot.reward.invasionFragmentHeroRand || slot.reward.invasionFragmentPet) { continue; } //Покупки героев, когда собираем героев if (heroIds.length <= 3) { for (let t = 0; t < heroIds.length; t++) { if (slot.reward.invasionFragmentHero?.[heroIds[t]] && heroFragments[t] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: shopId, slot: slot.id } }); console.log('%cКуплен герой ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; heroFragments[t] += slot.reward.invasionFragmentHero?.[heroIds[t]]; //Если c первым героем есть другой for (let i = t+1; i < heroIds.length; i++) { if (slot.reward.invasionFragmentHero?.[heroIds[i]]) { console.log('%cВторой герой в комплекте ', 'color: green; font-weight: bold;'); heroFragments[i] += slot.reward.invasionFragmentHero?.[heroIds[i]]; break; } } } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: shopId, slotId: slot.id } }); } break; } } } //Покупки героев, когда проходим миссии if (heroIds.length > 3) { //Если 2 героя в одном слоте if (Object.values(slot.reward.invasionFragmentHero).length >= 2) { for (let t = 0; t < heroIds.length; t++) { let boughtSlot = false; if (slot.reward.invasionFragmentHero?.[heroIds[t]] && heroFragments[t] < 7) { //Если c первым героем есть другой for (let i = t+1; i < heroIds.length; i++) { if (slot.reward.invasionFragmentHero?.[heroIds[i]]) { if (coins >= slot.cost.coin[1080]) { console.log('%cДва героя по цене троих! Выгодно. Покупаем. ', 'color: green; font-weight: bold;'); let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: shopId, slot: slot.id } }); heroFragments[t] += slot.reward.invasionFragmentHero?.[heroIds[t]]; heroFragments[i] += slot.reward.invasionFragmentHero?.[heroIds[i]]; coins -= slot.cost.coin[1080]; } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: shopId, slotId: slot.id } }); } boughtSlot = true; break; } } } if (boughtSlot) { break; } } } //Если 1 герой в слоте if (Object.values(slot.reward.invasionFragmentHero).length == 1) { for (let t = 0; t < heroIds.length; t++) { if (slot.reward.invasionFragmentHero?.[heroIds[t]] && heroFragments[t] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: shopId, slot: slot.id } }); console.log('%cКуплен герой ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; heroFragments[t] += slot.reward.invasionFragmentHero?.[heroIds[t]]; } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: shopId, slotId: slot.id } }); } break; } } } } } //Куплены все герои или нет for (let fragments of heroFragments) { if (fragments < 7) { boughtAllHeroes = false; break; } boughtAllHeroes = true; } } //Купить питомцев if (pets.length > 0) { for (let slot of shopSlots) { //Пропустить скрытые лоты и героев if (slot.reward.invasionFragmentHeroRand || slot.reward.invasionFragmentHero) { continue; } for (let s = 0; s < pets.length; s++) { if (slot.reward.invasionFragmentPet?.[pets[s]] ) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: shopId, slot: slot.id } }); console.log('%cКуплен питомец ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; pets.splice(pets.indexOf(pets[s]), 1) } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: shopId, slotId: slot.id } }); } break; } } if (pets.length == 0) { break; } } } } catch (e) { console.log('%cПроизошла ошибка', 'color: red; font-weight: bold;'); coins = await Caller.send('inventoryGet').then((e) => e.coin[1080]); } //Обновить магазин if (coins >= 15) { try { shopSlots = await Caller.send([{ name: 'shopRefresh', args: { shopId: shopId } }]).then((e) => Object.values(e.slots)); coins -= 3; console.log('Обновили магазин. Осталось монет: ' + coins); } catch (e) { shopSlots = await Caller.send([{ name: 'shopRefresh', args: { shopId: shopId } }]).then((e) => Object.values(e.slots)); coins = await Caller.send('inventoryGet').then((e) => e.coin[1080]); } } else { break; } } return false; } async function collectTotemFragments() { //Получить состояние на карте let invasionInfo = await Caller.send('invasion_getInfo'); let invasionInfoId = invasionInfo.id; let farmedChapters = invasionInfo.farmedChapters; console.log('invasionInfoId ' + invasionInfoId); console.log('farmedChapters ', JSON.stringify(farmedChapters)); //Получить id первой главый let chapters = Object.values(lib.data.invasion.chapter).filter((e) => e.invasionId === invasionInfoId); let chapterId = getChapterId(chapters, 'titan'); console.log('chapterId ' + chapterId); let cycle = true; while (cycle) { //Получить навыки тотемов, которые нужно собрать let titanSkilsIds = await getTitanSkillIdsToBuy(); if (titanSkilsIds.length == 0) { setProgress('', true); confShow(I18N('NT_TOTEM_SKILLS_COLLECTED')); cycle = false; return; } console.log(titanSkilsIds); setProgress(I18N('NT_COLLECT_TOTEM_SKILLS_PROGRESS', { counter: titanSkilsIds.length }), false); await new Promise((e) => setTimeout(e, 3000)); //Фрагменты навыков тотемов let titanSkilFragments = [0, 0]; if (titanSkilsIds.length == 1) { titanSkilFragments = [0]; } //Активировать главу let chapterInfo = await Caller.send({ name: 'invasion_setActiveChapter', args: { chapterId: chapterId } }); let haveTitanFragments = chapterInfo.invasion.fragments; //Получить id магазина let titanShopId = await getShopId(chapters, 'titan'); //1073; // Магазин титанов console.log('Id магазина титанов ' + titanShopId); //Id миссии let firstMissionId = chapterInfo.invasion.actions[0].payload.id; let missionId = firstMissionId; //Жизни let lives = chapterInfo.invasion.lives; console.log('firstMissionId ' + firstMissionId); console.log('missionId ' + missionId); console.log('lives ' + lives); //Id титанов, что необходимо купить //Ияри и Солярис let titanIds = [4042, 4043]; //Фрагменты титанов let titanFragments = [0, 0]; if (haveTitanFragments[titanIds[0]]) { titanFragments[0] = haveTitanFragments[titanIds[0]]; } if (haveTitanFragments[titanIds[1]]) { titanFragments[1] = haveTitanFragments[titanIds[1]]; } console.log('titanShopId ' + titanShopId); console.log(titanIds); console.log(titanFragments); while (lives > 0 && missionId <= firstMissionId + 7) { setProgress(I18N('NHR_SHOPPING'), false); //Купить титанов и навыки тотемов let result = await buyTotemSkilsInTheStore(titanShopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments); //Выйти, если босс побежден и полностью собрали два навыка тотема if (result && farmedChapters.includes(chapterId)) { break; } //Произвести атаку босса, если его ни разу не убили if (!farmedChapters.includes(chapterId)) { if (missionId == firstMissionId + 7) { console.log('%cАтакуем босса ', 'color: green; font-weight: bold;'); } } else { //Не атаковать босса, если его уже убили if (missionId == firstMissionId + 7) { break; } } //Получить атакующую команду let heroes = []; let titanSkil = []; await getAttackingTeam(heroes, titanSkil); console.log(heroes); let firstSpiritSkills = {}; //Проходим миссию setProgress(I18N('NT_MISSION_PROGRESS', {missionNumber: 1 + missionId - firstMissionId}), false); await attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills); //Результат атаки let invasionInfo = await Caller.send('invasion_getInfo'); farmedChapters = invasionInfo.farmedChapters; let missions = Object.values(invasionInfo.actions); for (let mission of missions) { if (mission.payload.wins == 0) { missionId = mission.payload.id; break; } } lives = invasionInfo.lives; console.log('missionId ' + missionId); console.log('lives ' + lives); } } } async function buyTotemSkilsInTheStore(titanShopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments) { console.log('Зашли в магазин'); console.log('titanIds ', JSON.stringify(titanIds)); console.log('titanFragments ', JSON.stringify(titanFragments)); console.log('titanSkilsIds ', JSON.stringify(titanSkilsIds)); console.log('titanSkilFragments ', JSON.stringify(titanSkilFragments)); let coins = await Caller.send('inventoryGet').then((e) => e.coin[1080]); console.log('Монеты: ' + coins); let shopSlots = null; while (coins >= 9) { //Получить состояние магазина if (!shopSlots) { shopSlots = await Caller.send([{ name: 'shopGet', args: { shopId: titanShopId } }]).then((e) => Object.values(e.slots)); } for (let slot of shopSlots) { //Пропустить скрытые лоты if (slot.reward.invasionFragmentTitanRand || slot.reward.invasionFragmentSkillRand) { continue; } //Купить первый навык тотема if (slot.reward.invasionFragmentSkill?.[titanSkilsIds[0]] && titanSkilFragments[0] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: titanShopId, slot: slot.id } }); if (shopBuy.error) { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); coins = 0; continue; } console.log('%cКуплена часть навыка тотема ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; titanSkilFragments[0] += slot.reward.invasionFragmentSkill?.[titanSkilsIds[0]]; } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); } continue; } //Купить второй навык тотема if (titanSkilsIds.length >= 2 && slot.reward.invasionFragmentSkill?.[titanSkilsIds[1]] && titanSkilFragments[1] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: titanShopId, slot: slot.id } }); if (shopBuy.error) { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); coins = 0; continue; } console.log('%cКуплена часть навыка тотема ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; titanSkilFragments[1] += slot.reward.invasionFragmentSkill?.[titanSkilsIds[1]]; } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); } continue; } //Если навыки собраны, обновляем навыки if (titanSkilsIds.length >= 2 && titanSkilFragments[0] >= 7 && titanSkilFragments[1] >= 7) { titanSkilsIds = await getTitanSkillIdsToBuy(); titanSkilFragments = [0, 0]; if (titanSkilsIds.length == 1) { titanSkilFragments = [0]; } } if ((titanSkilsIds.length == 1 && titanSkilFragments[0] >= 7) || titanSkilsIds.length == 0) { //Тратим оставшиеся монеты (пусть будет, вдруг пригодиццо) /*if (coins >= slot.cost.coin[1080]){ let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}}); coins -= slot.cost.coin[1080]; if(shopBuy.error){ coins = 0; continue; } }*/ //Купили все навыки, идем на выход return true; } //Купить первого титана if (slot.reward.invasionFragmentTitan?.[titanIds[0]] && titanFragments[0] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: titanShopId, slot: slot.id } }); if (shopBuy.error) { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); coins = 0; continue; } console.log('%cКуплен титан ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; titanFragments[0] += slot.reward.invasionFragmentTitan?.[titanIds[0]]; //Если c первым титаном есть второй if (slot.reward.invasionFragmentTitan?.[titanIds[1]]) { console.log('%cВторой титан в комплекте ', 'color: green; font-weight: bold;'); titanFragments[1] += slot.reward.invasionFragmentTitan?.[titanIds[1]]; } } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); } continue; } //Купить второго титана if (slot.reward.invasionFragmentTitan?.[titanIds[1]] && titanFragments[1] < 7) { if (coins >= slot.cost.coin[1080]) { let shopBuy = await Caller.send({ name: 'shopBuy', args: { cost: {}, reward: {}, shopId: titanShopId, slot: slot.id } }); if (shopBuy.error) { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); coins = 0; continue; } console.log('%cКуплен титан ', 'color: green; font-weight: bold;'); coins -= slot.cost.coin[1080]; titanFragments[1] += slot.reward.invasionFragmentTitan?.[titanIds[1]]; } else { await Caller.send({ name: 'shop_pinSlot', args: { shopId: titanShopId, slotId: slot.id } }); } continue; } } //Обновить магазин if (coins >= 12) { shopSlots = await Caller.send({ name: 'shopRefresh', args: { shopId: titanShopId } }).then((e) => Object.values(e.slots)); coins -= 3; console.log('Обновили магазин. Осталось монет ' + coins); if (shopSlots.error) { coins = 0; } } else { break; } } return false; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// async function attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills, boss = false) { if (boss == true) { console.log('%cАтакуем босса ', 'color: green; font-weight: bold;'); } const startBattle = await Caller.send({ name: 'invasion_bossStart', args: { id: missionId, chapterId: chapterId, heroes: heroes, //firstSpiritElement: "earth", firstSpiritSkills: firstSpiritSkills, favor: {}, }, }); const calcBattle = await Calc(startBattle); if (!calcBattle.result.win) { const cloneBattle = structuredClone(startBattle); const bFix = new WinFixBattle(cloneBattle); let result = await bFix.start(cloneBattle.endTime, Infinity); if (result.result?.win) { calcBattle.result = result.result; calcBattle.progress = result.progress; calcBattle.battleTimer = result.battleTimer; } } if (!calcBattle.result.win && boss == true) { //Босса не убили console.log('%cБосса не убили ', 'color: red; font-weight: bold;'); return; } if (boss == true) { let timer = calcBattle.battleTimer; console.log('%cУбили босса', 'color: green; font-weight: bold;'); let message = I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_1'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_2'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_3'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_4'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_5'); await countdownTimer(timer, message); } const endBattle = await Caller.send({ name: 'invasion_bossEnd', args: { id: missionId, result: calcBattle.result, progress: calcBattle.progress, }, }); } async function attackHeroMission(missionId, chapterId, heroes, pet, boss = false, petsFavor) { if (boss == true) { console.log('%cАтакуем босса ', 'color: green; font-weight: bold;'); } const startBattle = await Caller.send({ name: 'invasion_bossStart', args: { id: missionId, chapterId: chapterId, heroes: heroes, pet: pet, favor: petsFavor, }, }); const calcBattle = await Calc(startBattle); if (!calcBattle.result.win) { const cloneBattle = structuredClone(startBattle); const bFix = new WinFixBattle(cloneBattle); let result = await bFix.start(cloneBattle.endTime, Infinity); if (result.result?.win) { calcBattle.result = result.result; calcBattle.progress = result.progress; calcBattle.battleTimer = result.battleTimer; } } if (!calcBattle.result.win && boss == true) { //Босса не убили console.log('%cБосса не убили ', 'color: red; font-weight: bold;'); return; } if (boss == true) { let timer = calcBattle.battleTimer; console.log('%cУбили босса', 'color: green; font-weight: bold;'); let message = I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_1'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_2'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_3'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_4'); setProgress(message, false); await new Promise((e) => setTimeout(e, 1000)); message += I18N('NT_BOSS_WAS_KILLED_SET_PROGRESS_5'); await countdownTimer(timer, message); } await Caller.send({ name: 'invasion_bossEnd', args: { id: missionId, result: calcBattle.result, progress: calcBattle.progress, }, }); } })();