Skip to content

Instantly share code, notes, and snippets.

@Corvimae
Last active May 3, 2022 15:03
Show Gist options
  • Save Corvimae/335d862120ec849838739fac5ddfc83f to your computer and use it in GitHub Desktop.
Save Corvimae/335d862120ec849838739fac5ddfc83f to your computer and use it in GitHub Desktop.
pokeclicker auto tools

pokeclicker auto tools

installation

  1. get tampermonkey
  2. create a new script
  3. paste what you see below.
  4. refresh pokeclicker

installation for desktop client users

you may be able to use this by opening the dev console using either f12 or ctrl-shift-i and pasting the script into the console. i dont use the desktop client so honestly i have no idea.

// ==UserScript==
// @name May's Pokeclicker Tools
// @namespace http://tampermonkey.net/
// @version 0.7.0
// @description pokeclicker but idle-r
// @author Corvimae
// @match https://www.pokeclicker.com/
// @icon https://www.google.com/s2/favicons?sz=64&domain=pokeclicker.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
const SettingsKeys = {
AUTO_CLICKER_ENABLED: 'AUTO_CLICKER_ENABLED',
AUTO_DUNGEON_ENABLED: 'AUTO_DUNGEON_ENABLED',
AUTO_DUNGEON_PICK_UP_ITEMS_ENABLED: 'AUTO_DUNGEON_PICK_UP_ITEMS_ENABLED',
AUTO_DUNGEON_AUTO_START: 'AUTO_DUNGEON_AUTO_START',
AUTO_GYM_BATTLE_ENABLED: 'AUTO_GYM_BATTLE_ENABLED',
AUTO_GYM_BATTLE_INDEX: 'AUTO_GYM_BATTLE_INDEX',
AUTO_MINE_ENABLED: 'AUTO_MINE_ENABLED',
AUTO_MINE_ALGORITHM: 'AUTO_MINE_ALGORITHM',
AUTO_MINE_ENERGY_FLOOR: 'AUTO_MINE_ENERGY_FLOOR',
AUTO_MINE_ENERGY_FLOOR: 'AUTO_MINE_ENERGY_FLOOR',
AUTO_EGG_QUEUE_ENABLED: 'AUTO_EGG_QUEUE_ENABLED',
};
function formatSettingsKey(key) {
return `POKECLICKER_AUTO_TOOLS_${key}`;
}
function loadSetting(key, defaultValue, onLoad) {
onLoad(window.localStorage.getItem(formatSettingsKey(key)) ?? defaultValue);
}
function loadSettingToInput(key, defaultValue, inputSelector, onLoad) {
loadSetting(key, defaultValue, value => {
document.querySelector(inputSelector).setAttribute('value', value);
onLoad(value);
});
}
function loadSettingToSelect(key, defaultValue, inputSelector, onLoad) {
loadSetting(key, defaultValue, value => {
const option = [...document.querySelector(inputSelector).options].find(item => item.value === value);
if (option) option.selected = true;
onLoad(value);
});
}
function updateSetting(key, value) {
window.localStorage.setItem(formatSettingsKey(key), value);
}
function setButtonEnabledStatus(className, enabled) {
const elem = document.body.querySelector(`.${className}`);
if (!elem) return;
elem.classList.remove('btn-success', 'btn-danger');
if (enabled) {
elem.classList.add('btn-success');
elem.textContent = 'On';
} else {
elem.classList.add('btn-danger');
elem.textContent = 'Off';
}
}
function createToggleSet(className, settingsKey, defaultValue = false, onToggle = x => x) {
const value = { current: null };
function disable() {
onToggle(false);
value.current = false;
updateSetting(settingsKey, false);
setButtonEnabledStatus(className, false);
}
function enable() {
onToggle(true);
value.current = true;
updateSetting(settingsKey, true);
setButtonEnabledStatus(className, true);
}
function toggle() {
if (value.current) {
disable();
} else {
enable();
}
}
function initialize() {
loadSetting(settingsKey, defaultValue, value => {
if (value !== 'false') {
enable();
} else {
disable();
}
});
}
return [value, enable, disable, toggle, initialize];
}
function createIntervalToggleSet(className, func, settingsKey, defaultValue = false, intervalMs = 50) {
const interval = { current: null };
const [value, enable, disable, toggle, initialize] = createToggleSet(
className,
settingsKey,
defaultValue,
enabled => {
if (interval.current) {
clearInterval(interval.current);
interval.current = null;
}
if (enabled) {
interval.current = setInterval(func, intervalMs);
}
}
);
// const interval = { current: null };
// function disable() {
// setButtonEnabledStatus(className, false);
// updateSetting(settingsKey, false);
// if (interval.current) {
// clearInterval(interval.current);
// interval.current = null;
// }
// }
// function enable() {
// if (interval.current) {
// clearInterval(interval.current);
// interval.current = null;
// }
// updateSetting(settingsKey, true);
// setButtonEnabledStatus(className, true);
// interval.current = setInterval(func, intervalMs);
// }
// function toggle() {
// if (interval.current) {
// disable();
// } else {
// enable();
// }
// }
// function initialize() {
// loadSetting(settingsKey, defaultValue, value => {
// if (value !== 'false') {
// enable();
// } else {
// disable();
// }
// });
// }
return [enable, disable, toggle, initialize, interval];
}
function tickAutoclicker() {
if(!App || !App.game) return;
// Route
if (App.game.gameState == GameConstants.GameState.fighting && Battle.enemyPokemon() && Battle.enemyPokemon().health() > 0) {
Battle.clickAttack();
}
// Gym
if (App.game.gameState == GameConstants.GameState.gym && GymBattle.enemyPokemon() && GymBattle.enemyPokemon().health() > 0) {
GymBattle.clickAttack();
}
// Dungeon
if (App.game.gameState == GameConstants.GameState.dungeon && DungeonBattle.enemyPokemon() && DungeonBattle.enemyPokemon().health() > 0) {
DungeonBattle.clickAttack();
}
}
const [enableAutoclicker, disableAutoclicker, toggleAutoclicker, initializeAutoclicker] = createIntervalToggleSet('autoclicker', tickAutoclicker, SettingsKeys.AUTO_CLICKER_ENABLED, true, 10);
const [
autoDungeonPickupItems,
enableAutoDungeonPickupItems,
disableAutoDungeonPickupItems,
toggleAutoDungeonPickupItems,
initializeAutoDungeonPickupItems,
] = createToggleSet('autodungeonpickup', SettingsKeys.AUTO_DUNGEON_PICK_UP_ITEMS_ENABLED, false);
const [
autoDungeonAutoStart,
enableAutoDungeonAutoStart,
disableAutoDungeonAutoStart,
toggleAutoDungeonAutoStart,
initializeAutoDungeonAutoStart,
] = createToggleSet('autodungeonstart', SettingsKeys.AUTO_DUNGEON_AUTO_START, false);
let queue = [];
function tickAutoDungeon() {
if (!App || !App.game) return;
if (App.game.gameState === GameConstants.GameState.town && player.town() instanceof DungeonTown && player.town().dungeon && autoDungeonAutoStart.current) {
DungeonRunner.initializeDungeon(player.town().dungeon);
queue = [];
return;
}
if (App.game.gameState === GameConstants.GameState.dungeon) {
const dimensions = DungeonRunner.map.board().length;
const position = DungeonRunner.map.playerPosition()
if (queue.length === 0) {
// Move to 0, 0
for (let i = position.x; i >= 0; i -= 1) {
queue.push('left');
}
for (let j = position.y; j >= 0; j -= 1) {
queue.push('up');
}
queue.push('right');
for (let x = 0; x < dimensions - 1; x += 1) {
const startOffset = x < Math.floor(dimensions / 2) - 1 ? 1 : 0;
for (let y = startOffset; y < dimensions - 1; y += 1) {
queue.push(x % 2 === 0 ? 'down' : 'up');
}
queue.push('right');
}
}
const tileType = DungeonRunner.map.currentTile().type();
const isSkippableItem = tileType === GameConstants.DungeonTile.chest && !autoDungeonPickupItems.current
if (!DungeonBattle.catching() && !DungeonRunner.fighting() ) {
if (tileType === GameConstants.DungeonTile.empty || tileType === GameConstants.DungeonTile.entrance || isSkippableItem) {
const [head] = queue.splice(0, 1);
if (head) {
switch (head) {
case 'left':
DungeonRunner.map.moveLeft();
break;
case 'right':
DungeonRunner.map.moveRight();
break;
case 'up':
DungeonRunner.map.moveUp();
break;
case 'down':
DungeonRunner.map.moveDown();
break;
}
}
} else {
DungeonRunner.handleClick();
}
}
} else {
queue = [];
}
}
const [enableAutoDungeon, disableAutoDungeon, toggleAutoDungeon, initializeAutoDungeon] = createIntervalToggleSet('autodungeon', tickAutoDungeon, SettingsKeys.AUTO_DUNGEON_ENABLED, false, 50);
const autoGymBattleIndex = { current: 0 };
function tickAutoGymBattle() {
if (!App || !App.game) return;
if (App.game.gameState === GameConstants.GameState.town) {
const gyms = player.town().content.filter(item => item instanceof Gym);
const selectedGym = gyms[autoGymBattleIndex.current] ?? gyms[0];
if (selectedGym) GymRunner.startGym(selectedGym, false)
}
}
function setAutoGymBattleIndex(event) {
autoGymBattleIndex.current = Number(event.target.value);
updateSetting(SettingsKeys.AUTO_GYM_BATTLE_INDEX, event.target.value);
}
const [enableAutoGymBattle, disableAutoGymBattle, toggleAutoGymBattle, initializeAutoGymBattle] = createIntervalToggleSet('autogymbattle', tickAutoGymBattle, SettingsKeys.AUTO_GYM_BATTLE_ENABLED, false, 50);
let activeMineGrid = { current: null };
const currentMineCoordinates = { current: null };
const miningPass = { current: 0 };
const autoMineAlgorithm = { current: 'checkered' };
const autoMineEnergyFloor = { current: 0 };
function setAutoMineAlgorithm(event) {
autoMineAlgorithm.current = event.target.value;
updateSetting(SettingsKeys.AUTO_MINE_ALGORITHM, event.target.value);
}
function setAutoMineEnergyFloor(event) {
autoMineEnergyFloor.current = Number(event.target.value);
updateSetting(SettingsKeys.AUTO_MINE_ENERGY_FLOOR, event.target.value);
}
function tickAutoMine() {
if (!App || !App.game) return;
if (Mine.loadingNewLayer) return;
if (activeMineGrid.current !== Mine.grid) {
// New grid, restart from top.
currentMineCoordinates.current = null;
activeMineGrid.current = Mine.grid;
miningPass.current = 0;
}
if (App.game.underground.energy < Underground.CHISEL_ENERGY + autoMineEnergyFloor.current) return;
const dimensionsX = activeMineGrid.current[0].length;
const dimensionsY = activeMineGrid.current.length;
const { x, y } = currentMineCoordinates.current ?? { x: -1, y: -1};
const tile = currentMineCoordinates.current ? activeMineGrid.current[y][x]() : 0;
if (tile > 0) {
Mine.chisel(y, x); // backwards moment woozy emoji
} else {
if (currentMineCoordinates.current === null) {
currentMineCoordinates.current = { x: 0, y: 0 };
} else {
const isEndOfRow = x + (autoMineAlgorithm.current === 'checkered' ? 2 : 1) >= dimensionsX;
if (isEndOfRow) {
const isEndOfBoard = y + 1 >= dimensionsY;
if (isEndOfBoard) {
currentMineCoordinates.current = { x: miningPass.current === 0 ? 1 : 0, y: 0 };
miningPass.current = miningPass.current === 0 ? 1 : 0;
} else {
const passOffset = miningPass.current === 0 ? 0 : 1;
console.log(passOffset, autoMineAlgorithm.current === 'checkered', y % 2 === 1);
currentMineCoordinates.current = {
x: passOffset + (autoMineAlgorithm.current === 'checkered' && y % 2 === 0 ? 1 : 0),
y: y + 1
};
}
} else {
currentMineCoordinates.current = {
x: x + (autoMineAlgorithm.current === 'checkered' ? 2 : 1),
y,
};
}
}
}
}
const [enableAutoMine, disableAutoMine, toggleAutoMine, initializeAutoMine] = createIntervalToggleSet('automine', tickAutoMine, SettingsKeys.AUTO_MINE_ENABLED, false, 50);
function isPokemonHatchable(partyPokemon) {
if (partyPokemon.breeding || partyPokemon.level < 100) {
return false;
}
if (!BreedingController.filter.search().test(partyPokemon.name)) {
return false;
}
// Check based on category
if (BreedingController.filter.category() >= 0) {
if (partyPokemon.category !== BreedingController.filter.category()) {
return false;
}
}
// Check based on shiny status
if (BreedingController.filter.shinyStatus() >= 0) {
if (+partyPokemon.shiny !== BreedingController.filter.shinyStatus()) {
return false;
}
}
// Check based on native region
if (BreedingController.filter.region() > -2) {
if (PokemonHelper.calcNativeRegion(partyPokemon.name) !== BreedingController.filter.region()) {
return false;
}
}
// Check if either of the types match
const type1 = BreedingController.filter.type1() > -2 ? BreedingController.filter.type1() : null;
const type2 = BreedingController.filter.type2() > -2 ? BreedingController.filter.type2() : null;
if (type1 !== null || type2 !== null) {
const { type: types } = pokemonMap[partyPokemon.name];
if ([type1, type2].includes(PokemonType.None)) {
const type = (type1 == PokemonType.None) ? type2 : type1;
if (!BreedingController.isPureType(partyPokemon, type)) {
return false;
}
} else if ((type1 !== null && !types.includes(type1)) || (type2 !== null && !types.includes(type2))) {
return false;
}
}
return true;
}
function tickAutoHatcheryQueue() {
if (!App || !App.game) return;
const queueSize = App.game.breeding.queueList().length;
const queueSlots = 2; // App.game.breeding.queueSlots();
if (queueSize < queueSlots) {
const hatcheryList = [...App.game.party.caughtPokemon].sort(PartyController.compareBy(Settings.getSetting('hatcherySort').observableValue(), Settings.getSetting('hatcherySortDirection').observableValue()));
let offset = 0;
for (let i = 0; i < queueSlots - queueSize + offset; i += 1) {
const pokemon = hatcheryList[i];
if (!pokemon) return;
if (isPokemonHatchable(pokemon)) {
App.game.breeding.addPokemonToHatchery(pokemon);
} else {
offset += 1;
}
}
}
}
const [enableAutoHatcheryQueue, disableAutoHatcheryQueue, toggleAutoHatcheryQueue, initializeAutoHatcheryQueue] = createIntervalToggleSet('autohatcheryqueue', tickAutoHatcheryQueue, SettingsKeys.AUTO_EGG_QUEUE_ENABLED, true, 50);
function createToolUIRow(label, className, majorFeature, rightCell) {
const trElem = document.createElement('tr');
const labelElem = document.createElement('td');
const buttonContainerElem = document.createElement('td');
labelElem.classList.add(className + '-label', 'text-left', majorFeature ? 'font-weight-bold' : 'font-weight-normal');
labelElem.textContent = label;
buttonContainerElem.classList.add('p-1');
buttonContainerElem.appendChild(rightCell);
trElem.appendChild(labelElem);
trElem.appendChild(buttonContainerElem);
return trElem;
}
function createToolUIToggleRow(label, className, majorFeature, onClick) {
const buttonElem = document.createElement('button');
buttonElem.classList.add(className, 'btn', 'btn-block');
buttonElem.onclick = onClick;
return createToolUIRow(label, className, majorFeature, buttonElem);
}
function createToolUINumberRow(label, className, majorFeature, onChange, defaultValue = 0) {
const inputElem = document.createElement('input');
inputElem.classList.add(className, 'form-control');
inputElem.setAttribute('type', 'number');
inputElem.setAttribute('value', defaultValue);
inputElem.onchange = onChange;
return createToolUIRow(label, className, majorFeature, inputElem);
}
function createToolUISelectRow(label, className, majorFeature, onChange, options) {
const selectElem = document.createElement('select');
selectElem.classList.add(className, 'form-control');
selectElem.onchange = onChange;
options.forEach(([label, value]) => {
const optionElem = document.createElement('option');
optionElem.setAttribute('value', value);
optionElem.textContent = label;
selectElem.appendChild(optionElem);
});
return createToolUIRow(label, className, majorFeature, selectElem);
}
function createControlBar() {
const controlBarElem = document.createElement('div');
controlBarElem.classList.add('control-bar', 'card', 'sortable', 'border-secondary', 'mb-3', 'sortable-chosen');
const controlBarTitle = document.createElement('div');
controlBarTitle.classList.add('card-header', 'p-0');
controlBarTitle.setAttribute('data-toggle', 'collapse');
const controlBarTitleText = document.createElement('span');
controlBarTitleText.textContent = 'Auto Tools';
controlBarTitle.appendChild(controlBarTitleText);
const tableElem = document.createElement('table');
tableElem.classList.add('table');
tableElem.setAttribute('width', '100%');
const tableBodyElem = document.createElement('tbody');
tableBodyElem.appendChild(createToolUIToggleRow('Auto Clicker', 'autoclicker', true, toggleAutoclicker));
tableBodyElem.appendChild(createToolUIToggleRow('Auto Dungeon', 'autodungeon', true, toggleAutoDungeon));
tableBodyElem.appendChild(createToolUIToggleRow('Pick up items?', 'autodungeonpickup', false, toggleAutoDungeonPickupItems));
tableBodyElem.appendChild(createToolUIToggleRow('Auto start dungeon?', 'autodungeonstart', false, toggleAutoDungeonAutoStart));
tableBodyElem.appendChild(createToolUIToggleRow('Auto Gym Battle', 'autogymbattle', true, toggleAutoGymBattle));
tableBodyElem.appendChild(createToolUISelectRow('Elite 4 Selection', 'autogymbattlee4', false, setAutoGymBattleIndex, [
['1', '0'],
['2', '1'],
['3', '2'],
['4', '3'],
['Champion', '4'],
]));
tableBodyElem.appendChild(createToolUIToggleRow('Auto Mine', 'automine', true, toggleAutoMine));
tableBodyElem.appendChild(createToolUISelectRow('Mine Algorithm', 'autominealgorithm', false, setAutoMineAlgorithm, [
['Checkered', 'checkered'],
['Sequential', 'sequential'],
]));
tableBodyElem.appendChild(createToolUINumberRow('Min. Energy', 'automineenergyfloor', false, setAutoMineEnergyFloor));
tableBodyElem.appendChild(createToolUIToggleRow('Auto Egg Queue', 'autohatcheryqueue', true, toggleAutoHatcheryQueue));
tableElem.appendChild(tableBodyElem);
controlBarElem.appendChild(controlBarTitle);
controlBarElem.appendChild(tableElem);
document.querySelector('#left-column').appendChild(controlBarElem);
}
const gameStartInterval = { current: null };
gameStartInterval.current = setInterval(() => {
if (App && App.game && document.querySelector('#left-column')) {
clearInterval(gameStartInterval.current);
createControlBar();
setTimeout(() => {
initializeAutoclicker();
initializeAutoDungeon();
initializeAutoDungeonPickupItems();
initializeAutoDungeonAutoStart();
initializeAutoMine();
initializeAutoGymBattle();
initializeAutoHatcheryQueue();
loadSettingToSelect(SettingsKeys.AUTO_GYM_BATTLE_INDEX, 1, '.autogymbattlee4', index => {
autoGymBattleIndex.value = Number(index);
});
loadSettingToSelect(SettingsKeys.AUTO_MINE_ALGORITHM, 'checkered', '.autominealgorithm', algorithm => {
autoMineAlgorithm.current = algorithm;
});
loadSettingToInput(SettingsKeys.AUTO_MINE_ENERGY_FLOOR, 0, '.automineenergyfloor', value => {
autoMineEnergyFloor.current = Number(value);
});
}, 0);
}
}, 50);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment