Greasy Fork is available in English.

【脚本停止维护 有问题自行解决】宝可梦点击(Poke Clicker)辅助脚本 自动孵蛋模块

全自动高效孵化宝可梦、宝可梦蛋、化石

// ==UserScript==
// @name         【脚本停止维护 有问题自行解决】宝可梦点击(Poke Clicker)辅助脚本 自动孵蛋模块
// @namespace    PokeClickerHelper
// @version      1.0
// @description  全自动高效孵化宝可梦、宝可梦蛋、化石
// @author       DreamNya
// @match        https://www.pokeclicker.com
// @match        https://g8hh.github.io/pokeclicker/
// @match        https://pokeclicker.g8hh.com
// @match        https://yx.g8hh.com/pokeclicker/
// @match        https://dreamnya.github.io/pokeclicker/
// @icon         data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/319hf99fYX/fX2F/319hf8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////99fYX/fX2F/319hf8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////wAAAP8AAAD/fX2F/319hf99fYX/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////8AAAD/AAAA/wAAAP99fYX/fX2F/wAAAP8AAAD/AAAA/319hf8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/HBT//xwU//8AAAD//////319hf8AAAD/Dgim/w4Ipv8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAD/HBT//xwU//8cFP//HBT//wAAAP8AAAD/Dgim/w4Ipv8OCKb/Dgim/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/xwU//8cFP//HBT//xwU/44cFP//HBT//xwU//8cFP//Dgim/w4Ipv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/HBT//xwU/47/////HBT/jhwU//8cFP//HBT//w4Ipv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xwU//8cFP//HBT/jhwU//8OCKb/Dgim/w4Ipv8OCKb/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/xwU//8OCKb/Dgim/w4Ipv8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAPw/AADwDwAA4AcAAOAHAADAAwAAwAMAAMADAADAAwAA4AcAAOAHAADwDwAA/D8AAP//AAD//wAA//8AAA==
// @grant        none
// @license      MIT
// @run-at       document-end
// ==/UserScript==
/* global App, $, PokeClickerHelper, Underground, PartyController, GameConstants, player, ItemList, CaughtStatus, PokemonHelper, Settings, pokemonMap, PokemonCategories, SortOptionConfigs */

if (typeof PokeClickerHelper == typeof void 0) {
    alert('宝可梦点击(Poke Clicker)辅助脚本 自动孵蛋模块加载失败\n\n未找到核心模块,需要先安装核心模块才可正常使用\n\n论坛主页:https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=3842')
    window.open("https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=3842")
    return
}


//UI相关
PokeClickerHelper.UIDOM.push(`
<div id="PokeClickerHelperBreeding" class="custom-row">
    <div>
        <div class="form-row mb-1">
            <div class="col-auto align-self-center">
                <label class="m-0">自动培育:</label>
            </div>
            <div class="col">
                <button id="PokeClickerHelperToggleBreeding" class="btn btn-sm btn-primary mr-1" value="开始">开始</button>
                <label class="form-check-label ml-4 mr-1" title="降序:从大到小&#10;升序:从小到大"><input id="PokeClickerHelperBreedingInvert" type="checkbox" value="false">升序</label>
                <label class="form-check-label ml-4 mr-1" title="使用新排序算法减少孵化计算量 加快孵化效率&#10;测试功能 不保证无BUG 炸档不负责&#10;使用前强烈建议备份存档"><input id="PokeClickerHelperBreedingNewAlg" type="checkbox" value="false">新排序算法</label>
                <label class="form-check-label ml-4 d-none"><input id="PokeClickerHelperBreedingUncaught" type="checkbox" value="false">只孵化未捕捉</label>
            </div>
        </div>
        <div class="form-row">
            <div class="col">
                <label>孵化类型</label>
                <select id="PokeClickerHelperBreedingType" class="custom-select">
                    <option value="BreadingPokemon">宝可梦</option>
                    <option value="BreadingEgg">蛋</option>
                    <option value="BreadingFossil">化石</option>
                </select>
            </div>
            <div class="col">
                <label>排序</label>
                <select id="PokeClickerHelperBreedingSortOption" class="custom-select">

                </select>
            </div>
            <div class="col">
                <label>闪光状态</label>
                <select id="PokeClickerHelperBreedingShiny" class="custom-select">
                    <option value="all">全部</option>
                    <option value="true">闪光</option>
                    <option value="false">非闪光</option>
                </select>
            </div>
            <div class="col" id="PokeClickerHelperBreedingRegionDebuffDiv">
                <label>地区减益</label>
                <select id="PokeClickerHelperBreedingRegionDebuff" class="custom-select">
                    <option value="-1">无</option>
                    <option value="0">关东地区</option>
                    <option value="1">城都地区</option>
                    <option value="2">丰缘地区</option>
                    <option value="3">神奥地区</option>
                    <option value="4">合众地区</option>
                    <option value="5">卡洛斯地区 </option>
                    <option value="6">阿罗拉地区</option>
                    <option value="7">伽勒尔地区</option>
                    <option value="8">最终</option>
                </select>
            </div>
        </div>
        <div class="mt-2 mb-1 border-top border-secondary opacity-25"></div>
        <div class="form-row" id="PokeClickerHelperBreedingRow2">
            <div class="col-3">
                <label>孵化属性1</label>
                <select id="PokeClickerHelperBreedingTypeFilter1" class="custom-select" title="选择后仅孵化第一第二属性完全符合的宝可梦"></select>
              </div>
          <div class="col-3">
              <label>孵化属性2</label>
              <select id="PokeClickerHelperBreedingTypeFilter2" class="custom-select" title="选择后仅孵化第一第二属性完全符合的宝可梦"></select>
            </div>
            <div class="col-3"><label>优先类别</label><select id="PokeClickerHelperBreedingPriority" class="custom-select" title="无视其他设定 能够孵化时优先孵化该类别宝可梦"></select></div>
        </div>
    </div>
</div>
<div class="mt-2 mb-1 border-top border-secondary"></div>
    `)
