diff --git a/CHANGELOG.md b/CHANGELOG.md index b982041..b2afda6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,66 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- **BREAKING** New requirements system + - Replaces many features' existing requirements with new generic form +- Formulas, which can be used to calculate buy max for you +- Action feature +- ETA util +- createCollapsibleMilestones util +- deleteLowerSaves util +- Minimized layers can now display a component +- submitOnBlur property to Text fields +- showPopups property to Milestones +- Mouse/touch events to more onClick listeners +- Example hotkey to starting layer +- Schema for projInfo.json +### Changes +- **BREAKING** Buyables renamed to Repeatables + - Renamed purchaseLimit to limit + - Renamed buyMax to maximize + - Added initialAmount property +- **BREAKING** Persistent refs no longer have redundancies in save object + - Requires referencing persistent refs either through a proxy or by wrapping in `noPersist()` +- **BREAKING** Visibility properties can now take booleans + - Removed showIf util +- Tweaked settings display +- setupPassiveGeneration will no longer lower the resource +- displayResource now floors resource amounts +- Tweaked modifier displays, incl showing negative modifiers in red +- Hotkeys now appear on key graphic +- Mofifier sections now accept computable strings for title and subtitle +- Updated b_e +### Fixed +- NaN detection stopped working + - Now specifically only checks persistent refs +- trackTotal would increase the total when loading the save +- PWAs wouldn't show updates +- Board feature no longer working at all +- Some discord links didn't open in new tab +- Adjacent grid cells wouldn't merge +- When fixing old saves, the modVersion would not be updated +- Default layer would display `Dev Speed: 0x` when paused +- Fixed hotkeys not working with shift + numbers +- Fixed console errors about deleted persistent refs not being included in the layer object +- Modifiers wouldn't display small numbers +- Conversions' addSoftcap wouldn't affect currentAt or nextAt +- MainDisplay not respecting style and classes props +- Tabs could sometimes not update correctly +- offlineTime not capping properly +- Tooltips being user-selectable +- Workflows not working with submodules +- Various minor typing issues +### Documented +- requirements.tsx +- formulas.tsx +- repeatables.tsx +### Tests +- requirements +- formulas + +Contributors: thepaperpilot, escapee, adsaf, ducdat + ## [0.5.2] - 2022-08-22 ### Added - onLoad event diff --git a/package-lock.json b/package-lock.json index 7082e7c..31bffe8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "jsdom": "^20.0.0", "prettier": "^2.5.1", "typescript": "^4.7.4", - "vitest": "^0.28.5", + "vitest": "^0.29.3", "vue-tsc": "^0.38.1" }, "engines": { @@ -2718,23 +2718,23 @@ } }, "node_modules/@vitest/expect": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.28.5.tgz", - "integrity": "sha512-gqTZwoUTwepwGIatnw4UKpQfnoyV0Z9Czn9+Lo2/jLIt4/AXLTn+oVZxlQ7Ng8bzcNkR+3DqLJ08kNr8jRmdNQ==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.29.3.tgz", + "integrity": "sha512-z/0JqBqqrdtrT/wzxNrWC76EpkOHdl+SvuNGxWulLaoluygntYyG5wJul5u/rQs5875zfFz/F+JaDf90SkLUIg==", "dev": true, "dependencies": { - "@vitest/spy": "0.28.5", - "@vitest/utils": "0.28.5", + "@vitest/spy": "0.29.3", + "@vitest/utils": "0.29.3", "chai": "^4.3.7" } }, "node_modules/@vitest/runner": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.28.5.tgz", - "integrity": "sha512-NKkHtLB+FGjpp5KmneQjTcPLWPTDfB7ie+MmF1PnUBf/tGe2OjGxWyB62ySYZ25EYp9krR5Bw0YPLS/VWh1QiA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.29.3.tgz", + "integrity": "sha512-XLi8ctbvOWhUWmuvBUSIBf8POEDH4zCh6bOuVxm/KGfARpgmVF1ku+vVNvyq85va+7qXxtl+MFmzyXQ2xzhAvw==", "dev": true, "dependencies": { - "@vitest/utils": "0.28.5", + "@vitest/utils": "0.29.3", "p-limit": "^4.0.0", "pathe": "^1.1.0" } @@ -2767,24 +2767,23 @@ } }, "node_modules/@vitest/spy": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.28.5.tgz", - "integrity": "sha512-7if6rsHQr9zbmvxN7h+gGh2L9eIIErgf8nSKYDlg07HHimCxp4H6I/X/DPXktVPPLQfiZ1Cw2cbDIx9fSqDjGw==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.29.3.tgz", + "integrity": "sha512-LLpCb1oOCOZcBm0/Oxbr1DQTuKLRBsSIHyLYof7z4QVE8/v8NcZKdORjMUq645fcfX55+nLXwU/1AQ+c2rND+w==", "dev": true, "dependencies": { "tinyspy": "^1.0.2" } }, "node_modules/@vitest/utils": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.28.5.tgz", - "integrity": "sha512-UyZdYwdULlOa4LTUSwZ+Paz7nBHGTT72jKwdFSV4IjHF1xsokp+CabMdhjvVhYwkLfO88ylJT46YMilnkSARZA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.29.3.tgz", + "integrity": "sha512-hg4Ff8AM1GtUnLpUJlNMxrf9f4lZr/xRJjh3uJ0QFP+vjaW82HAxKrmeBmLnhc8Os2eRf+f+VBu4ts7TafPPkA==", "dev": true, "dependencies": { "cli-truncate": "^3.1.0", "diff": "^5.1.0", "loupe": "^2.3.6", - "picocolors": "^1.0.0", "pretty-format": "^27.5.1" } }, @@ -5819,15 +5818,15 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/mlly": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.1.0.tgz", - "integrity": "sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.0.tgz", + "integrity": "sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==", "dev": true, "dependencies": { - "acorn": "^8.8.1", - "pathe": "^1.0.0", - "pkg-types": "^1.0.1", - "ufo": "^1.0.1" + "acorn": "^8.8.2", + "pathe": "^1.1.0", + "pkg-types": "^1.0.2", + "ufo": "^1.1.1" } }, "node_modules/ms": { @@ -6083,14 +6082,14 @@ } }, "node_modules/pkg-types": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.1.tgz", - "integrity": "sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.2.tgz", + "integrity": "sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==", "dev": true, "dependencies": { "jsonc-parser": "^3.2.0", - "mlly": "^1.0.0", - "pathe": "^1.0.0" + "mlly": "^1.1.1", + "pathe": "^1.1.0" } }, "node_modules/postcss": { @@ -7019,9 +7018,9 @@ } }, "node_modules/ufo": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz", - "integrity": "sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.1.1.tgz", + "integrity": "sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==", "dev": true }, "node_modules/unbox-primitive": { @@ -7202,9 +7201,9 @@ } }, "node_modules/vite-node": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.28.5.tgz", - "integrity": "sha512-LmXb9saMGlrMZbXTvOveJKwMTBTNUH66c8rJnQ0ZPNX+myPEol64+szRzXtV5ORb0Hb/91yq+/D3oERoyAt6LA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.29.3.tgz", + "integrity": "sha512-QYzYSA4Yt2IiduEjYbccfZQfxKp+T1Do8/HEpSX/G5WIECTFKJADwLs9c94aQH4o0A+UtCKU61lj1m5KvbxxQA==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -7212,8 +7211,6 @@ "mlly": "^1.1.0", "pathe": "^1.1.0", "picocolors": "^1.0.0", - "source-map": "^0.6.1", - "source-map-support": "^0.5.21", "vite": "^3.0.0 || ^4.0.0" }, "bin": { @@ -7280,9 +7277,9 @@ } }, "node_modules/vite-node/node_modules/rollup": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.15.0.tgz", - "integrity": "sha512-F9hrCAhnp5/zx/7HYmftvsNBkMfLfk/dXUh73hPSM2E3CRgap65orDNJbLetoiUFwSAk6iHPLvBrZ5iHYvzqsg==", + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.19.1.tgz", + "integrity": "sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -7296,9 +7293,9 @@ } }, "node_modules/vite-node/node_modules/vite": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", - "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.4.tgz", + "integrity": "sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==", "dev": true, "dependencies": { "esbuild": "^0.16.14", @@ -7380,18 +7377,18 @@ } }, "node_modules/vitest": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.28.5.tgz", - "integrity": "sha512-pyCQ+wcAOX7mKMcBNkzDwEHRGqQvHUl0XnoHR+3Pb1hytAHISgSxv9h0gUiSiYtISXUU3rMrKiKzFYDrI6ZIHA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.29.3.tgz", + "integrity": "sha512-muMsbXnZsrzDGiyqf/09BKQsGeUxxlyLeLK/sFFM4EXdURPQRv8y7dco32DXaRORYP0bvyN19C835dT23mL0ow==", "dev": true, "dependencies": { "@types/chai": "^4.3.4", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.28.5", - "@vitest/runner": "0.28.5", - "@vitest/spy": "0.28.5", - "@vitest/utils": "0.28.5", + "@vitest/expect": "0.29.3", + "@vitest/runner": "0.29.3", + "@vitest/spy": "0.29.3", + "@vitest/utils": "0.29.3", "acorn": "^8.8.1", "acorn-walk": "^8.2.0", "cac": "^6.7.14", @@ -7407,7 +7404,7 @@ "tinypool": "^0.3.1", "tinyspy": "^1.0.2", "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.28.5", + "vite-node": "0.29.3", "why-is-node-running": "^2.2.2" }, "bin": { @@ -9914,23 +9911,23 @@ } }, "@vitest/expect": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.28.5.tgz", - "integrity": "sha512-gqTZwoUTwepwGIatnw4UKpQfnoyV0Z9Czn9+Lo2/jLIt4/AXLTn+oVZxlQ7Ng8bzcNkR+3DqLJ08kNr8jRmdNQ==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.29.3.tgz", + "integrity": "sha512-z/0JqBqqrdtrT/wzxNrWC76EpkOHdl+SvuNGxWulLaoluygntYyG5wJul5u/rQs5875zfFz/F+JaDf90SkLUIg==", "dev": true, "requires": { - "@vitest/spy": "0.28.5", - "@vitest/utils": "0.28.5", + "@vitest/spy": "0.29.3", + "@vitest/utils": "0.29.3", "chai": "^4.3.7" } }, "@vitest/runner": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.28.5.tgz", - "integrity": "sha512-NKkHtLB+FGjpp5KmneQjTcPLWPTDfB7ie+MmF1PnUBf/tGe2OjGxWyB62ySYZ25EYp9krR5Bw0YPLS/VWh1QiA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.29.3.tgz", + "integrity": "sha512-XLi8ctbvOWhUWmuvBUSIBf8POEDH4zCh6bOuVxm/KGfARpgmVF1ku+vVNvyq85va+7qXxtl+MFmzyXQ2xzhAvw==", "dev": true, "requires": { - "@vitest/utils": "0.28.5", + "@vitest/utils": "0.29.3", "p-limit": "^4.0.0", "pathe": "^1.1.0" }, @@ -9953,24 +9950,23 @@ } }, "@vitest/spy": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.28.5.tgz", - "integrity": "sha512-7if6rsHQr9zbmvxN7h+gGh2L9eIIErgf8nSKYDlg07HHimCxp4H6I/X/DPXktVPPLQfiZ1Cw2cbDIx9fSqDjGw==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.29.3.tgz", + "integrity": "sha512-LLpCb1oOCOZcBm0/Oxbr1DQTuKLRBsSIHyLYof7z4QVE8/v8NcZKdORjMUq645fcfX55+nLXwU/1AQ+c2rND+w==", "dev": true, "requires": { "tinyspy": "^1.0.2" } }, "@vitest/utils": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.28.5.tgz", - "integrity": "sha512-UyZdYwdULlOa4LTUSwZ+Paz7nBHGTT72jKwdFSV4IjHF1xsokp+CabMdhjvVhYwkLfO88ylJT46YMilnkSARZA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.29.3.tgz", + "integrity": "sha512-hg4Ff8AM1GtUnLpUJlNMxrf9f4lZr/xRJjh3uJ0QFP+vjaW82HAxKrmeBmLnhc8Os2eRf+f+VBu4ts7TafPPkA==", "dev": true, "requires": { "cli-truncate": "^3.1.0", "diff": "^5.1.0", "loupe": "^2.3.6", - "picocolors": "^1.0.0", "pretty-format": "^27.5.1" } }, @@ -12129,15 +12125,15 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "mlly": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.1.0.tgz", - "integrity": "sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.0.tgz", + "integrity": "sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==", "dev": true, "requires": { - "acorn": "^8.8.1", - "pathe": "^1.0.0", - "pkg-types": "^1.0.1", - "ufo": "^1.0.1" + "acorn": "^8.8.2", + "pathe": "^1.1.0", + "pkg-types": "^1.0.2", + "ufo": "^1.1.1" } }, "ms": { @@ -12327,14 +12323,14 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pkg-types": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.1.tgz", - "integrity": "sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.2.tgz", + "integrity": "sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==", "dev": true, "requires": { "jsonc-parser": "^3.2.0", - "mlly": "^1.0.0", - "pathe": "^1.0.0" + "mlly": "^1.1.1", + "pathe": "^1.1.0" } }, "postcss": { @@ -12981,9 +12977,9 @@ "dev": true }, "ufo": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz", - "integrity": "sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.1.1.tgz", + "integrity": "sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==", "dev": true }, "unbox-primitive": { @@ -13101,9 +13097,9 @@ } }, "vite-node": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.28.5.tgz", - "integrity": "sha512-LmXb9saMGlrMZbXTvOveJKwMTBTNUH66c8rJnQ0ZPNX+myPEol64+szRzXtV5ORb0Hb/91yq+/D3oERoyAt6LA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.29.3.tgz", + "integrity": "sha512-QYzYSA4Yt2IiduEjYbccfZQfxKp+T1Do8/HEpSX/G5WIECTFKJADwLs9c94aQH4o0A+UtCKU61lj1m5KvbxxQA==", "dev": true, "requires": { "cac": "^6.7.14", @@ -13111,8 +13107,6 @@ "mlly": "^1.1.0", "pathe": "^1.1.0", "picocolors": "^1.0.0", - "source-map": "^0.6.1", - "source-map-support": "^0.5.21", "vite": "^3.0.0 || ^4.0.0" }, "dependencies": { @@ -13154,18 +13148,18 @@ } }, "rollup": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.15.0.tgz", - "integrity": "sha512-F9hrCAhnp5/zx/7HYmftvsNBkMfLfk/dXUh73hPSM2E3CRgap65orDNJbLetoiUFwSAk6iHPLvBrZ5iHYvzqsg==", + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.19.1.tgz", + "integrity": "sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==", "dev": true, "requires": { "fsevents": "~2.3.2" } }, "vite": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", - "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.4.tgz", + "integrity": "sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==", "dev": true, "requires": { "esbuild": "^0.16.14", @@ -13202,18 +13196,18 @@ } }, "vitest": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.28.5.tgz", - "integrity": "sha512-pyCQ+wcAOX7mKMcBNkzDwEHRGqQvHUl0XnoHR+3Pb1hytAHISgSxv9h0gUiSiYtISXUU3rMrKiKzFYDrI6ZIHA==", + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.29.3.tgz", + "integrity": "sha512-muMsbXnZsrzDGiyqf/09BKQsGeUxxlyLeLK/sFFM4EXdURPQRv8y7dco32DXaRORYP0bvyN19C835dT23mL0ow==", "dev": true, "requires": { "@types/chai": "^4.3.4", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.28.5", - "@vitest/runner": "0.28.5", - "@vitest/spy": "0.28.5", - "@vitest/utils": "0.28.5", + "@vitest/expect": "0.29.3", + "@vitest/runner": "0.29.3", + "@vitest/spy": "0.29.3", + "@vitest/utils": "0.29.3", "acorn": "^8.8.1", "acorn-walk": "^8.2.0", "cac": "^6.7.14", @@ -13229,7 +13223,7 @@ "tinypool": "^0.3.1", "tinyspy": "^1.0.2", "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.28.5", + "vite-node": "0.29.3", "why-is-node-running": "^2.2.2" }, "dependencies": { diff --git a/package.json b/package.json index 8403380..0bf023d 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "jsdom": "^20.0.0", "prettier": "^2.5.1", "typescript": "^4.7.4", - "vitest": "^0.28.5", + "vitest": "^0.29.3", "vue-tsc": "^0.38.1" }, "engines": { diff --git a/src/data/common.tsx b/src/data/common.tsx index b0becca..d163f72 100644 --- a/src/data/common.tsx +++ b/src/data/common.tsx @@ -1,14 +1,15 @@ import Collapsible from "components/layout/Collapsible.vue"; +import { GenericAchievement } from "features/achievements/achievement"; import type { Clickable, ClickableOptions, GenericClickable } from "features/clickables/clickable"; import { createClickable } from "features/clickables/clickable"; import type { GenericConversion } from "features/conversion"; import type { CoercableComponent, JSXFunction, OptionsFunc, Replace } from "features/feature"; import { jsx, setDefault } from "features/feature"; -import { GenericMilestone } from "features/milestones/milestone"; import { displayResource, Resource } from "features/resources/resource"; import type { GenericTree, GenericTreeNode, TreeNode, TreeNodeOptions } from "features/trees/tree"; import { createTreeNode } from "features/trees/tree"; -import { GenericFormula } from "game/formulas"; +import Formula from "game/formulas/formulas"; +import type { FormulaSource, GenericFormula } from "game/formulas/types"; import type { Modifier } from "game/modifiers"; import type { Persistent } from "game/persistence"; import { DefaultValue, persistent } from "game/persistence"; @@ -383,35 +384,35 @@ export function colorText(textToColor: string, color = "var(--accent2)"): JSX.El } /** - * Creates a collapsible display of a list of milestones - * @param milestones A dictionary of the milestones to display, inserted in the order from easiest to hardest + * Creates a collapsible display of a list of achievements + * @param achievements A dictionary of the achievements to display, inserted in the order from easiest to hardest */ -export function createCollapsibleMilestones(milestones: Record) { - // Milestones are typically defined from easiest to hardest, and we want to show hardest first - const orderedMilestones = Object.values(milestones).reverse(); - const collapseMilestones = persistent(true, false); - const lockedMilestones = computed(() => - orderedMilestones.filter(m => m.earned.value === false) +export function createCollapsibleAchievements(achievements: Record) { + // Achievements are typically defined from easiest to hardest, and we want to show hardest first + const orderedAchievements = Object.values(achievements).reverse(); + const collapseAchievements = persistent(true, false); + const lockedAchievements = computed(() => + orderedAchievements.filter(m => m.earned.value === false) ); const { firstFeature, collapsedContent, hasCollapsedContent } = getFirstFeature( - orderedMilestones, + orderedAchievements, m => m.earned.value ); const display = jsx(() => { - const milestonesToDisplay = [...lockedMilestones.value]; + const achievementsToDisplay = [...lockedAchievements.value]; if (firstFeature.value) { - milestonesToDisplay.push(firstFeature.value); + achievementsToDisplay.push(firstFeature.value); } return renderColJSX( - ...milestonesToDisplay, + ...achievementsToDisplay, jsx(() => ( @@ -419,7 +420,7 @@ export function createCollapsibleMilestones(milestones: Record { if (unref(processedShowPreview)) { @@ -490,3 +491,24 @@ export function createFormulaPreview( return formatSmall(formula.evaluate()); }); } + +export function modifierToFormula( + modifier: WithRequired, + base: T +): T; +export function modifierToFormula(modifier: Modifier, base: FormulaSource): GenericFormula; +export function modifierToFormula(modifier: Modifier, base: FormulaSource) { + return new Formula({ + inputs: [base], + evaluate: val => modifier.apply(val), + invert: + "revert" in modifier && modifier.revert != null + ? (val, lhs) => { + if (lhs instanceof Formula && lhs.hasVariable()) { + return lhs.invert(modifier.revert!(val)); + } + throw new Error("Could not invert due to no input being a variable"); + } + : undefined + }); +} diff --git a/src/data/layers/prestige.tsx b/src/data/layers/prestige.tsx index 4490ded..30fe99f 100644 --- a/src/data/layers/prestige.tsx +++ b/src/data/layers/prestige.tsx @@ -3,7 +3,7 @@ * @hidden */ import { main } from "data/projEntry"; -import { createCumulativeConversion, createPolynomialScaling } from "features/conversion"; +import { createCumulativeConversion } from "features/conversion"; import { jsx } from "features/feature"; import { createHotkey } from "features/hotkey"; import { createReset } from "features/reset"; @@ -23,10 +23,9 @@ const layer = createLayer(id, function (this: BaseLayer) { const points = createResource(0, "prestige points"); const conversion = createCumulativeConversion(() => ({ - scaling: createPolynomialScaling(10, 0.5), + formula: x => x.div(10).sqrt(), baseResource: main.points, - gainResource: points, - roundUpCost: true + gainResource: points })); const reset = createReset(() => ({ diff --git a/src/features/achievements/Achievement.vue b/src/features/achievements/Achievement.vue index 78ac17b..5bc1103 100644 --- a/src/features/achievements/Achievement.vue +++ b/src/features/achievements/Achievement.vue @@ -12,25 +12,26 @@ feature: true, achievement: true, locked: !unref(earned), - bought: unref(earned), + done: unref(earned), + small: unref(small), ...unref(classes) }" > - + - - - diff --git a/src/features/milestones/milestone.tsx b/src/features/milestones/milestone.tsx deleted file mode 100644 index 2796f57..0000000 --- a/src/features/milestones/milestone.tsx +++ /dev/null @@ -1,248 +0,0 @@ -import Select from "components/fields/Select.vue"; -import { Decorator } from "features/decorators/common"; -import type { - CoercableComponent, - GenericComponent, - OptionsFunc, - Replace, - StyleValue -} from "features/feature"; -import { - Component, - GatherProps, - getUniqueID, - isVisible, - jsx, - setDefault, - Visibility -} from "features/feature"; -import MilestoneComponent from "features/milestones/Milestone.vue"; -import { globalBus } from "game/events"; -import "game/notifications"; -import type { Persistent } from "game/persistence"; -import { persistent } from "game/persistence"; -import player from "game/player"; -import settings, { registerSettingField } from "game/settings"; -import { camelToTitle } from "util/common"; -import type { - Computable, - GetComputableType, - GetComputableTypeWithDefault, - ProcessedComputable -} from "util/computed"; -import { processComputable } from "util/computed"; -import { createLazyProxy } from "util/proxies"; -import { coerceComponent, isCoercableComponent } from "util/vue"; -import { computed, unref, watchEffect } from "vue"; -import { useToast } from "vue-toastification"; - -const toast = useToast(); - -export const MilestoneType = Symbol("Milestone"); - -export enum MilestoneDisplay { - All = "all", - //Last = "last", - Configurable = "configurable", - Incomplete = "incomplete", - None = "none" -} - -export interface MilestoneOptions { - visibility?: Computable; - shouldEarn?: () => boolean; - style?: Computable; - classes?: Computable>; - display?: Computable< - | CoercableComponent - | { - requirement: CoercableComponent; - effectDisplay?: CoercableComponent; - optionsDisplay?: CoercableComponent; - } - >; - showPopups?: Computable; - onComplete?: VoidFunction; -} - -export interface BaseMilestone { - id: string; - earned: Persistent; - complete: VoidFunction; - type: typeof MilestoneType; - [Component]: typeof MilestoneComponent; - [GatherProps]: () => Record; -} - -export type Milestone = Replace< - T & BaseMilestone, - { - visibility: GetComputableTypeWithDefault; - style: GetComputableType; - classes: GetComputableType; - display: GetComputableType; - showPopups: GetComputableType; - } ->; - -export type GenericMilestone = Replace< - Milestone, - { - visibility: ProcessedComputable; - } ->; - -export function createMilestone( - optionsFunc?: OptionsFunc, - ...decorators: Decorator[] -): Milestone { - const earned = persistent(false, false); - const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {}); - return createLazyProxy(() => { - const milestone = optionsFunc?.() ?? ({} as ReturnType>); - milestone.id = getUniqueID("milestone-"); - milestone.type = MilestoneType; - milestone[Component] = MilestoneComponent; - - for (const decorator of decorators) { - decorator.preConstruct?.(milestone); - } - - milestone.earned = earned; - Object.assign(milestone, decoratedData); - milestone.complete = function () { - const genericMilestone = milestone as GenericMilestone; - earned.value = true; - genericMilestone.onComplete?.(); - if (genericMilestone.display != null && unref(genericMilestone.showPopups) === true) { - const display = unref(genericMilestone.display); - const Display = coerceComponent( - isCoercableComponent(display) ? display : display.requirement - ); - toast( - <> -

