// ==UserScript==
// @name 自动孵蛋模块
// @namespace PokeClickerHelper
// @version 0.1.2
// @description 全自动高效孵化宝可梦、宝可梦蛋、化石
// @author 超超
// @match https://pokemon.ccox.cc/
// @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://scriptcat.org/script-show-page/1228')
window.open("https://scriptcat.org/script-show-page/1228")
return
}
//UI相关
PokeClickerHelper.UIDOM.push(`
`)
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(``)
})
//读取孵蛋排序
Object.values(SortOptionConfigs).forEach(({text},index) => {
$('#PokeClickerHelperBreedingSortOption').append(``)
})
}
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)
}
}