const fuc = () => {
    //非挑战模式区域减益隐藏
    if (!App.game.challenges.list.regionalAttackDebuff.active()) $('#PokeClickerHelperBreedingRegionDebuffDiv').addClass('invisible')

    //读取孵化属性标签
    $('[name="breedingTypeFilter1"] option').clone().each((_, i) => $(i).attr('data-bind', null).attr('selected', null)).appendTo($("#PokeClickerHelperBreedingTypeFilter1,#PokeClickerHelperBreedingTypeFilter2"))

    //读取孵蛋类别
    PokemonCategories.categories().map(i => i.name()).forEach((i, index) => {
        $('#PokeClickerHelperBreedingPriority').append(`<option value="${index}">${i}</option>`)
    })

    //读取孵蛋排序
    Object.values(SortOptionConfigs).forEach(({text},index) => {
        $('#PokeClickerHelperBreedingSortOption').append(`<option value="${index}">${text}</option>`)
    })
}

const listener = () => {
    $('#PokeClickerHelperToggleBreeding').on('click', function () {
        if (this.value == '结束') {
            PokeClickerHelper.restoreHook(PokeClickerHelper.hookGame.breeding) //还原hook方法
            $('#PokeClickerHelperToggleBreeding').text(this.value = '开始')
        } else {
            PokeClickerHelper.applyHook(PokeClickerHelper.hookGame.breeding) //应用hook方法
            $('#PokeClickerHelperToggleBreeding').text(this.value = '结束')
        }
    })

    $("#PokeClickerHelperBreedingType").on('change', function () {
        const isPokemon = this.value == 'BreadingPokemon'
        $("label:has(#PokeClickerHelperBreedingInvert)").toggleClass('d-none', !isPokemon)
        $("label:has(#PokeClickerHelperBreedingNewAlg)").toggleClass('d-none', !isPokemon)
        $("label:has(#PokeClickerHelperBreedingUncaught)").toggleClass('d-none', isPokemon)
        $("#PokeClickerHelperBreedingType").parent().siblings().find('select').attr('disabled', !isPokemon)
        $("#PokeClickerHelperBreedingRow2 select").attr('disabled', !isPokemon)
    })
}
PokeClickerHelper.UICustomFuc.push(fuc);
PokeClickerHelper.UIlistener.push(listener);

//暴露对象方法到全局
const BreedingHelper = {};
PokeClickerHelper.BreedingHelper = BreedingHelper;

//满步数自动孵蛋、有空位自动孵蛋 hook方法
const autoHatch = function (Game) {
    const replacement = [
        ['this._queueList().length && ', ''],
        [/^/, "PokeClickerHelper.BreedingHelper.AutoBreeding();"],
    ];
    PokeClickerHelper.HookFuc(Game.breeding, 'progressEggs', replacement, 'amount');
    PokeClickerHelper.restoreHook(PokeClickerHelper.hookGame.breeding)
}
PokeClickerHelper.addHook('Game', autoHatch)


let newAlgLastOptions
let newAlgLastPokemonArr = []

//委托函数 利用语法糖配合解构减少冗余代码
BreedingHelper.AutoBreeding = () => {
    if (!App.game.breeding.hasFreeEggSlot()) return
    let value = [...document.querySelectorAll('#PokeClickerHelperBreeding select')].map(i => i.value)
    const newAlg = document.querySelector("#PokeClickerHelperBreedingNewAlg").checked
    if (newAlg) {
        value.push(true)
        const newAlgOptions = value.join()
        if (newAlgOptions == newAlgLastOptions) value.push(true)
        newAlgLastOptions = newAlgOptions
    }
    if (value.length > 0) BreedingHelper[value.shift()](value)
}