Milestone earned!

-
- {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */} - {/* @ts-ignore */} - -
- - ); - } - }; - - processComputable(milestone as T, "visibility"); - setDefault(milestone, "visibility", Visibility.Visible); - const visibility = milestone.visibility as ProcessedComputable; - milestone.visibility = computed(() => { - const display = unref((milestone as GenericMilestone).display); - switch (settings.msDisplay) { - default: - case MilestoneDisplay.All: - return unref(visibility); - case MilestoneDisplay.Configurable: - if ( - unref(milestone.earned) && - !( - display != null && - typeof display == "object" && - "optionsDisplay" in (display as Record) - ) - ) { - return Visibility.None; - } - return unref(visibility); - case MilestoneDisplay.Incomplete: - if (unref(milestone.earned)) { - return Visibility.None; - } - return unref(visibility); - case MilestoneDisplay.None: - return Visibility.None; - } - }); - - processComputable(milestone as T, "style"); - processComputable(milestone as T, "classes"); - processComputable(milestone as T, "display"); - processComputable(milestone as T, "showPopups"); - - for (const decorator of decorators) { - decorator.postConstruct?.(milestone); - } - - const decoratedProps = decorators.reduce((current, next) => Object.assign(current, next?.getGatheredProps?.(milestone)), {}); - milestone[GatherProps] = function (this: GenericMilestone) { - const { visibility, display, style, classes, earned, id } = this; - return { visibility, display, style: unref(style), classes, earned, id, ...decoratedProps }; - }; - - if (milestone.shouldEarn) { - const genericMilestone = milestone as GenericMilestone; - watchEffect(() => { - if (settings.active !== player.id) return; - if ( - !genericMilestone.earned.value && - isVisible(genericMilestone.visibility) && - genericMilestone.shouldEarn?.() - ) { - genericMilestone.earned.value = true; - genericMilestone.onComplete?.(); - if ( - genericMilestone.display != null && - unref(genericMilestone.showPopups) === true - ) { - const display = unref(genericMilestone.display); - const Display = coerceComponent( - isCoercableComponent(display) ? display : display.requirement - ); - toast( - <> -

Milestone earned!

-
- {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */} - {/* @ts-ignore */} - -
- - ); - } - } - }); - } - - return milestone as unknown as Milestone; - }); -} - -declare module "game/settings" { - interface Settings { - msDisplay: MilestoneDisplay; - } -} - -globalBus.on("loadSettings", settings => { - setDefault(settings, "msDisplay", MilestoneDisplay.All); -}); - -const msDisplayOptions = Object.values(MilestoneDisplay).map(option => ({ - label: camelToTitle(option), - value: option -})); - -registerSettingField( - jsx(() => ( -