// ==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',
'