//利用解构减少代码
//孵宝可梦
BreedingHelper.BreadingPokemon = ([sortOption, shiny, region, type1, type2, Priority, newAlg = false, newAlgMark = false]) => {
    if (shiny != 'all') shiny = JSON.parse(shiny)

    if (newAlg && newAlgMark) {
        for (const pokemon of newAlgLastPokemonArr) {
            if (!App.game.breeding.hasFreeEggSlot()) return
            if (pokemon.shiny != shiny) break
            if (pokemon.level >= 100 && !pokemon.breeding) {
                //console.log('新算法孵宝可梦',pokemon.displayName,pokemon)
                App.game.breeding.addPokemonToHatchery(pokemon)
            }
        }
    }

    if (!App.game.breeding.hasFreeEggSlot()) return

    const direction = !document.querySelector("#PokeClickerHelperBreedingInvert").checked

    let typeFlag
    if (type1 + type2 != '-2-2') {
        typeFlag = true
        type1 = type1 * 1
        type2 = type2 * 1
        if (type1 == -1) type1 = void 0
        if (type2 == -1) type2 = void 0
    }
    const pokemonArr = App.game.party.caughtPokemon

    //优先孵化 不排序
    const pokemonPriorityArr = (Priority != '0' && (!newAlg || (newAlg && !newAlgMark) || (newAlg && newAlgMark && newAlgLastPokemonArr.length == 0))) ? pokemonArr.filter(i => i.category == Priority) : []
    for (const pokemon of pokemonPriorityArr) {
        if (!App.game.breeding.hasFreeEggSlot()) return (newAlgLastPokemonArr = pokemonPriorityArr)//优先孵化满槽后直接中断不再进行排序 减少计算量
        if (pokemon.level >= 100 && !pokemon.breeding) {
            //console.log('优先孵宝可梦',pokemon.displayName,pokemon)
            App.game.breeding.addPokemonToHatchery(pokemon)
        }
    }
    if (!App.game.breeding.hasFreeEggSlot()) return

    //普通孵化 排序
    const pokemonFilterArr = shiny == 'all' && !typeFlag ? pokemonArr : pokemonArr.filter(i => {
        let flag = true
        if (shiny != 'all') flag = i.shiny == shiny
        if (flag && typeFlag) {
            const pokemonType = pokemonMap[i.name].type
            flag = (type1 < 0 || (type1 >= 0 && pokemonType.includes(type1))) && (type2 < 0 || (type2 >= 0 && pokemonType.includes(type2)))
        }
        return flag
    })
    pokemonFilterArr.sort(PartyController.compareBy(sortOption * 1, direction, region * 1))

    for (const pokemon of pokemonFilterArr) {
        if (!App.game.breeding.hasFreeEggSlot()) return (newAlgLastPokemonArr = Priority == '0' ? pokemonFilterArr : pokemonPriorityArr)
        if (pokemon.level >= 100 && !pokemon.breeding) {
            //console.log('孵宝可梦',pokemon.displayName,pokemon)
            App.game.breeding.addPokemonToHatchery(pokemon)
        }
    }
}

//孵蛋
BreedingHelper.BreadingEgg = () => {
    let avaiableEgg = Object.keys(GameConstants.EggItemType).filter(e => isNaN(e)).filter(x => player._itemList[x]());
    const onlyUncaught = document.querySelector("#PokeClickerHelperBreedingUncaught").value == 'true'

    if (onlyUncaught) avaiableEgg = avaiableEgg.filter(i => ItemList[i].getCaughtStatus() == CaughtStatus.NotCaught)
    avaiableEgg = avaiableEgg.flatMap(i => Array(Math.min(player._itemList[i](), 4)).fill(i))

    for (const egg of avaiableEgg) {
        if (!App.game.breeding.hasFreeEggSlot()) break
        ItemList[egg].use();
    }
}

//孵化石
BreedingHelper.BreadingFossil = () => {
    let avaiableFossil = Object.keys(GameConstants.FossilToPokemon).map(f => player.mineInventory().find(i => i.name == f)).filter(f => f ? f.amount() : false)
    const onlyUncaught = document.querySelector("#PokeClickerHelperBreedingUncaught").value == 'true'
    avaiableFossil = avaiableFossil.filter(i => {
        let flag = PokemonHelper.calcNativeRegion(GameConstants.FossilToPokemon[i.name]) <= player.highestRegion()
        if (onlyUncaught) flag = flag && PartyController.getCaughtStatusByName(GameConstants.FossilToPokemon[i.name]) == CaughtStatus.NotCaught
        return flag
    })
    avaiableFossil = avaiableFossil.map(i => Array(i.amount()).fill(i.id)).flat()

    for (const fossil of avaiableFossil) {
        if (!App.game.breeding.hasFreeEggSlot()) break
        Underground.sellMineItem(fossil)
    }
}