// ==UserScript== // @name HWHNewCharacterExt // @name:en HWHNewCharacterExt // @name:ru HWHNewCharacterExt // @namespace HWHNewCharacterExt // @version 1.01 // @description Extension for HeroWarsHelper script // @description:en Extension for HeroWarsHelper script // @description:ru Расширение для скрипта HeroWarsHelper // @author ZingerY, Green // @license Copyright Green // @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 { buttons } = HWHData; const { popup, confShow, getInput, setProgress, hideProgress, I18N, send, getTimer, countdownTimer, getUserInfo, getSaveVal, setSaveVal, setIsCancalBattle, random, EventEmitterMixin, } = HWHFuncs; const { i18nLangData } = HWHData; const { WinFixBattle } = HWHClasses; const i18nLangDataEn = { NEWCHARACTER: 'New Character', NEWCHARACTER_TITLE: 'Complete quests for a new hero or titan', NEWCHARACTER_NOEVENT: 'The event is not active', NEWHERO: 'New Hero Event', NEWTITAN: 'New Titan Event', NEWHERO_COMPLETETASKS: 'Complete the tasks', NEWHERO_COMPLETETASKS_TITLE: 'Complete the event tasks', NEWHERO_COMPLETECAPTERS:'Complete chapters', NEWHERO_COMPLETECAPTERS_TITLE:'Complete chapters', NEWHERO_SELECTACTION:'Select an action', NEWTITAN_GETTITANS: 'Get the Titans', NEWTITAN_GETTITANS_TITLE: 'Get the Titans of the maximum rank by collecting fragments in the shop', NEWTITAN_GETHEROES: 'Get the Heroes', NEWTITAN_GETHEROES_TITLE: 'Get the Heroes of the maximum rank by collecting fragments in the shop', NEWTITAN_GETINFLUENCESKILL: 'Get influence skill', NEWTITAN_GETINFLUENCESKILL_TITLE: 'Get the influence skill of the maximum rank by collecting fragments in the shop', NEWTITAN_GETTITANSPROGRESS: ' {counter} titans left to collect. Collecting...', NEWTITAN_GETTITANSCOLLECTED: 'All titans have been collected', }; i18nLangData['en'] = Object.assign(i18nLangData['en'], i18nLangDataEn); const i18nLangDataRu = { NEWCHARACTER: 'Новый персонаж', NEWCHARACTER_TITLE: 'Выполнять задания для нового героя или титана', NEWCHARACTER_NOEVENT: 'Ивент не активен', NEWHERO: 'Событие нового героя', NEWTITAN: 'Событие нового титана', NEWHERO_COMPLETETASKS: 'Выполнить задания', NEWHERO_COMPLETETASKS_TITLE: 'Выполнить заданий ивента', NEWHERO_COMPLETECAPTERS:'Проходить главы', NEWHERO_COMPLETECAPTERS_TITLE:'Проходить главы', NEWHERO_SELECTACTION:'Выберите действие', NEWTITAN_GETTITANS: 'Получить титанов', NEWTITAN_GETTITANS_TITLE: 'Получить титанов максимального ранга, собирая фрагменты в магазине', NEWTITAN_GETHEROES: 'Получить героев', NEWTITAN_GETHEROES_TITLE: 'Получить героев максимального ранга, собирая фрагменты в магазине', NEWTITAN_GETINFLUENCESKILL: 'Получить навыки влияния', NEWTITAN_GETINFLUENCESKILL_TITLE: 'Получить навыки влияния максимального ранга, собирая фрагменты в магазине', NEWTITAN_GETTITANSPROGRESS: 'Осталось собрать {counter} титанов. Собираем...', NEWTITAN_GETTITANSCOLLECTED: 'Все титаны собраны', }; i18nLangData['ru'] = Object.assign(i18nLangData['ru'], i18nLangDataRu); /////////////////////////////////////////////////////////////////////////////////////////////// // Добавление кнопоки в окно Разное const { othersPopupButtons } = HWHData; othersPopupButtons.push({ get msg() { return I18N('NEWCHARACTER'); }, get title() { return I18N('NEWCHARACTER_TITLE'); }, result: async function () { //if(await Caller.send(['invasion_getInfo'])){ if(true){ await onClickNewHeroTitanButton(); }else{ confShow(`${I18N('NEWCHARACTER_NOEVENT')}`); } }, }); async function onClickNewHeroTitanButton() { const popupButtons = [ { get msg() { return I18N('NEWHERO'); }, get title() { return I18N('NEWHERO_COMPLETETASKS_TITLE'); }, result:async function () { await onClickNewHeroButton(); }, }, { get msg() { return I18N('NEWTITAN'); }, get title() { return I18N('NEWHERO_COMPLETETASKS_TITLE'); }, result:async function () { await onClickNewTitanButton(); }, }, ]; popupButtons.push({ result: false, isClose: true }); const answer = await popup.confirm(`${I18N('NEWHERO_SELECTACTION')}`, popupButtons); if (typeof answer === 'function') { answer(); } } async function onClickNewHeroButton() { const popupButtons = [ { get msg() { return I18N('NEWHERO_COMPLETETASKS'); }, get title() { return I18N('NEWHERO_COMPLETETASKS_TITLE'); }, result:async function () { confShow('Нажата кнопка'); }, }, { get msg() { return I18N('NEWHERO_COMPLETECAPTERS'); }, get title() { return I18N('NEWHERO_COMPLETECAPTERS_TITLE'); }, result: () => { confShow('Нажата кнопка 2'); }, }, ]; popupButtons.push({ result: false, isClose: true }); const answer = await popup.confirm(`${I18N('NEWHERO_SELECTACTION')}`, popupButtons); if (typeof answer === 'function') { answer(); } } async function onClickNewTitanButton() { const popupButtons = [ { get msg() { return I18N('NEWTITAN_GETTITANS'); }, get title() { return I18N('NEWTITAN_GETTITANS_TITLE'); }, result:async function () { //confShow('Нажата кнопка'); await newTitanGetTitans(); }, }, { get msg() { return I18N('NEWTITAN_GETHEROES'); }, get title() { return I18N('NEWTITAN_GETHEROES_TITLE'); }, result: () => { confShow('Нажата кнопка 2'); }, }, { get msg() { return I18N('NEWTITAN_GETINFLUENCESKILL'); }, get title() { return I18N('NEWTITAN_GETINFLUENCESKILL_TITLE'); }, result: () => { confShow('Нажата кнопка 3'); }, }, ]; popupButtons.push({ result: false, isClose: true }); const answer = await popup.confirm(`${I18N('NEWHERO_SELECTACTION')}`, popupButtons); if (typeof answer === 'function') { answer(); } } async function newTitanGetTitans() { //Получить состояние на карте let invasionInfoId = await Caller.send('invasion_getInfo').then(e => e.id); console.log("invasionInfoId " + invasionInfoId); //Сброс главы await Caller.send('invasion_resetChapter') //Получить id первой главый let chapters = Object.values(lib.data.invasion.chapter).filter(e => e.invasionId === invasionInfoId) let chapterId = chapters[0].id console.log("chapterId " + chapterId); //Получить id магазина //let heroShopId = await getShopId(chapters, "hero"); //1074; // Магазин героев let titanShopId = await getShopId(chapters, "titan"); //1073; // Магазин титанов //console.log("Id магазина героев " + heroShopId); console.log("Id магазина титанов " + titanShopId); let cycle = true; while( cycle ){ //Получить титанов, которых нужно собрать let allTitanIdsToBuy = await getTitanIdsToBuy(); console.log(allTitanIdsToBuy); if (allTitanIdsToBuy.length == 0){ confShow(I18N('NEWTITAN_GETTITANSCOLLECTED')); cycle = false; return; } setProgress(I18N('NEWTITAN_GETTITANSPROGRESS', {counter:allTitanIdsToBuy.length}), false); //Активировать главу let chapterInfo = await Caller.send({name: 'invasion_setActiveChapter',args: {chapterId: chapterId}}); let haveTitanFragments = chapterInfo.invasion.fragments; //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 fragments = [0, 0]; //Id титанов, что необходимо купить let titanIdsToBuy = [0, 0]; if (allTitanIdsToBuy.length >= 2){ titanIdsToBuy = [allTitanIdsToBuy[0], allTitanIdsToBuy[1]]; }else{ titanIdsToBuy = [allTitanIdsToBuy[0], Object.keys(haveTitanFragments)[0]]; } if (haveTitanFragments[titanIdsToBuy[0]]){ fragments[0] = haveTitanFragments[titanIdsToBuy[0]]; } if (haveTitanFragments[titanIdsToBuy[1]]){ fragments[1] = haveTitanFragments[titanIdsToBuy[1]]; } console.log("titanShopId "+ titanShopId); console.log(titanIdsToBuy); console.log(fragments); while( lives > 0 && missionId <= (firstMissionId+7)){ //Купить титанов await buyTitanInTheStore(titanShopId, titanIdsToBuy, fragments); //Не атакуем босса if (missionId == (firstMissionId+7)){ break; } //Получить атакующую команду let heroes = []; haveTitanFragments = await Caller.send('invasion_getInfo').then(e => e.fragments); for (let f in haveTitanFragments){ heroes.push(Number(f)); if(heroes.length == 5){ break; } } console.log(heroes) let firstSpiritSkills = {}; //Проходим миссию await attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills); //Результат атаки 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; } } lives = invasionInfo.lives; console.log("missionId "+ missionId); console.log("lives "+ lives); } //cycle = false; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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){ for (let chapter of chapters){ if(chapter.settings.unitType === titanOrHero){ return chapter.settings.stallShopId; } } return false; } async function buyTitanInTheStore(titanShopId, titanIdsToBuy, fragments) { console.log("Зашли в магазин"); console.log(titanIdsToBuy); console.log(fragments); //Навыки тотемов let titanSkilsIdsToBuy = await getTitanSkillIdsToBuy(); console.log(titanSkilsIdsToBuy); console.log(titanSkilsIdsToBuy.length); //Фрагменты навыка let titanSkilFragments = 0; let coins = await Caller.send('inventoryGet').then(e => e.coin[1080]); console.log("coins " + coins); while( coins >= 9){ //Получить состояние магазина let result = await Caller.send([{name:'shopGet',args:{shopId: titanShopId}}]).then(e => e.slots); let slots = Object.values(result) console.log(slots); for (let slot of slots){ //Пропустить скрытые лоты if (slot.reward.invasionFragmentTitanRand || slot.reward.invasionFragmentSkillRand){ continue; } //console.log(slot); //Купить первого титана if (slot.reward.invasionFragmentTitan?.[titanIdsToBuy[0]] && fragments[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]; fragments[0] += slot.reward.invasionFragmentTitan?.[titanIdsToBuy[0]]; //Если c первым титаном есть второй if(slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]]){ console.log("%cВторой титан в комплекте ", "color: green; font-weight: bold;") fragments[1] += slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]]; } }else{ await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}}); } continue; } //Купить второго титана if (slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]] && fragments[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]; fragments[1] += slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]]; } else{ await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}}); } continue; } //Потратить оставшиеся монеты, если титаны уже куплены if (fragments[0] >= 7 && fragments[1] >= 7){ console.log("Тратим монеты"); //Покупаем часть тотема if (titanSkilsIdsToBuy.length >= 1){ //console.log("Покупаем часть тотема"); if (slot.reward.invasionFragmentSkill?.[titanSkilsIdsToBuy[0]]){ 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 += slot.reward.invasionFragmentSkill?.[titanSkilsIdsToBuy[0]]; if (titanSkilFragments >= 7){ titanSkilsIdsToBuy = await getTitanSkillIdsToBuy(); titanSkilFragments = 0; } }else{ await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}}); } } }else{ 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; } } } } } //Обновить магазин if (coins >= 12){ let shopRefresh = await Caller.send({name: 'shopRefresh', args: {shopId: titanShopId}}); //await new Promise((e) => setTimeout(e, 1000)); coins -= 3; console.log("Обновили магазин. Осталось монет " + coins); let coins2 = await Caller.send('inventoryGet').then(e => e.coin[1080]); console.log("coins2 " + coins2); if(shopRefresh.error){ coins = 0; } }else{ break; return; } } } async function buyHeroInTheStore(heroShopId, herosId) { let coins = await Caller.send('inventoryGet').then(e => e.coin[1080]); console.log("coins" + coins); //Получить состояние магазина const result = await Caller.send([{name:'shopGet',args:{shopId: shopId}}]).then(e => e.slots); let slots = Object.values(result) for (let slot of slots){ //Пропустить скрытые лоты if (slot.reward.invasionFragmentHeroRand){ continue; } console.log(slot); console.log(slot.id) console.log(slot.cost.coin[1080]) } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// async function attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills) { 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; } } /*if (!calcBattle.result.win) { // Поражение return; }*/ const endBattle = await Caller.send({ name: 'invasion_bossEnd', args: { id: missionId, result: calcBattle.result, progress: calcBattle.progress, }, }); } ////////////////// async function attackHeroMission(missionId, chapterId, attacHero, pet) { const startBattle = await Caller.send({ name: 'invasion_bossStart', args: { id: missionId, chapterId:chapterId, heroes: attacHero, pet: pet, 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; } } /*if (!calcBattle.result.win) { // Поражение return; }*/ const endBattle = await Caller.send({ name: 'invasion_bossEnd', args: { id: missionId, result: calcBattle.result, progress: calcBattle.progress, }, }); } })();