您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
新しい放置ゲームで目標までの放置時間を表示します
当前为
// ==UserScript== // @name 新しい放置ゲームで目標までの放置時間を表示する // @namespace http://tampermonkey.net/ // @version 0.6.0 // @description 新しい放置ゲームで目標までの放置時間を表示します // @author toomer // @match https://dem08656775.github.io/newincrementalgame/ // @grant none // ==/UserScript== // jshint esversion: 6 (() => { 'use strict'; const matrix_mul = (a, b) => { let c = Array.from(new Array(a.length), () => new Array(b[0].length).fill(new Decimal(0))); for (let i = 0; i < a.length; i++) { for (let j = 0; j < b[0].length; j++) { for (let k = 0; k < a[0].length; k++) { c[i][j] = c[i][j].add(a[i][k].mul(b[k][j])); } } } return c; }; const matrix_eye = (n) => { let a = Array.from(new Array(n), () => new Array(n).fill(new Decimal(0))); for (let i = 0; i < n; i++) { a[i][i] = new Decimal(1); } return a; }; class NIG { constructor() { this.game = NIG.load(); } static load() { let game = { player: { money: new Decimal(document.getElementById('coinamount').textContent.slice(6)), level: (() => { const contents = document.getElementsByClassName('levelrcontents'); if (contents.length == 0) return new Decimal(0); const res = contents[0].textContent.match(/段位: (?<level>[e\d\+\.]+)/); return new Decimal(res === null ? 0 : res.groups.level); })(), levelresettime: (() => { const contents = document.getElementsByClassName('levelrcontents'); if (contents.length == 0) return new Decimal(0); const res = contents[0].textContent.match(/段位リセット: (?<levelresettime>[e\d\+\.]+)/); return new Decimal(res === null ? 0 : res.groups.levelresettime); })(), maxlevelgained: (() => { const res = document.getElementsByClassName('challenges-container')[0].parentElement.textContent.match(/最大取得段位:(?<maxlevelgained>[e\d\+\.]+)/); return new Decimal(res === null ? 1 : res.groups.maxlevelgained); })(), rank: (() => { const contents = document.getElementsByClassName('rankrcontents'); if (contents.length == 0) return new Decimal(0); const res = contents[0].textContent.match(/階位: (?<rank>[e\d\+\.]+)/); return new Decimal(res === null ? 0 : res.groups.rank); })(), rankresettime: (() => { const contents = document.getElementsByClassName('rankrcontents'); if (contents.length == 0) return new Decimal(0); const res = contents[0].textContent.match(/階位リセット: (?<rankresettime>[e\d\+\.]+)/); return new Decimal(res === null ? 0 : res.groups.rankresettime); })(), generators: (() => { let generators = new Array(8).fill(null).map(() => new Decimal(0)); const generatorElements = document.getElementsByClassName('generator'); for (let i = 0; i < generatorElements.length; i++) { const res = generatorElements[i].textContent.match(/発生器(\d)+: (?<n>[e\d\+\.]+)/); if (res !== null) generators[i] = new Decimal(res.groups.n); } return generators; })(), generatorsBought: (() => { let generatorsBought = new Array(8).fill(null).map(() => new Decimal(0)); const generatorElements = document.getElementsByClassName('generator'); for (let i = 0; i < generatorElements.length; i++) { const res = generatorElements[i].textContent.match(/購入数: (?<n>[e\d\+\.]+)/); if (res !== null) generatorsBought[i] = new Decimal(res.groups.n); } return generatorsBought; })(), generatorsCost: (() => { let generatorsCost = [new Decimal(1), new Decimal('1e4'), new Decimal('1e9'), new Decimal('1e16'), new Decimal('1e25'), new Decimal('1e36'), new Decimal('1e49'), new Decimal('1e64')]; const gbuttons = document.getElementsByClassName('gbutton'); for (let i = 0; i < gbuttons.length; i++) { const res = gbuttons[i].textContent.match(/購入 コスト: (?<n>[e\d\+\.]+)/); generatorsCost[i] = new Decimal(res.groups.n); } return generatorsCost; })(), generatorsMode: (() => { let generatorsMode = new Array(8).fill(null).map((_, i) => i); const generatorElements = document.getElementsByClassName('generator'); for (let i = 0; i < generatorElements.length; i++) { const res = generatorElements[i].textContent.match(/モード: (?<n>\d+)/); if (res !== null) generatorsMode[i] = Number(res.groups.n); } return generatorsMode; })(), accelerators: (() => { let accelerators = new Array(8).fill(null).map(() => new Decimal(0)); const acceleratorElements = document.getElementsByClassName('accelerator'); for (let i = 0; i < acceleratorElements.length; i++) { const res = acceleratorElements[i].textContent.match(/時間加速器(\d)+: (?<n>[e\d\+\.]+)/); if (res !== null) accelerators[i] = new Decimal(res.groups.n); } return accelerators; })(), acceleratorsBought: (() => { let acceleratorsBought = new Array(8).fill(null).map(() => new Decimal(0)); const acceleratorElements = document.getElementsByClassName('accelerator'); for (let i = 0; i < acceleratorElements.length; i++) { const res = acceleratorElements[i].textContent.match(/購入数: (?<n>[e\d\+\.]+)/); if (res !== null) acceleratorsBought[i] = new Decimal(res.groups.n); } return acceleratorsBought; })(), acceleratorsCost: (() => { let acceleratorsCost = [new Decimal(10), new Decimal('1e10'), new Decimal('1e20'), new Decimal('1e40'), new Decimal('1e80'), new Decimal('1e160'), new Decimal('1e320'), new Decimal('1e640')]; const abuttons = document.getElementsByClassName('abutton'); for (let i = 0; i < abuttons.length; i++) { const res = abuttons[i].textContent.match(/購入 コスト: (?<n>[e\d\+\.]+)/); acceleratorsCost[i] = new Decimal(res.groups.n); } return acceleratorsCost; })(), tickspeed: (() => { const res = document.getElementById('tickspeed').textContent.match(/: (?<tickspeed>\d+)/); return new Decimal(res === null ? 1000 : res.groups.tickspeed); })(), onchallenge: document.getElementsByClassName('challengeconfigbutton')[8].textContent == ' 挑戦放棄 ', challenges: (() => { let challenges = []; const challengeconfigbutton = document.getElementsByClassName('challengeconfigbutton'); for (let i = 0; i < 8; i++) { if (challengeconfigbutton[i].classList.contains('selected')) { challenges.push(i); } } return challenges; })(), challengebonuses: (() => { let challengebonuses = []; const rewardbuttons = document.getElementsByClassName('rewardbutton'); for (let i = 0; i < 15; i++) { if (rewardbuttons[i].classList.contains('selected')) { challengebonuses.push(i); } } return challengebonuses; })(), rankchallengebonuses: (() => { let rankchallengebonuses = []; const rewardbuttons = document.getElementsByClassName('rewardbutton'); for (let i = 15; i < 30; i++) { if (rewardbuttons[i].classList.contains('selected')) { rankchallengebonuses.push(i - 15); } } return rankchallengebonuses; })(), levelitems: (() => { let levelitems = [0, 0, 0, 0, 0]; const levelitemElements = document.getElementsByClassName('levelitem'); for (let i = 0; i < levelitemElements.length; i++) { const res = levelitemElements[i].textContent.match(/取得数: (?<n>\d+)/); if (res !== null) levelitems[i] = Number(res.groups.n); } return levelitems; })(), levelitembought: 0, }, activechallengebonuses: [], memory: (() => { const res = document.getElementsByClassName('worlds')[0].parentElement.textContent.match(/記憶: (?<memory>[e\d\+\.]+)/); return res === null ? 0 : res.groups.memory; })(), }; game.player.onchallenge |= document.getElementById('enablechalcheck').checked; if (game.player.challengebonuses.includes(4) || !game.player.onchallenge) { game.activechallengebonuses = game.player.challengebonuses; } return game; } static softCap(num, cap) { if (num.lessThanOrEqualTo(cap)) return num; let capped = num.div(cap); capped = new Decimal(capped.log2()).add(1); return cap.mul(capped).min(num); } calcincrementmult(i, to) { let mult = new Decimal(1); if (!(this.game.player.onchallenge && this.game.player.challenges.includes(4))) { mult = mult.mul(new Decimal(10).pow((i + 1) * (i - to))); } if (!(this.game.player.onchallenge && this.game.player.challenges.includes(7))) { let cap = new Decimal(100).mul(this.game.player.levelitems[2] + 1); mult = mult.mul(NIG.softCap(this.game.player.levelresettime.add(1), cap)); } mult = mult.mul(new Decimal(this.game.player.level.add(2).log2()).pow(i - to)); let highest = 0; for (let j = 0; j < 8; j++) { if (this.game.player.generators[j].greaterThan(0)) { highest = j; } } if (!(this.game.player.onchallenge && this.game.player.challenges.includes(2))) { let mm = this.game.player.generatorsBought[i]; if (this.game.activechallengebonuses.includes(11)) { mm = mm.mul(new Decimal(mm.add(2).log2()).round()); } if (i < highest && this.game.player.generatorsBought[i].greaterThan(0)) { mult = mult.mul(mm); } else { if (this.game.activechallengebonuses.includes(2) && this.game.player.generatorsBought[i].greaterThan(0)) { mult = mult.mul(mm); } } } if (this.game.activechallengebonuses.includes(3)) { mult = mult.mul(new Decimal(2)); } if (this.game.player.rankchallengebonuses.includes(3)) { mult = mult.mul(new Decimal(3)) } if (i == 0 && this.game.activechallengebonuses.includes(7)) { mult = mult.mul(this.game.player.maxlevelgained.min(100000)); } mult = mult.mul(1 + this.game.memory * 0.25); return mult; } multmatrix() { let multmat = matrix_eye(9); for (let i = 0; i < 8; i++) { if (!this.game.activechallengebonuses.includes(13)) { const to = this.game.player.generatorsMode[i]; multmat[i + 1][to] = multmat[i + 1][to].add(this.calcincrementmult(i, to)); } else if (this.game.player.onchallenge && this.game.player.challenges.includes(3)) { multmat[i + 1][0] = multmat[i + 1][0].add(this.calcincrementmult(i, 0).mul(i + 1)); } else { for (let to = 0; to <= i; to++) { multmat[i + 1][to] = multmat[i + 1][to].add(this.calcincrementmult(i, to)); } } } return multmat; } amount() { let a = new Array(1); let b = new Array(9).fill(new Decimal(0)); b[0] = this.game.player.money; for (let i = 0; i < this.game.player.generators.length; i++) { b[i + 1] = this.game.player.generators[i]; } a[0] = b; return a; } accmultmatrix() { let multmat = matrix_eye(8); for (let i = 1; i < 8; i++) { let mult = new Decimal(1); if (this.game.activechallengebonuses.includes(10)) { mult = mult.mul(this.game.player.acceleratorsBought[i]); } multmat[i][i - 1] = multmat[i][i - 1].add(mult); } return multmat; } accamount() { let a = new Array(1); let b = new Array(8).fill(new Decimal(0)); for (let i = 0; i < this.game.player.accelerators.length; i++) { b[i] = this.game.player.accelerators[i]; } a[0] = b; return a; } targetmoney(target) { let tmoney = new Decimal('1e+100'); if (target == 'lowest') { for (let i = 0; i < this.game.player.generatorsCost.length; i++) { if (i >= 3 && this.game.player.onchallenge && this.game.player.challenges.includes(6)) break; tmoney = tmoney.min(this.game.player.generatorsCost[i]); } if (!(this.game.player.onchallenge && this.game.player.challenges.includes(5))) { for (let i = 0; i < this.game.player.acceleratorsCost; i++) { tmoney = tmoney.min(this.game.player.acceleratorsCost[i]); } } } else if (target == 'newgen') { for (let i = 0; i < this.game.player.generatorsCost.length; i++) { if (i >= 3 && this.game.player.onchallenge && this.game.player.challenges.includes(6)) break; if (this.game.player.generators[i].eq(0)) { tmoney = tmoney.min(this.game.player.generatorsCost[i]); } } } else if (target == 'levelreset') { if (this.game.player.onchallenge && this.game.player.challenges.includes(0)) { tmoney = new Decimal('1e+24'); } else { tmoney = new Decimal('1e+18'); } } else if (target == 'rankreset') { tmoney = new Decimal('1e+72'); } else if (target == 'input') { try { tmoney = (new Decimal(document.getElementById('targetcfg').value)).max(0); } catch (e) { } } else { tmoney = new Decimal('1e+18'); } return tmoney; } calcgoalticks(tmoney) { const multmat = this.multmatrix(); const amount = this.amount(); if (amount[0][0].greaterThanOrEqualTo(tmoney)) return new Decimal(0); if (amount[0].slice(1).every((a) => a.eq(0))) return new Decimal('Infinity'); let base = [multmat, new Decimal(1)]; let bases = []; while (matrix_mul(amount, base[0])[0][0].lessThan(tmoney)) { bases.push(base); base = [matrix_mul(base[0], base[0]), base[1].add(base[1])]; } base = [matrix_eye(multmat.length), new Decimal(0)]; while (bases.length > 0) { const bb = bases.pop(); const m = matrix_mul(base[0], bb[0]); if (matrix_mul(amount, m)[0][0].lessThan(tmoney)) { base = [m, base[1].add(bb[1])]; } } return base[1].add(new Decimal(1)); } tick2sec(tick) { const accmultmat = this.accmultmatrix(); const accamount = this.accamount(); if (tick.lessThanOrEqualTo(0)) return new Decimal(0); if (tick.eq(new Decimal('Infinity'))) return new Decimal('Infinity'); // const delay = tick.mul('1e-6').max(new Decimal('1e-3')); const delay = new Decimal('1e-3'); let base = [accmultmat, new Decimal(1)]; let bases = []; while (base[1].lessThanOrEqualTo(tick)) { bases.push(base); base = [matrix_mul(base[0], base[0]), base[1].add(base[1])]; } const basetick = new Decimal(1000 - this.game.player.levelitems[1] * this.game.player.challengebonuses.length).div(1000); let amult = this.game.activechallengebonuses.includes(6) ? this.game.player.acceleratorsBought[0].max(1) : new Decimal(1); base = [matrix_eye(accmultmat.length), new Decimal(0)]; let prevdt = this.game.player.tickspeed.mul(new Decimal('1e-3')); let sec = new Decimal(0); while (base[1].lessThan(tick)) { const prevtick = base[1]; for (let i = bases.length; i-- > 0;) { if (base[1].add(bases[i][1]).lessThanOrEqualTo(tick)) { const m = matrix_mul(base[0], bases[i][0]); if (i == 0 && prevtick.eq(base[1]) || basetick.div(matrix_mul(accamount, m)[0][0].add(10).mul(amult).log10()).add(delay).greaterThan(prevdt)) { base = [m, base[1].add(bases[i][1])]; } } } if (prevtick.eq(base[1])) break; const dt = basetick.div(matrix_mul(accamount, base[0])[0][0].add(10).mul(amult).log10()); sec = sec.add((prevdt.add(dt)).div(2).mul(base[1].sub(prevtick))); prevdt = dt; } return sec; } } let prevupdtime = 0; let prev = null; let tickspeed = new Decimal(1000); const update = (force, repeat) => { if (force || (Date.now() - prevupdtime >= 1000)) { let nig = new NIG(); const sel = document.getElementById('targetSelector'); const tmoney = nig.targetmoney(sel.options[sel.selectedIndex].value); const goalticks = nig.calcgoalticks(tmoney); const goalsec = nig.tick2sec(goalticks); tickspeed = nig.game.player.tickspeed; prevupdtime = Date.now(); prev = { tmoney: tmoney, goalticks: goalticks, goalsec: goalsec, }; } if (prev !== null) { const updategoal = () => { const elapsed = Date.now() - prevupdtime; const goalticks = prev.goalticks.sub(new Decimal(elapsed).div(tickspeed).floor()).max(0); const goalsec = prev.goalsec.sub(elapsed / 1000).max(0); let goalstr = prev.tmoney.toExponential(3) + ' ポイントまで ' + goalticks.toExponential(3) + ' ticks'; goalstr += ' (' + goalsec.toExponential(3) + ' sec)'; goalstr += ' ' + (new Date(Date.now() + Number(goalsec.mul(1000).toExponential(20)))).toLocaleString() + ' に達成'; document.getElementById('targetmoney').textContent = goalstr; }; updategoal(); } if (repeat) { setTimeout(() => update(false, repeat), 200); } }; let div = document.createElement('div'); div.id = 'calculator'; { let selectdiv = document.createElement('div'); let select = document.createElement('select'); select.id = 'targetSelector'; [ ['lowest', '最低コスト'], ['newgen', '新しい発生器'], ['levelreset', '段位リセット'], ['rankreset', '階位リセット'], ['input', '入力'], ].forEach(cfg => { let option = document.createElement('option'); option.value = cfg[0]; option.textContent = cfg[1]; select.appendChild(option); }); select.addEventListener('change', () => { const sel = document.getElementById('targetSelector'); const input = document.getElementById('targetcfg'); if (sel.options[sel.selectedIndex].value == 'input') { input.style.visibility = 'visible'; } else { input.style.visibility = 'hidden'; } }); selectdiv.appendChild(select); let input = document.createElement('input'); input.id = 'targetcfg'; input.type = 'text'; input.value = '1e18'; input.size = 10; input.style.visibility = 'hidden'; selectdiv.appendChild(input); div.appendChild(selectdiv); } { let inputdiv = document.createElement('div'); let input = document.createElement('input'); input.id = 'enablechalcheck'; input.type = 'checkbox'; inputdiv.appendChild(input); inputdiv.append('挑戦内容を反映'); div.appendChild(inputdiv); } { let targetmoneydiv = document.createElement('div'); targetmoneydiv.id = 'targetmoney'; targetmoneydiv.textContent = '1e18'; div.appendChild(targetmoneydiv); } document.getElementsByClassName('container')[0].appendChild(div); update(true, true); })();