diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a4bab89..8b0fdc2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,9 +16,10 @@ jobs: uses: actions/checkout@v2 - name: Set env run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - - run: mkdir BestDealHelper-${RELEASE_VERSION} - - run: cp -v info.txt main.js chroma.min.js BestDealHelper-${RELEASE_VERSION}/ - - run: zip -r BestDealHelper-${RELEASE_VERSION}.zip BestDealHelper-${RELEASE_VERSION} + - run: mkdir BestDealHelper + - run: cp -v CHANGELOG.md info.txt main.js chroma.min.js BestDealHelper/ + - run: touch BestDealHelper/Ver_${RELEASE_VERSION} + - run: zip -r BestDealHelper-${RELEASE_VERSION}.zip BestDealHelper - uses: ncipollo/release-action@v1 with: name: Release ${{ env.RELEASE_VERSION }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cfcf0b..06913b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2042.8] - 2021-09-18 +### Fixed +- Fix "raw cookies per second" get changed incorrectly. However, this Mod cannot detect whether your stat is correct or incorrectly; Please export your save, visit https://coderpatsy.bitbucket.io/cookies/editor.html, change `Highest raw CpS` to 0 and import modified save back to fix the value. + +### Changed +- Grandmapocalypse related upgrades are set to 0%, including "One mind", "Communal brainsweep", "Elder pact". + ## [2042.7] - 2021-09-18 ### Added diff --git a/README.md b/README.md index aa5b785..7d20820 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# BestDealHelper \ No newline at end of file +# BestDealHelper + +1. It sorts buildings and upgrades by CPS-Acceleration ratio* in game (toggleable) +2. It adds normalized* CPS-Acceleration ratio (💹xxx%) for unlocked buildings. + * Grandmapocalypse related upgrades are set to 0%, including "One mind", "Communal brainsweep", "Elder pact". \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md index b1db00f..bc4f0c6 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,7 +1,6 @@ -## [2042.7] - 2021-09-18 -### Added -- Include upgrades now! +## [2042.8] - 2021-09-18 +### Fixed +- Fix "raw cookies per second" get changed incorrectly. However, this Mod cannot detect whether your stat is correct or incorrectly; Please export your save, visit https://coderpatsy.bitbucket.io/cookies/editor.html, change `Highest raw CpS` to 0 and import modified save back to fix the value. ### Changed -- Improve: change The metric of deal quality from `Price–PerBuildingCPS ratio` to `cpsAcceleration ratio`, in order to gain most cps in the shortest time. -- Improve: hue for notations. \ No newline at end of file +- Grandmapocalypse related upgrades are set to 0%, including "One mind", "Communal brainsweep", "Elder pact". \ No newline at end of file diff --git a/info.txt b/info.txt index 0e89e41..12123d9 100644 --- a/info.txt +++ b/info.txt @@ -3,9 +3,9 @@ "ID": "Best Deal Helper", "Author": "Jethro Yu", "Description": "Help you choose best deal!", - "ModVersion": 2042.4, + "ModVersion": 2042.8, "GameVersion": 2.042, - "Date": "13/09/2021", + "Date": "18/09/2021", "Dependencies": ["CCSE"], "Disabled": 1, "AllowSteamAchievs": 1 diff --git a/main.js b/main.js index 8fcb18f..a9bb914 100644 --- a/main.js +++ b/main.js @@ -15,13 +15,15 @@ */ /** * @typedef {Object} Building - * @property {number} price * @property {DocumentFragment} l + * @property {number} price + * @property {number} timeToTargetCookie */ /** * @typedef {Object} Upgrade * @property {function} getPrice * @property {number} bought + * @property {number} timeToTargetCookie */ /** * @typedef {Object} Game @@ -61,11 +63,7 @@ let BestDealHelper = { sortbuildings: 0, }, - isLoaded: false, - load_chroma: false, - loopCount: 0, - - register: function () { + isLoaded: false, load_chroma: false, loopCount: 0, register: function () { Game.registerMod(this.name, this); }, @@ -114,34 +112,75 @@ let BestDealHelper = { logicLoop: function () { MOD.loopCount++; - if ( - MOD.loopCount >= 5 - || MOD.last_cps !== Game.cookiesPs - || MOD.config.sortbuildings !== MOD.last_config_sortbuildings - || !document.querySelector("#productAcc0") - || (document.querySelector("#upgrade0") && !document.querySelector("#upgradeAcc0")) - ) { + if (MOD.loopCount >= 5 || MOD.last_cps !== Game.cookiesPs || MOD.config.sortbuildings !== MOD.last_config_sortbuildings || !document.querySelector("#productAcc0") || (document.querySelector("#upgrade0") && !document.querySelector("#upgradeAcc0"))) { MOD.sortDeals(); MOD.loopCount = 0; MOD.last_config_sortbuildings = MOD.config.sortbuildings; MOD.last_cps = Game.cookiesPs; } }, - median: function (values) { - if (values.length === 0) return 0; - values.sort(function (a, b) { - return a - b; - }); + insertAfter: function (newNode, referenceNode) { + referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); + }, - const half = Math.floor(values.length / 2); + getCpsAcceleration: function (me) { + // Treat Grandmapocalypse upgrade as 0% temporary + if (["One mind", "Communal brainsweep", "Elder pact"].includes(me.name)) return 0; - if (values.length % 2) return values[half]; + // Backup + Game.Logic_ = Game.Logic; + Game.Logic = function () { + }; + let oldCookiesPsRawHighest = Game.cookiesPsRawHighest; + + if (me.type === "upgrade") me.bought++; else me.amount++; + Game.CalculateGains(); + me.newCookiesPs = Game.cookiesPs; + if (me.type === "upgrade") me.bought--; else me.amount--; + Game.CalculateGains(); + + // Restore + Game.cookiesPsRawHighest = oldCookiesPsRawHighest; + Game.Logic = Game.Logic_; + + let deltaTime; + if (me.type === "upgrade") me.price = me.getPrice(); + if (me.price > Game.cookies) { + deltaTime = (me.price - Game.cookies) / Game.cookiesPs + me.price / me.newCookiesPs; + } else { + deltaTime = me.price / me.newCookiesPs; + } - return (values[half - 1] + values[half]) / 2.0; + let deltaCps = me.newCookiesPs - Game.cookiesPs; + return deltaCps / deltaTime; }, - insertAfter: function (newNode, referenceNode) { - referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); + + /** + * @param {(Building|Upgrade)[]} all + */ + findHelper: function (all) { + all.forEach(e => e.isBestHelper = false); + + const target = all[0]; + if (target.price <= Game.cookies) return; + + target.timeToTargetCookie = (target.price - Game.cookies) / Game.cookiesPs; + let helpers = all.filter(me => me !== target && me.price < target.price); + if (!helpers.length) return; + + helpers.forEach(function (me) { + if (me.price > Game.cookies) { + me.timeToTargetCookie = (me.price - Game.cookies) / Game.cookiesPs + target.price / me.newCookiesPs; + } else { + me.timeToTargetCookie = (target.price - (Game.cookies - me.price)) / me.newCookiesPs; + } + }); + helpers.sort((a, b) => a.timeToTargetCookie - b.timeToTargetCookie); + if (helpers[0].timeToTargetCookie < target.timeToTargetCookie) { + helpers[0].isBestHelper = true; + } + }, sortDeals: function () { @@ -151,54 +190,37 @@ let BestDealHelper = { let all = [...buildings, ...upgrades]; // Calculate cpsAcceleration - all.forEach(function (me) { - Game.Logic_ = Game.Logic; - Game.Logic = function () { - }; - if (me.type === "upgrade") me.bought++; else me.amount++; - Game.CalculateGains(); - let newCookiesPs = Game.cookiesPs; - if (me.type === "upgrade") me.bought--; else me.amount--; - Game.CalculateGains(); - Game.Logic = Game.Logic_; - - let deltaTime; - if (me.type === "upgrade") me.price = me.getPrice(); - if (me.price > Game.cookies) { - deltaTime = (me.price - Game.cookies) / Game.cookiesPs + me.price / newCookiesPs; - } else { - deltaTime = me.price / newCookiesPs; - } + all.forEach(me => me.cpsAcceleration = MOD.getCpsAcceleration(me)); + // Sorting by cpsAcceleration + all.sort((a, b) => b.cpsAcceleration - a.cpsAcceleration); - let deltaCps = newCookiesPs - Game.cookiesPs; - return me.cpsAcceleration = deltaCps / deltaTime; - }); + // If the best cpsAcceleration is not affordable, try to find a pre-deal help us to get the best deal quicker. + MOD.findHelper(all); - // determine colors - all.sort((a, b) => a.cpsAcceleration - b.cpsAcceleration); + // Determine colors all.forEach((e, index) => e.accRank = index); let palette = ["#00ffff"]; - let rank = all.length - 1; + let rank = 0; let domain = [all[rank].cpsAcceleration]; - rank--; - if (rank >= 0) { + rank++; + if (rank < all.length) { palette.unshift("#00ff00"); domain.unshift(all[rank].cpsAcceleration); } - rank -= 6; - if (rank >= 0) { + rank += 6; + if (rank < all.length) { palette.unshift("#ffd939"); domain.unshift(all[rank].cpsAcceleration); } - rank -= 8; - if (rank >= 0) { + rank += 8; + if (rank < all.length) { palette.unshift("#ff0000"); domain.unshift(all[rank].cpsAcceleration); } - rank--; - if (rank >= 0) { + rank++; + if (rank < all.length) { palette.unshift("#64007c"); - domain.unshift(all[0].cpsAcceleration); + domain.unshift(all[all.length - 1].cpsAcceleration); } let color = chroma.scale(palette).mode("lab").domain(domain); @@ -223,20 +245,19 @@ let BestDealHelper = { l("upgrade" + i).appendChild(span); } span.textContent = Beautify(me.cpsAcceleration * 100 / avg, 1) + "%"; - span.style.color = color(me.cpsAcceleration); - } - // Sort upgrades (or leave them as default) - upgrades.sort((a, b) => b.cpsAcceleration - a.cpsAcceleration); - // Only sort when the order is different - let upgrades_order = upgrades.map(e => e.l.id); - let current_upgrades_order = [...document.querySelector("#upgrades").children].map(e => e.id); - if (!upgrades_order.every((value, index) => value === current_upgrades_order[index])) { - let store = document.querySelector("#upgrades"); - for (let i = 0; i < upgrades.length; ++i) { - store.appendChild(upgrades[i].l); + if (me.isBestHelper) { + let text = span.innerText; + span.innerHTML = ""; + for (let i = 0; i < text.length; i++) { + let charElem = document.createElement("span"); + charElem.style.color = "hsl(" + (360 * i / text.length) + ",80%,50%)"; + charElem.innerHTML = text[i]; + span.appendChild(charElem); + } + } else { + span.style.color = color(me.cpsAcceleration); } } - // Notation for buildings for (const i in buildings) { let me = buildings[i]; @@ -249,10 +270,32 @@ let BestDealHelper = { MOD.insertAfter(span, l("productPrice" + me.id)); } span.textContent = " 💹" + Beautify(me.cpsAcceleration * 100 / avg, 2) + "%"; - span.style.color = color(me.cpsAcceleration); - + if (me.isBestHelper) { + let text = span.innerText; + span.innerHTML = ""; + for (let i = 0; i < text.length; i++) { + let charElem = document.createElement("span"); + charElem.style.color = "hsl(" + (360 * i / text.length) + ",80%,50%)"; + charElem.innerHTML = text[i]; + span.appendChild(charElem); + } + } else { + span.style.color = color(me.cpsAcceleration); + } } + + // Sort upgrades (or leave them as default) + upgrades.sort((a, b) => b.cpsAcceleration - a.cpsAcceleration); + // Only sort when the order is different + let upgrades_order = upgrades.map(e => e.l.id); + let current_upgrades_order = [...document.querySelector("#upgrades").children].map(e => e.id); + if (!upgrades_order.every((value, index) => value === current_upgrades_order[index])) { + let store = document.querySelector("#upgrades"); + for (let i = 0; i < upgrades.length; ++i) { + store.appendChild(upgrades[i].l); + } + } // Sort buildings (or leave them as default) if (MOD.config.sortbuildings) { buildings.sort((a, b) => b.cpsAcceleration - a.cpsAcceleration);