您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Makes it easier.
// ==UserScript== // @name MoshMages' Cookie Clicker Mods // @version 1.10.3.2 // @description Makes it easier. // @author [email protected] // @match *orteil.dashnet.org/cookieclicker/* // @grant none // @namespace https://gist.github.com/moshmage/792ac013a8fb0b23d39f491261ebdb90 // ==/UserScript== (() => { const options = { enable: false, enableQueue: false, pauseQueue: true, saveQueue: false, autoBuyUpgrades: true, autoClickShimmers: true, avoidWrathCookie: false, disableBuyIfBuffs: true, killWrinkles: true, killGoldenWrinkles: false, preventBuildingDeBuff: true, preventClot: true, preventRuin: true, tickSpeedMs: 50, clickCookie: true, } setTimeout(() => { const bigCookie = document.querySelector(`#bigCookie`); const centerSection = document.querySelector(`#centerArea`); const game = document.querySelector(`#game`); const comments = document.querySelector(`#comments`); const _Game = window.Game || {tooltip: {}, shimmers: [], wrinklers: [], buffs: [], goldenCookieBuildingBuffs: {}, Has: (s) => {}, hasGod: (s) => {}, ObjectsById: [], cookies: 0, buyMode: 1, buyBulk: 1}; const wrinkleEl = document.createElement(`div`); const wrinklerScoreToggle = document.createElement(`div`); const queueData = []; const saveQData = () => { options.saveQueue && localStorage.setItem(`acmq`, JSON.stringify(queueData)); } const loadQData = () => options.saveQueue && queueData.push(... JSON.parse(localStorage.getItem(`acmq`) || [])); const unwantedEffects = Object.entries(_Game.goldenCookieBuildingBuffs).map(([name, [good, bad]]) => bad.toLowerCase()); const killWrinkle = (wrinkle) => wrinkle.hp-- && wrinkle.hp > 0 && killWrinkle(wrinkle); const updateWrinkleScore = () => { const score = _Game.wrinklers .filter(w => w.sucked > 0) .map(w => !w.type && w.sucked || w.sucked * 3) .reduce(((p, c) => p+c), 0); let percent = 10; if (_Game.Has(`Wrinklerspawn`)) percent += 5; if (_Game.Has(`Sacrilegious corruption`)) percent += 5; if (_Game.hasGod) { const level = _Game.hasGod(`scorn`); if (level) percent += +(Math.abs(level - 4) * .05).toFixed(2).substring(2); } wrinkleEl.querySelector(`div`).innerHTML = `${window.Beautify(score + ((score/100)*percent))}<br/><span style="font-size:50%">wrinkled cookies</span>`; } const killWrinkles = () => { _Game .wrinklers .filter(({close, phase, hp}) => phase && close === 1 && hp) .forEach(killWrinkle); } const tickAction = () => { if (!options.enable) return; if (options.clickCookie) bigCookie.click() const buyThing = (selector) => { const things = document.querySelectorAll(selector); if (things.length) things[0].click(); } if (options.autoClickShimmers) _Game.shimmers.forEach(shimmer => (!options.avoidWrathCookie || options.avoidWrathCookie && !shimmer.wrath) && shimmer.pop()); const hasWrinklers = _Game.wrinklers.some(w => w.phase > 0); if (hasWrinklers) { if (options.killWrinkles) killWrinkles(); else { updateWrinkleScore(); if (wrinklerScoreToggle.style.display !== `block`) wrinklerScoreToggle.style.display = `block`; } } else if (wrinklerScoreToggle.style.display === `block`) { wrinklerScoreToggle.style.display = `none`; wrinkleEl.style.display = `none`; } const buffs = document.querySelectorAll(`#buffs *`).length; if (!options.disableBuyIfBuffs || options.disableBuyIfBuffs && !buffs) { if (options.autoBuyUpgrades) buyThing(`#upgrades .enabled`); if (options.enableQueue && !options.pauseQueue && queueData.length) { const {amount, mode, id, unique} = queueData[0]; const product = _Game.ObjectsById.find(o => o.id === id); const el = document.querySelector(`[data-id="${unique}"]`); if (product) { let acted = false; if (mode === -1) (acted = true, product.sell(amount)); else if (mode === 1 && product.getSumPrice(amount) < _Game.cookies) (acted = true, product.buy(amount)) if (acted) el.removeFromQueue(undefined, unique); } else el.removeFromQueue(null, unique); } } setTimeout(() => tickAction(), options.tickSpeedMs); } const onoff = (pointer) => pointer && `ON` || `OFF`; const makeListingOption = (name, desc, id, key, cb) => { const listing = document.createElement(`div`); listing.classList.add(`listing`); const option = document.createElement(`a`); option.classList.add(`option`); if (key) { if (!options[key]) option.classList.add(`off`); else option.classList.remove(`off`); } option.setAttribute(`id`, id); option.textContent = `${name} ${key && onoff(options[key]) || ``}`; option.addEventListener(`click`, (ev) => { if (key) { options[key] = !options[key]; option.textContent = `${name} ${onoff(options[key])}`; localStorage.setItem(`acmoptions`, JSON.stringify(options)); if (!options[key]) option.classList.add(`off`); else option.classList.remove(`off`); } if (cb) cb(ev, key); }); const label = document.createElement(`label`); label.textContent = desc && `(${desc})` || ``; if (name) listing.appendChild(option); if (desc) listing.appendChild(label); return listing; } const makeSlider = (name, min, max, increment, key) => { const listing = document.createElement(`div`); listing.classList.add(`listing`); const slider = document.createElement(`div`); slider.classList.add(`sliderBox`); const label = document.createElement(`div`); label.style.float = `left`; label.textContent = name; const value = document.createElement(`div`); value.style.float = `right`; value.textContent = options[key]; const option = document.createElement(`input`); option.setAttribute(`type`, `range`); option.setAttribute(`min`, min); option.setAttribute(`max`, max); option.setAttribute(`step`, increment); option.style.clear = `both`; option.value = options[key]; option.addEventListener(`change`, (ev) => { options[key] = +ev.target.value; localStorage.setItem(`acmoptions`, JSON.stringify(options)); value.textContent = options[key]; }); slider.appendChild(label); slider.appendChild(value); slider.appendChild(option); listing.appendChild(slider); return listing; } const makeTitle = (title) => { const element = document.createElement(`div`) element.classList.add(`title`); element.textContent = title; return element; } const makeAscensionButton = (text, style = {}) => { style = {position: `absolute`, fontSize: `14px`, fontWeight: `bold`, fontFamily: `Georgia`, color: `#fff`, textShadow: `0px -1px 1px #09f,0px 1px 1px #f04`, cursor: `pointer`, zIndex: `1000`, display: `block`, ...style}; const button = document.createElement(`div`); button.classList.add(`roundedPanel`); Object.entries(style).forEach(([key, val]) => button.style[key] = val); button.textContent = text; return button; } const makePage = (title = ``, buttonText = ``, buttonStyle = {}) => { const style = {display: `none`, position: `absolute`, zIndex: `100`, left: `0`, right: `0`, top: `0`, bottom: `0`}; const page = document.createElement(`div`); page.setAttribute(`id`, buttonText); Object.entries(style).forEach(([key, val]) => page.style[key] = val); const closePageButton = document.createElement(`div`); closePageButton.classList.add(`close`, `menuClose`); closePageButton.textContent = `x`; closePageButton.setAttribute(`data-close`, buttonText); const pageTitle = document.createElement(`div`); pageTitle.classList.add(`section`); pageTitle.textContent = title; const openPage = () => { const close = centerSection.querySelector(`.close:not([data-close="${buttonText}"])`); if (close) close.click(); game.classList.add(`onMenu`); page.style.display = `block`; } const closePage = (removeMenu = true) => { if (removeMenu) game.classList.remove(`onMenu`); page.style.display = `none`; } closePageButton.addEventListener(`click`, closePage); const pageButton = makeAscensionButton(buttonText, buttonStyle); pageButton.setAttribute(`data-toggle`, buttonText); pageButton.addEventListener(`click`, () => { if (page.style.display === `block`) closePage(); else openPage(); }); comments.appendChild(pageButton); comments .querySelectorAll(`.button`) .forEach(el => el.addEventListener(`click`, () => closePage(false))); page.appendChild(closePageButton); page.appendChild(pageTitle); page.closeEl = closePageButton; page.pageButtonEl = pageButton; page.openPage = openPage; return page; } const makeSubSection = (title = ``) => { const subsection = document.createElement(`div`); subsection.classList.add(`subsection`); subsection.appendChild(makeTitle(title)); return subsection; } const makeQueuePage = () => { const queueEl = makePage(`Product buy queue`, `Queue`, {top: `4.5rem`, left: `10rem`}); const queueHelp = makeSubSection(`Options`); const queueListEl = makeSubSection(`Queue`); queueHelp.appendChild(makeListingOption(`Pause`, `While paused, no action will be taken`, ``, `pauseQueue`)); queueHelp.appendChild(makeListingOption(`Constant queue`, `Will keep the queue list between sessions, using localStorage`, ``, `saveQueue`)); const buyCostEl = makeListingOption(``, `Buy cost`); const sellWorthEl = makeListingOption(``, `Sell worth`); queueListEl.appendChild(buyCostEl) queueListEl.appendChild(sellWorthEl) queueEl.appendChild(queueHelp); queueEl.appendChild(queueListEl); const updateCostTitles = () => { const buyCost = queueData.filter(e => e.mode === 1).map(e => getProduct(e.productIndex).getSumPrice(e.amount)).reduce((p, c) => p+c, 0); const sellWorth = queueData.filter(e => e.mode === -1).map(e => getProduct(e.productIndex).getSumPrice(e.amount)).reduce((p, c) => p+c, 0); const updateCost = (el, str, amount) => { el.querySelector(`label`).textContent = `${str}: ${window.Beautify(amount)} cookies` if (!amount) el.style.display = `none`; else el.style.display = `block`; } updateCost(buyCostEl, `Buy cost`, buyCost); updateCost(sellWorthEl, `Sell worth`, sellWorth) } const qEntry = (amount, mode, product, unique, cb) => { unique = unique || Math.random() * +new Date(); const name = product.name; const action = mode === -1 && `sell` || `buy`; const worth = window.Beautify(product.getSumPrice(amount)); const entry = makeListingOption(name, `${action} ${amount}, worth ${worth} cookies`, ``, ``, cb); entry.setAttribute(`data-product-id`, product.id); entry.setAttribute(`data-id`, unique.toString()); return entry; } const getProduct = (index) => _Game.ObjectsById[index]; const removeFromQueue = (ev, id) => { id = id || ev.target.parentElement.getAttribute(`data-id`); const index = queueData.findIndex(({unique}) => unique === id); if (index > -1) queueData.splice(index, 1); if (options.saveQueue) saveQData(); queueListEl.removeChild(document.querySelector(`[data-id="${id}"]`)); updateCostTitles(); } const makeEntry = (product, unique) => { const entry = qEntry(_Game.buyBulk, _Game.buyMode, product, unique, removeFromQueue); entry.removeFromQueue = removeFromQueue; return entry; } const addToQueue = (productIndex) => { const product = getProduct(productIndex); const unique = (Math.random() * +new Date()).toFixed(0); queueListEl.appendChild(makeEntry(product, unique)); queueData.push({unique, name: product.name, mode: _Game.buyMode, amount: _Game.buyBulk, id: product.id, productIndex}); if (options.saveQueue) saveQData(); updateCostTitles(); } const createQButton = (productIndex) => { const button = makeAscensionButton(`+`, {left: `1rem`, top: `.1rem`, transform: `scale(.7)`}); button.setAttribute(`q`, `button`); button.addEventListener(`click`, (ev) => { ev.cancelBubble = true; ev.preventDefault(); addToQueue(productIndex); queueEl.openPage(); }); return button; } document.querySelectorAll(`#products .product`) .forEach((el, i) => el.appendChild(createQButton(i))); if (options.saveQueue) { loadQData(); queueData.forEach((entry, i) => { const productIndex = _Game.ObjectsById.findIndex((o) => o.id === entry.id); if (productIndex < 0) queueData.splice(i, 1); queueListEl.appendChild(makeEntry(getProduct(productIndex), entry.unique)); }); } centerSection.appendChild(queueEl); } const buildUI = () => { const startTickAction = () => { if (options.enable) tickAction(); } const toggleQueueUI = () => { const toggleDisplay = (el) => el.style.display = !options.enableQueue && `none` || `block`; toggleDisplay(document.querySelector(`[data-toggle="Queue"]`)); document.querySelectorAll(`[q]`).forEach(toggleDisplay); } Object.assign(options, JSON.parse(localStorage.getItem(`acmoptions`) || `{}`)); const modMenu = makePage(`MoshMages' Madness`, `Mod`, {top: `4.5rem`, right: `auto`, left: `6rem`}); const subsection = makeSubSection(`Global`); subsection.appendChild(makeListingOption(`Enable`, `enable/disable auto click abilities`, `enable-madness`, `enable`, function() { startTickAction() })) subsection.appendChild(makeSlider(`Tick speed (ms)`, 50, 1000, 10, `tickSpeedMs`)); subsection.appendChild(makeTitle(`Auto click`)); subsection.appendChild(makeListingOption(`Big cookie`, `click the big cookie`, `enable-cookie-click`, `clickCookie`)); subsection.appendChild(makeListingOption(`Shimmers`, ``, `auto-shimmer`, `autoClickShimmers`)); subsection.appendChild(makeListingOption(`Avoid wrath cookies`, ``, `auto-shimmer`, `avoidWrathCookie`)); subsection.appendChild(makeTitle(`Auto buy`)); subsection.appendChild(makeListingOption(`Wait for buff end`, `will not buy if buffs are active`, `auto-buff-wait`, `disableBuyIfBuffs`)); subsection.appendChild(makeListingOption(`Product queue`, `enable product buy queue`, `auto-build`, `enableQueue`, function() { toggleQueueUI(); })); subsection.appendChild(makeListingOption(`Upgrades`, `buy first upgrade available`, `auto-upgrade`, `autoBuyUpgrades`)); subsection.appendChild(makeTitle(`Wrinklers`)) subsection.appendChild(makeListingOption(`Kill wrinklers`, ``, `auto-wrinkler`, `killWrinkles`)); subsection.appendChild(makeListingOption(`Kill Golden wrinklers`, ``, `auto-golden-wrinkler`, `killGoldenWrinkles`)); subsection.appendChild(makeTitle(`Debuffs`)); subsection.appendChild(makeListingOption(`Prevent clot`, ``, `auto-avoid-clot-ruin`, `preventClot`)); subsection.appendChild(makeListingOption(`Prevent ruin`, ``, `auto-avoid-ruin`, `preventRuin`)); subsection.appendChild(makeListingOption(`Prevent building debuffs`, ``, `auto-avoid-building-debuffs`, `preventBuildingDeBuff`)); modMenu.appendChild(subsection); centerSection.appendChild(modMenu); modMenu.pageButtonEl.click(); wrinkleEl.classList.add(`title`); wrinkleEl.setAttribute(`id`, `wrinkle-bits`); wrinkleEl.style.bottom = `10%` wrinkleEl.style.textAlign = `center`; wrinkleEl.style.position = `absolute`; wrinkleEl.style.width = `100%`; wrinkleEl.style.background = `rgba(0,0,0,.4)`; wrinkleEl.style.padding = `5px 0 5px 0`; wrinkleEl.style.zIndex = `2000`; wrinkleEl.style.display = `none`; wrinkleEl.appendChild(document.createElement(`div`)); const wrinklePop = document.createElement(`a`); wrinklePop.classList.add(`option`); wrinklePop.textContent = `exterminate`; wrinklePop.addEventListener(`click`, () => { killWrinkles(); }); const wrinklerScoreToggleHolder = document.createElement(`div`); wrinklerScoreToggleHolder.style.bottom = `9rem`; wrinklerScoreToggleHolder.style.right = `.5rem`; wrinklerScoreToggleHolder.style.position = `absolute`; wrinklerScoreToggleHolder.style.zIndex = `2001`; wrinklerScoreToggleHolder.style.transform = `scale(.8)` wrinklerScoreToggle.classList.add(`crate`, `upgrade`, `heavenly`); wrinklerScoreToggle.style.backgroundPosition = `-1248px -576px`; wrinklerScoreToggle.style.cursor = `pointer`; wrinklerScoreToggle.style.display = `none`; wrinklerScoreToggleHolder.appendChild(wrinklerScoreToggle); wrinklerScoreToggle.addEventListener(`click`, () => { wrinkleEl.style.display = wrinkleEl.style.display === `block` ? `none` : `block`; updateWrinkleScore(); if (wrinkleEl.style.display === `block`) wrinklerScoreToggle.classList.add(`enabled`); else wrinklerScoreToggle.classList.remove(`enabled`); }); const leftSection = document.querySelector(`#sectionLeft`); wrinkleEl.appendChild(wrinklePop); leftSection.appendChild(wrinkleEl); leftSection.appendChild(wrinklerScoreToggleHolder); if (options.enable) tickAction(); window.ochoose = window.choose; const filterWord = (word) => (sentence = ``) => sentence.toString().toLowerCase().indexOf(word.toLowerCase()) < 0; const filterBuildingDeBuffs = (k = ``) => unwantedEffects.some(t => filterWord(t)(k)) window.ochoose = window.choose; window.choose = (arr) => window.ochoose( arr .filter(options.preventClot ? filterWord(`clot`) : () => true) .filter(options.preventRuin ? filterWord(`ruin`) : () => true) .filter(options.preventBuildingDeBuff ? filterBuildingDeBuffs : () => true) ); } setTimeout(buildUI, 500); setTimeout(makeQueuePage, 500); }, 500) })();