This commit is contained in:
Omsi 2022-05-23 08:29:14 -07:00
commit b111d56cf5
336 changed files with 12936 additions and 10584 deletions

View File

@ -1,6 +1,7 @@
{ {
"extends": [ "extends": [
"eslint:recommended", "eslint:recommended",
"plugin:import/recommended",
"plugin:vue/recommended" "plugin:vue/recommended"
], ],
"env": { "env": {
@ -14,7 +15,46 @@
"sourceType": "module", "sourceType": "module",
"parser": "@babel/eslint-parser" "parser": "@babel/eslint-parser"
}, },
"settings": {
"import/resolver": {
"alias": {
"map": [
["@", "./src"]
],
"extensions": [".js", ".vue"]
}
}
},
"rules": { "rules": {
"import/prefer-default-export": "off",
"import/no-unresolved": "error",
"import/named": "error",
"import/namespace": "error",
"import/default": "error",
"import/export": "error",
"import/no-named-as-default": "warn",
"import/no-named-as-default-member": "warn",
"import/no-duplicates": "warn",
"import/extensions": ["warn", "never"],
"import/first": "warn",
"import/newline-after-import": "warn",
"import/no-named-default": "warn",
"import/no-self-import": "warn",
"import/order": [
"warn",
{
"newlines-between": "always-and-inside-groups",
"pathGroups": [{ "pattern": "@/**", "group": "sibling" }]
}
],
"sort-imports": [
"warn",
{
"ignoreCase": true,
"allowSeparatedGroups": true
}
],
"no-console": "warn", "no-console": "warn",
"no-template-curly-in-string": "warn", "no-template-curly-in-string": "warn",
"array-callback-return": "error", "array-callback-return": "error",
@ -32,7 +72,6 @@
"allowElseIf": false "allowElseIf": false
} }
], ],
"vue/one-component-per-file": "error", "vue/one-component-per-file": "error",
"vue/component-definition-name-casing": "warn", "vue/component-definition-name-casing": "warn",
"vue/order-in-components": "warn", "vue/order-in-components": "warn",

3
.stylelintignore Normal file
View File

@ -0,0 +1,3 @@
public/stylesheets/fontawesome/**/*.css
public/stylesheets/codemirror/*.css
public/stylesheets/vis-network.css

425
.stylelintrc.json Normal file
View File

@ -0,0 +1,425 @@
{
"plugins": [
"stylelint-order"
],
"extends": [
"stylelint-config-standard"
],
"rules": {
"no-descending-specificity": null,
"font-family-no-missing-generic-family-keyword": null,
"no-empty-source": null,
"color-hex-length": "long",
"custom-property-empty-line-before": null,
"color-function-notation": null,
"declaration-empty-line-before": null,
"comment-empty-line-before": null,
"property-no-vendor-prefix": [
true,
{
"ignoreProperties": ["appearance", "background-clip", "backdrop-filter", "clip-path", "user-select"]
}
],
"unit-allowed-list": [
"rem",
"%",
"px",
"deg",
"s",
"ms",
"fr"
],
"custom-property-pattern": [
"^([_a-z][a-z0-9]*)([-_]{1,2}[a-z0-9]+)*$",
{
"message": "Expected custom property name to be kebab-case"
}
],
"selector-class-pattern": [
"^(CodeMirror.*|([_a-z][a-z0-9]*)([-_]{1,2}[a-z0-9]+)*)$",
{
"message": "Expected class selector name to be kebab-case"
}
],
"keyframes-name-pattern": [
"^a-([-_]{0,2}[a-z0-9]+)*$",
{
"message": "Keyframe name must begin with `a-` and be kebab-case"
}
],
"selector-id-pattern": [
"^([_a-z][a-z0-9]*)([-_]{1,2}[a-z0-9]+)*$",
{
"message": "Expected id selector name to be kebab-case"
}
],
"order/order": [
"custom-properties",
"at-rules",
"rules",
"declarations"
],
"order/properties-order": [
[
{
"groupName": "content",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"content"
]
},
{
"groupName": "display",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"display",
"visibility",
"float",
"clear",
"resize",
"overflow",
"overflow-x",
"overflow-y",
"white-space",
"word-break",
"overflow-wrap",
"tab-size",
"clip",
"zoom"
]
},
{
"groupName": "flex",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"flex",
"flex-grow",
"flex-shrink",
"flex-basis",
"flex-flow",
"flex-direction",
"flex-wrap"
]
},
{
"groupName": "grid",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"grid",
"grid-auto-columns",
"grid-auto-flow",
"grid-auto-rows",
"grid-template-areas",
"grid-template-columns",
"grid-template-rows",
"grid-row-gap",
"grid-column-gap",
"row-gap",
"column-gap",
"grid-row",
"grid-row-start",
"grid-row-end",
"grid-column",
"grid-column-start",
"grid-column-end"
]
},
{
"groupName": "table",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image"
]
},
{
"groupName": "size",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"width",
"height",
"min-width",
"max-width",
"min-height",
"max-height"
]
},
{
"groupName": "position",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"position",
"will-change",
"inset",
"top",
"right",
"bottom",
"left",
"z-index"
]
},
{
"groupName": "alignment",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"place-content",
"justify-content",
"align-content",
"align-items",
"align-self",
"vertical-align",
"text-align",
"text-align-last"
]
},
{
"groupName": "scrollbar",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"scrollbar-color",
"scrollbar-width"
]
},
{
"groupName": "svg",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"stroke",
"stroke-width",
"stroke-linecap",
"stroke-dasharray",
"fill",
"text-anchor"
]
},
{
"groupName": "font",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"font",
"font-family",
"font-size",
"font-stretch",
"font-style",
"font-variant",
"font-weight",
"font-smoothing",
"font-smooth",
"line-height",
"src",
"unicode-range"
]
},
{
"groupName": "color",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"opacity",
"color"
]
},
{
"groupName": "text",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"text-shadow",
"text-decoration"
]
},
"appearance",
{
"groupName": "background",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"background",
"background-attachment",
"background-clip",
"background-color",
"background-image",
"background-origin",
"background-position",
"background-position-x",
"background-position-y",
"background-repeat",
"background-size"
]
},
{
"groupName": "border",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"border",
"border-color",
"border-style",
"border-width",
"border-top",
"border-top-color",
"border-top-style",
"border-top-width",
"border-right",
"border-right-color",
"border-right-style",
"border-right-width",
"border-bottom",
"border-bottom-color",
"border-bottom-style",
"border-bottom-width",
"border-left",
"border-left-color",
"border-left-style",
"border-left-width",
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"border-spacing"
]
},
{
"groupName": "box",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"box-shadow",
"box-sizing"
]
},
{
"groupName": "outline",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset"
]
},
{
"groupName": "margin",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left"
]
},
{
"groupName": "padding",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left"
]
},
{
"groupName": "animation",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"transform",
"transform-origin",
"filter",
"mix-blend-mode",
"transition",
"transition-delay",
"transition-timing-function",
"transition-duration",
"transition-property",
"animation",
"animation-name",
"animation-duration",
"animation-play-state",
"animation-timing-function",
"animation-delay",
"animation-iteration-count",
"animation-direction",
"animation-fill-mode"
]
},
{
"groupName": "pointer",
"emptyLineBefore": "never",
"noEmptyLineBetween": true,
"properties": [
"pointer-events",
"user-select",
"cursor"
]
}
],
{
"unspecified": "bottomAlphabetical",
"emptyLineBeforeUnspecified": "always"
}
]
},
"overrides": [
{
"files": [
"*.vue",
"**/*.vue"
],
"extends": [
"stylelint-config-recommended",
"stylelint-config-html"
],
"rules": {
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": [
"deep",
"global"
]
}
],
"selector-pseudo-element-no-unknown": [
true,
{
"ignorePseudoElements": [
"v-deep",
"v-global",
"v-slotted"
]
}
]
}
}
]
}

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "../game-mechanics/index.js"; import { GameMechanicState } from "../game-mechanics/index";
class AchievementState extends GameMechanicState { class AchievementState extends GameMechanicState {
constructor(config) { constructor(config) {

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "../game-mechanics/index.js"; import { GameMechanicState } from "../game-mechanics/index";
class SecretAchievementState extends GameMechanicState { class SecretAchievementState extends GameMechanicState {
constructor(config) { constructor(config) {

View File

@ -1,92 +1,88 @@
import MessageModal from "@/components/modals/MessageModal";
import CelestialQuoteModal from "@/components/modals/CelestialQuoteModal"; import CelestialQuoteModal from "@/components/modals/CelestialQuoteModal";
import CloudSaveConflictModal from "@/components/modals/cloud/CloudSaveConflictModal";
import CloudLoadConflictModal from "@/components/modals/cloud/CloudLoadConflictModal"; import CloudLoadConflictModal from "@/components/modals/cloud/CloudLoadConflictModal";
import CloudSaveConflictModal from "@/components/modals/cloud/CloudSaveConflictModal";
import EternityChallengeStartModal from "@/components/modals/challenges/EternityChallengeStartModal"; import EternityChallengeStartModal from "@/components/modals/challenges/EternityChallengeStartModal";
import InfinityChallengeStartModal from "@/components/modals/challenges/InfinityChallengeStartModal"; import InfinityChallengeStartModal from "@/components/modals/challenges/InfinityChallengeStartModal";
import MessageModal from "@/components/modals/MessageModal";
import NormalChallengeStartModal from "@/components/modals/challenges/NormalChallengeStartModal"; import NormalChallengeStartModal from "@/components/modals/challenges/NormalChallengeStartModal";
import DimensionBoostModal from "@/components/modals/prestige/DimensionBoostModal";
import AntimatterGalaxyModal from "@/components/modals/prestige/AntimatterGalaxyModal"; import AntimatterGalaxyModal from "@/components/modals/prestige/AntimatterGalaxyModal";
import BigCrunchModal from "@/components/modals/prestige/BigCrunchModal";
import ReplicantiGalaxyModal from "@/components/modals/prestige/ReplicantiGalaxyModal";
import EternityModal from "@/components/modals/prestige/EternityModal";
import EnterDilationModal from "@/components/modals/prestige/EnterDilationModal";
import RealityModal from "@/components/modals/prestige/RealityModal";
import ResetRealityModal from "@/components/modals/prestige/ResetRealityModal";
import ExitCelestialModal from "@/components/modals/prestige/ExitCelestialModal";
import EnterCelestialsModal from "@/components/modals/prestige/EnterCelestialsModal";
import HardResetModal from "@/components/modals/prestige/HardResetModal";
import SpeedrunModeModal from "@/components/modals/SpeedrunModeModal";
import ChangeNameModal from "@/components/modals/ChangeNameModal";
import ArmageddonModal from "@/components/modals/prestige/ArmageddonModal"; import ArmageddonModal from "@/components/modals/prestige/ArmageddonModal";
import BigCrunchModal from "@/components/modals/prestige/BigCrunchModal";
import ChangeNameModal from "@/components/modals/ChangeNameModal";
import DimensionBoostModal from "@/components/modals/prestige/DimensionBoostModal";
import EnterCelestialsModal from "@/components/modals/prestige/EnterCelestialsModal";
import EnterDilationModal from "@/components/modals/prestige/EnterDilationModal";
import EternityModal from "@/components/modals/prestige/EternityModal";
import ExitCelestialModal from "@/components/modals/prestige/ExitCelestialModal";
import HardResetModal from "@/components/modals/prestige/HardResetModal";
import RealityModal from "@/components/modals/prestige/RealityModal";
import ReplicantiGalaxyModal from "@/components/modals/prestige/ReplicantiGalaxyModal";
import ResetRealityModal from "@/components/modals/prestige/ResetRealityModal";
import SpeedrunModeModal from "@/components/modals/SpeedrunModeModal";
import ConfirmationOptionsModal from "@/components/modals/options/ConfirmationOptionsModal";
import InfoDisplayOptionsModal from "@/components/modals/options/InfoDisplayOptionsModal";
import AwayProgressOptionsModal from "@/components/modals/options/AwayProgressOptionsModal";
import HotkeysModal from "@/components/modals/options/HotkeysModal";
import NewsOptionsModal from "@/components/modals/options/NewsOptionsModal";
import AnimationOptionsModal from "@/components/modals/options/AnimationOptionsModal"; import AnimationOptionsModal from "@/components/modals/options/AnimationOptionsModal";
import PreferredTreeModal from "@/components/modals/options/PreferredTreeModal"; import AwayProgressOptionsModal from "@/components/modals/options/AwayProgressOptionsModal";
import ConfirmationOptionsModal from "@/components/modals/options/ConfirmationOptionsModal";
import HiddenTabsModal from "@/components/modals/options/hidden-tabs/HiddenTabsModal"; import HiddenTabsModal from "@/components/modals/options/hidden-tabs/HiddenTabsModal";
import HotkeysModal from "@/components/modals/options/HotkeysModal";
import InfoDisplayOptionsModal from "@/components/modals/options/InfoDisplayOptionsModal";
import NewsOptionsModal from "@/components/modals/options/NewsOptionsModal";
import PreferredTreeModal from "@/components/modals/options/PreferredTreeModal";
import DeleteCompanionGlyphModal from "@/components/modals/glyph-management/DeleteCompanionGlyphModal"; import DeleteCompanionGlyphModal from "@/components/modals/glyph-management/DeleteCompanionGlyphModal";
import DeleteGlyphModal from "@/components/modals/glyph-management/DeleteGlyphModal"; import DeleteGlyphModal from "@/components/modals/glyph-management/DeleteGlyphModal";
import PurgeGlyphModal from "@/components/modals/glyph-management/PurgeGlyphModal";
import SacrificeGlyphModal from "@/components/modals/glyph-management/SacrificeGlyphModal";
import RefineGlyphModal from "@/components/modals/glyph-management/RefineGlyphModal";
import PurgeAllUnprotectedGlyphsModal from "@/components/modals/glyph-management/PurgeAllUnprotectedGlyphsModal";
import PurgeAllRejectedGlyphsModal from "@/components/modals/glyph-management/PurgeAllRejectedGlyphsModal"; import PurgeAllRejectedGlyphsModal from "@/components/modals/glyph-management/PurgeAllRejectedGlyphsModal";
import PurgeAllUnprotectedGlyphsModal from "@/components/modals/glyph-management/PurgeAllUnprotectedGlyphsModal";
import PurgeGlyphModal from "@/components/modals/glyph-management/PurgeGlyphModal";
import RefineGlyphModal from "@/components/modals/glyph-management/RefineGlyphModal";
import SacrificeGlyphModal from "@/components/modals/glyph-management/SacrificeGlyphModal";
import H2PModal from "@/components/modals/H2PModal";
import InformationModal from "@/components/modals/InformationModal";
import GlyphShowcasePanelModal from "@/components/modals/GlyphShowcasePanelModal";
import UndoGlyphModal from "@/components/modals/UndoGlyphModal";
import ReplaceGlyphModal from "@/components/modals/ReplaceGlyphModal";
import UiChoiceModal from "@/components/modals/UiChoiceModal";
import AwayProgressModal from "@/components/modals/AwayProgressModal";
import LoadGameModal from "@/components/modals/LoadGameModal";
import ImportSaveModal from "@/components/modals/ImportSaveModal";
import ImportAutomatorScriptModal from "@/components/modals/ImportAutomatorScriptModal";
import DeleteAutomatorScriptModal from "@/components/modals/DeleteAutomatorScriptModal";
import AutomatorScriptTemplate from "@/components/modals/AutomatorScriptTemplate"; import AutomatorScriptTemplate from "@/components/modals/AutomatorScriptTemplate";
import AwayProgressModal from "@/components/modals/AwayProgressModal";
import BreakInfinityModal from "@/components/modals/BreakInfinityModal";
import DeleteAutomatorScriptModal from "@/components/modals/DeleteAutomatorScriptModal";
import EnslavedHintsModal from "@/components/modals/EnslavedHintsModal";
import GlyphSetSaveDeleteModal from "@/components/modals/GlyphSetSaveDeleteModal";
import GlyphShowcasePanelModal from "@/components/modals/GlyphShowcasePanelModal";
import H2PModal from "@/components/modals/H2PModal";
import ImportAutomatorScriptModal from "@/components/modals/ImportAutomatorScriptModal";
import ImportSaveModal from "@/components/modals/ImportSaveModal";
import InformationModal from "@/components/modals/InformationModal";
import LoadGameModal from "@/components/modals/LoadGameModal";
import PelleEffectsModal from "@/components/modals/PelleEffectsModal";
import RealityGlyphCreationModal from "@/components/modals/RealityGlyphCreationModal";
import ReplaceGlyphModal from "@/components/modals/ReplaceGlyphModal";
import SacrificeModal from "@/components/modals/SacrificeModal";
import SingularityMilestonesModal from "@/components/modals/SingularityMilestonesModal";
import StdStoreModal from "@/components/modals/StdStoreModal"; import StdStoreModal from "@/components/modals/StdStoreModal";
import StudyStringModal from "@/components/modals/StudyStringModal"; import StudyStringModal from "@/components/modals/StudyStringModal";
import SacrificeModal from "@/components/modals/SacrificeModal"; import SwitchAutomatorEditorModal from "@/components/modals/SwitchAutomatorEditorModal";
import BreakInfinityModal from "@/components/modals/BreakInfinityModal"; import UiChoiceModal from "@/components/modals/UiChoiceModal";
import GlyphSetSaveDeleteModal from "@/components/modals/GlyphSetSaveDeleteModal"; import UndoGlyphModal from "@/components/modals/UndoGlyphModal";
import RealityGlyphCreationModal from "@/components/modals/RealityGlyphCreationModal";
import EnslavedHintsModal from "@/components/modals/EnslavedHintsModal";
import SingularityMilestonesModal from "@/components/modals/SingularityMilestonesModal";
import PelleEffectsModal from "@/components/modals/PelleEffectsModal";
export class Modal { export class Modal {
constructor(component, bare = false) { constructor(component, priority = 0, bare = false) {
this._component = component; this._component = component;
this._bare = bare; this._bare = bare;
this._modalConfig = {}; this._modalConfig = {};
this._prioritize = false; this._priority = priority;
} }
show(modalConfig) { show(modalConfig) {
if (!GameUI.initialized) return; if (!GameUI.initialized) return;
this._props = Object.assign({}, modalConfig || {}); this._props = Object.assign({}, modalConfig || {});
if (ui.view.modal.queue.length === 0) ui.view.modal.current = this;
// New modals go to the back of the queue (shown last).
if (!ui.view.modal.queue.includes(this)) {
if (this._prioritize) {
ui.view.modal.queue.unshift(this);
ui.view.modal.current = this;
} else {
ui.view.modal.queue.push(this);
}
}
}
prioritize() { const modalQueue = ui.view.modal.queue;
this._prioritize = true; // Add this modal to the front of the queue and sort based on priority to ensure priority is maintained.
return this; modalQueue.unshift(this);
modalQueue.sort((x, y) => y.priority - x.priority);
// Filter out multiple instances of the same modal.
const singleQueue = [...new Set(modalQueue)];
ui.view.modal.queue = singleQueue;
// If the front of the queue is what is currently presented, we dont need to do anything.
if (!singleQueue[0].isOpen) ui.view.modal.current = singleQueue[0];
} }
get isOpen() { get isOpen() {
@ -105,6 +101,10 @@ export class Modal {
return this._props; return this._props;
} }
get priority() {
return this._priority;
}
static hide() { static hide() {
if (!GameUI.initialized) return; if (!GameUI.initialized) return;
ui.view.modal.queue.shift(); ui.view.modal.queue.shift();
@ -132,8 +132,7 @@ export class Modal {
class ChallengeConfirmationModal extends Modal { class ChallengeConfirmationModal extends Modal {
show(id) { show(id) {
this.id = id; super.show({ id });
super.show();
} }
} }
@ -144,20 +143,20 @@ Modal.startEternityChallenge = new ChallengeConfirmationModal(EternityChallengeS
Modal.startInfinityChallenge = new ChallengeConfirmationModal(InfinityChallengeStartModal); Modal.startInfinityChallenge = new ChallengeConfirmationModal(InfinityChallengeStartModal);
Modal.startNormalChallenge = new ChallengeConfirmationModal(NormalChallengeStartModal); Modal.startNormalChallenge = new ChallengeConfirmationModal(NormalChallengeStartModal);
Modal.dimensionBoost = new Modal(DimensionBoostModal).prioritize(); Modal.dimensionBoost = new Modal(DimensionBoostModal, 1);
Modal.antimatterGalaxy = new Modal(AntimatterGalaxyModal).prioritize(); Modal.antimatterGalaxy = new Modal(AntimatterGalaxyModal, 1);
Modal.bigCrunch = new Modal(BigCrunchModal).prioritize(); Modal.bigCrunch = new Modal(BigCrunchModal, 1);
Modal.replicantiGalaxy = new Modal(ReplicantiGalaxyModal).prioritize(); Modal.replicantiGalaxy = new Modal(ReplicantiGalaxyModal, 1);
Modal.eternity = new Modal(EternityModal).prioritize(); Modal.eternity = new Modal(EternityModal, 1);
Modal.enterDilation = new Modal(EnterDilationModal).prioritize(); Modal.enterDilation = new Modal(EnterDilationModal, 1);
Modal.reality = new Modal(RealityModal).prioritize(); Modal.reality = new Modal(RealityModal, 1);
Modal.resetReality = new Modal(ResetRealityModal).prioritize(); Modal.resetReality = new Modal(ResetRealityModal, 1);
Modal.exitCelestialReality = new Modal(ExitCelestialModal).prioritize(); Modal.exitCelestialReality = new Modal(ExitCelestialModal, 1);
Modal.celestials = new Modal(EnterCelestialsModal).prioritize(); Modal.celestials = new Modal(EnterCelestialsModal, 1);
Modal.hardReset = new Modal(HardResetModal).prioritize(); Modal.hardReset = new Modal(HardResetModal, 1);
Modal.enterSpeedrun = new Modal(SpeedrunModeModal); Modal.enterSpeedrun = new Modal(SpeedrunModeModal);
Modal.changeName = new Modal(ChangeNameModal); Modal.changeName = new Modal(ChangeNameModal);
Modal.armageddon = new Modal(ArmageddonModal).prioritize(); Modal.armageddon = new Modal(ArmageddonModal, 1);
Modal.confirmationOptions = new Modal(ConfirmationOptionsModal); Modal.confirmationOptions = new Modal(ConfirmationOptionsModal);
Modal.infoDisplayOptions = new Modal(InfoDisplayOptionsModal); Modal.infoDisplayOptions = new Modal(InfoDisplayOptionsModal);
@ -168,16 +167,16 @@ Modal.animationOptions = new Modal(AnimationOptionsModal);
Modal.hiddenTabs = new Modal(HiddenTabsModal); Modal.hiddenTabs = new Modal(HiddenTabsModal);
Modal.preferredTree = new Modal(PreferredTreeModal); Modal.preferredTree = new Modal(PreferredTreeModal);
Modal.deleteCompanion = new Modal(DeleteCompanionGlyphModal).prioritize(); Modal.deleteCompanion = new Modal(DeleteCompanionGlyphModal, 1);
Modal.glyphDelete = new Modal(DeleteGlyphModal).prioritize(); Modal.glyphDelete = new Modal(DeleteGlyphModal, 1);
Modal.glyphPurge = new Modal(PurgeGlyphModal).prioritize(); Modal.glyphPurge = new Modal(PurgeGlyphModal, 1);
Modal.glyphSacrifice = new Modal(SacrificeGlyphModal).prioritize(); Modal.glyphSacrifice = new Modal(SacrificeGlyphModal, 1);
Modal.glyphRefine = new Modal(RefineGlyphModal).prioritize(); Modal.glyphRefine = new Modal(RefineGlyphModal, 1);
Modal.deleteAllUnprotectedGlyphs = new Modal(PurgeAllUnprotectedGlyphsModal).prioritize(); Modal.deleteAllUnprotectedGlyphs = new Modal(PurgeAllUnprotectedGlyphsModal, 1);
Modal.deleteAllRejectedGlyphs = new Modal(PurgeAllRejectedGlyphsModal).prioritize(); Modal.deleteAllRejectedGlyphs = new Modal(PurgeAllRejectedGlyphsModal, 1);
Modal.glyphShowcasePanel = new Modal(GlyphShowcasePanelModal); Modal.glyphShowcasePanel = new Modal(GlyphShowcasePanelModal);
Modal.glyphUndo = new Modal(UndoGlyphModal).prioritize(); Modal.glyphUndo = new Modal(UndoGlyphModal, 1);
Modal.glyphReplace = new Modal(ReplaceGlyphModal); Modal.glyphReplace = new Modal(ReplaceGlyphModal);
Modal.enslavedHints = new Modal(EnslavedHintsModal); Modal.enslavedHints = new Modal(EnslavedHintsModal);
Modal.realityGlyph = new Modal(RealityGlyphCreationModal); Modal.realityGlyph = new Modal(RealityGlyphCreationModal);
@ -191,12 +190,13 @@ Modal.import = new Modal(ImportSaveModal);
Modal.importScript = new Modal(ImportAutomatorScriptModal); Modal.importScript = new Modal(ImportAutomatorScriptModal);
Modal.automatorScriptDelete = new Modal(DeleteAutomatorScriptModal); Modal.automatorScriptDelete = new Modal(DeleteAutomatorScriptModal);
Modal.automatorScriptTemplate = new Modal(AutomatorScriptTemplate); Modal.automatorScriptTemplate = new Modal(AutomatorScriptTemplate);
Modal.switchAutomatorEditorMode = new Modal(SwitchAutomatorEditorModal);
Modal.shop = new Modal(StdStoreModal); Modal.shop = new Modal(StdStoreModal);
Modal.studyString = new Modal(StudyStringModal); Modal.studyString = new Modal(StudyStringModal);
Modal.singularityMilestones = new Modal(SingularityMilestonesModal); Modal.singularityMilestones = new Modal(SingularityMilestonesModal);
Modal.pelleEffects = new Modal(PelleEffectsModal); Modal.pelleEffects = new Modal(PelleEffectsModal);
Modal.sacrifice = new Modal(SacrificeModal).prioritize(); Modal.sacrifice = new Modal(SacrificeModal, 1);
Modal.breakInfinity = new Modal(BreakInfinityModal); Modal.breakInfinity = new Modal(BreakInfinityModal, 1);
Modal.celestialQuote = new class extends Modal { Modal.celestialQuote = new class extends Modal {
show(celestial, lines) { show(celestial, lines) {
if (!GameUI.initialized || player.speedrun.isActive) return; if (!GameUI.initialized || player.speedrun.isActive) return;
@ -245,7 +245,7 @@ Modal.celestialQuote = new class extends Modal {
} }
return x; return x;
} }
}(CelestialQuoteModal, true); }(CelestialQuoteModal, 2, true);
Modal.cloudSaveConflict = new Modal(CloudSaveConflictModal); Modal.cloudSaveConflict = new Modal(CloudSaveConflictModal);
Modal.cloudLoadConflict = new Modal(CloudLoadConflictModal); Modal.cloudLoadConflict = new Modal(CloudLoadConflictModal);
@ -319,4 +319,4 @@ Modal.message = new class extends Modal {
this.closeButton = this.queue[0].closeButton; this.closeButton = this.queue[0].closeButton;
} }
} }
}(MessageModal); }(MessageModal, 2);

View File

@ -1,5 +1,7 @@
import { sha512_256 } from "js-sha512"; import { sha512_256 } from "js-sha512";
import FullScreenAnimationHandler from "../full-screen-animation-handler";
export class GameOptions { export class GameOptions {
static toggleNews() { static toggleNews() {
@ -65,10 +67,9 @@ export function isSecretImport(data) {
export function tryImportSecret(data) { export function tryImportSecret(data) {
const index = secretImportIndex(data); const index = secretImportIndex(data);
if (index === 0 && document.body.style.animation === "") { if (index === 0) {
document.body.style.animation = "barrelRoll 5s 1"; FullScreenAnimationHandler.display("a-barrel-roll", 5);
SecretAchievement(15).unlock(); SecretAchievement(15).unlock();
setTimeout(() => document.body.style.animation = "", 5000);
return true; return true;
} }
if (index === 1) { if (index === 1) {

View File

@ -1,4 +1,3 @@
// eslint-disable-next-line prefer-const
export const state = { export const state = {
view: { view: {
modal: { modal: {

View File

@ -1,8 +1,10 @@
import { notify } from "./notify.js";
import { state } from "./ui.init.js";
import VTooltip from "v-tooltip"; import VTooltip from "v-tooltip";
import { useLongPress, useRepeatingClick } from "./longpress";
import VueGtag from "vue-gtag"; import VueGtag from "vue-gtag";
import { useLongPress, useRepeatingClick } from "./longpress";
import { notify } from "./notify";
import { state } from "./ui.init";
import GameUIComponent from "@/components/GameUIComponent"; import GameUIComponent from "@/components/GameUIComponent";
Vue.mixin({ Vue.mixin({
@ -95,7 +97,7 @@ const ReactivityComplainer = {
throw new Error(`Boi you fukked up - ${path} became REACTIVE (oh shite)`); throw new Error(`Boi you fukked up - ${path} became REACTIVE (oh shite)`);
} }
for (const key in obj) { for (const key in obj) {
if (!obj.hasOwnProperty(key)) continue; if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
const prop = obj[key]; const prop = obj[key];
if (typeof prop === "object") { if (typeof prop === "object") {
this.checkReactivity(prop, `${path}.${key}`); this.checkReactivity(prop, `${path}.${key}`);

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.annihilation = new class AnnihilationAutobuyerState extends AutobuyerState { Autobuyer.annihilation = new class AnnihilationAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,5 +1,6 @@
import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer.js"; import { DC } from "../constants";
import { DC } from "../constants.js";
import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer";
class AntimatterDimensionAutobuyerState extends UpgradeableAutobuyerState { class AntimatterDimensionAutobuyerState extends UpgradeableAutobuyerState {
get tier() { get tier() {

View File

@ -1,4 +1,4 @@
import { Autobuyer } from "./autobuyer.js"; import { Autobuyer } from "./autobuyer";
export const Autobuyers = (function() { export const Autobuyers = (function() {
const antimatterDimensions = Autobuyer.antimatterDimension.zeroIndexed; const antimatterDimensions = Autobuyer.antimatterDimension.zeroIndexed;

View File

@ -1,4 +1,4 @@
import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer.js"; import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer";
Autobuyer.bigCrunch = new class BigCrunchAutobuyerState extends UpgradeableAutobuyerState { Autobuyer.bigCrunch = new class BigCrunchAutobuyerState extends UpgradeableAutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
class BlackHolePowerAutobuyerState extends AutobuyerState { class BlackHolePowerAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js"; import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
Autobuyer.darkMatterDimsAscension = Autobuyer.darkMatterDimsAscension =
new class DarkMatterDimensionAscensionAutobuyerState extends IntervaledAutobuyerState { new class DarkMatterDimensionAscensionAutobuyerState extends IntervaledAutobuyerState {

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js"; import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
Autobuyer.darkMatterDims = new class DarkMatterDimensionAutobuyerState extends IntervaledAutobuyerState { Autobuyer.darkMatterDims = new class DarkMatterDimensionAutobuyerState extends IntervaledAutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js"; import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
class DilationUpgradeAutobuyerState extends IntervaledAutobuyerState { class DilationUpgradeAutobuyerState extends IntervaledAutobuyerState {
get _upgradeName() { return ["dtGain", "galaxyThreshold", "tachyonGain"][this.id - 1]; } get _upgradeName() { return ["dtGain", "galaxyThreshold", "tachyonGain"][this.id - 1]; }

View File

@ -1,4 +1,4 @@
import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer.js"; import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer";
Autobuyer.dimboost = new class DimBoostAutobuyerState extends UpgradeableAutobuyerState { Autobuyer.dimboost = new class DimBoostAutobuyerState extends UpgradeableAutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.eternity = new class EternityAutobuyerState extends AutobuyerState { Autobuyer.eternity = new class EternityAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer.js"; import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer";
Autobuyer.galaxy = new class GalaxyAutobuyerState extends UpgradeableAutobuyerState { Autobuyer.galaxy = new class GalaxyAutobuyerState extends UpgradeableAutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
class ImaginaryUpgradeAutobuyerState extends AutobuyerState { class ImaginaryUpgradeAutobuyerState extends AutobuyerState {
get name() { get name() {

View File

@ -1,27 +1,27 @@
import "./autobuyer.js"; import "./autobuyer";
import "./antimatter-dimension-autobuyer.js"; import "./antimatter-dimension-autobuyer";
import "./tickspeed-autobuyer.js"; import "./tickspeed-autobuyer";
import "./dimboost-autobuyer.js"; import "./dimboost-autobuyer";
import "./galaxy-autobuyer.js"; import "./galaxy-autobuyer";
import "./big-crunch-autobuyer.js"; import "./big-crunch-autobuyer";
import "./sacrifice-autobuyer.js"; import "./sacrifice-autobuyer";
import "./eternity-autobuyer.js"; import "./eternity-autobuyer";
import "./reality-autobuyer.js"; import "./reality-autobuyer";
import "./infinity-dimension-autobuyer.js"; import "./infinity-dimension-autobuyer";
import "./time-dimension-autobuyer.js"; import "./time-dimension-autobuyer";
import "./time-theorem-autobuyer.js"; import "./time-theorem-autobuyer";
import "./black-hole-power-autobuyer.js"; import "./black-hole-power-autobuyer";
import "./reality-upgrade-autobuyer.js"; import "./reality-upgrade-autobuyer";
import "./imaginary-upgrade-autobuyer.js"; import "./imaginary-upgrade-autobuyer";
import "./replicanti-upgrade-autobuyer.js"; import "./replicanti-upgrade-autobuyer";
import "./dilation-upgrade-autobuyer.js"; import "./dilation-upgrade-autobuyer";
import "./prestige-currency-multiplier-autobuyer.js"; import "./prestige-currency-multiplier-autobuyer";
import "./replicanti-galaxy-autobuyer.js"; import "./replicanti-galaxy-autobuyer";
import "./dark-matter-dimension-autobuyer.js"; import "./dark-matter-dimension-autobuyer";
import "./dark-matter-dimension-ascension-autobuyer.js"; import "./dark-matter-dimension-ascension-autobuyer";
import "./singularity-autobuyer.js"; import "./singularity-autobuyer";
import "./annihilation-autobuyer.js"; import "./annihilation-autobuyer";
export * from "./autobuyers.js"; export * from "./autobuyers";

View File

@ -1,5 +1,6 @@
import { InfinityDimensions } from "../globals.js"; import { InfinityDimensions } from "../globals";
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js";
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
class InfinityDimensionAutobuyerState extends IntervaledAutobuyerState { class InfinityDimensionAutobuyerState extends IntervaledAutobuyerState {
get tier() { get tier() {
@ -27,7 +28,7 @@ class InfinityDimensionAutobuyerState extends IntervaledAutobuyerState {
} }
get isUnlocked() { get isUnlocked() {
return EternityMilestone.autobuyerID(this.tier).isReached || PelleUpgrade.IDAutobuyers.canBeApplied; return EternityMilestone[`autobuyerID${this.tier}`].isReached || PelleUpgrade.IDAutobuyers.canBeApplied;
} }
get resetTickOn() { get resetTickOn() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.ipMult = new class IPMultAutobuyerState extends AutobuyerState { Autobuyer.ipMult = new class IPMultAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.reality = new class RealityAutobuyerState extends AutobuyerState { Autobuyer.reality = new class RealityAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
class RealityUpgradeAutobuyerState extends AutobuyerState { class RealityUpgradeAutobuyerState extends AutobuyerState {
get name() { get name() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.replicantiGalaxy = new class ReplicantiGalaxyAutobuyerState extends AutobuyerState { Autobuyer.replicantiGalaxy = new class ReplicantiGalaxyAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js"; import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
class ReplicantiUpgradeAutobuyerState extends IntervaledAutobuyerState { class ReplicantiUpgradeAutobuyerState extends IntervaledAutobuyerState {
get _upgradeName() { return ["chance", "interval", "galaxies"][this.id - 1]; } get _upgradeName() { return ["chance", "interval", "galaxies"][this.id - 1]; }

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.sacrifice = new class SacrificeAutobuyerState extends AutobuyerState { Autobuyer.sacrifice = new class SacrificeAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.singularity = new class SingularityAutobuyerState extends AutobuyerState { Autobuyer.singularity = new class SingularityAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -1,5 +1,6 @@
import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer.js"; import { DC } from "../constants";
import { DC } from "../constants.js";
import { Autobuyer, UpgradeableAutobuyerState } from "./autobuyer";
Autobuyer.tickspeed = new class TickspeedAutobuyerState extends UpgradeableAutobuyerState { Autobuyer.tickspeed = new class TickspeedAutobuyerState extends UpgradeableAutobuyerState {
get data() { get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js"; import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
class TimeDimensionAutobuyerState extends IntervaledAutobuyerState { class TimeDimensionAutobuyerState extends IntervaledAutobuyerState {
get tier() { get tier() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js"; import { Autobuyer, AutobuyerState } from "./autobuyer";
Autobuyer.timeTheorem = new class TimeTheoremAutobuyerState extends AutobuyerState { Autobuyer.timeTheorem = new class TimeTheoremAutobuyerState extends AutobuyerState {
get data() { get data() {

View File

@ -111,7 +111,6 @@ class AutomatorStackEntry {
export class AutomatorScript { export class AutomatorScript {
constructor(id) { constructor(id) {
if (!id) throw new Error("Invalid Automator script ID");
this._id = id; this._id = id;
this.compile(); this.compile();
} }
@ -183,7 +182,7 @@ export const AutomatorData = {
createNewScript(newScript, name) { createNewScript(newScript, name) {
const newScriptID = Object.values(player.reality.automator.scripts).length + 1; const newScriptID = Object.values(player.reality.automator.scripts).length + 1;
player.reality.automator.scripts[newScriptID] = { player.reality.automator.scripts[newScriptID] = {
id: `${newScriptID}`, id: newScriptID,
name, name,
content: newScript content: newScript
}; };
@ -243,12 +242,31 @@ export const AutomatorBackend = {
return this.isOn && this.mode === AUTOMATOR_MODE.RUN; return this.isOn && this.mode === AUTOMATOR_MODE.RUN;
}, },
findRawScriptObject(id) {
const auto = player.reality.automator;
const index = Object.values(auto.scripts).findIndex(s => s.id === id);
return auto.scripts[parseInt(Object.keys(auto.scripts)[index], 10)];
},
get currentRunningScript() {
return this.findRawScriptObject(this.state.topLevelScript);
},
get currentEditingScript() {
return this.findRawScriptObject(player.reality.automator.state.editorScript);
},
get scriptName() { get scriptName() {
return this.findScript(this.state.topLevelScript).name; return this.currentRunningScript?.name ?? "";
},
hasDuplicateName(name) {
const nameArray = Object.values(player.reality.automator.scripts).map(s => s.name);
return nameArray.filter(n => n === name).length > 1;
}, },
get currentLineNumber() { get currentLineNumber() {
if (this.stack.top === null) if (!this.stack.top)
return -1; return -1;
return this.stack.top.lineNumber; return this.stack.top.lineNumber;
}, },
@ -257,6 +275,14 @@ export const AutomatorBackend = {
return Math.clampMin(Math.pow(0.994, Currency.realities.value) * 500, 1); return Math.clampMin(Math.pow(0.994, Currency.realities.value) * 500, 1);
}, },
get currentRawText() {
return this.currentRunningScript?.content ?? "";
},
get currentScriptLength() {
return this.currentRawText.split("\n").length;
},
update(diff) { update(diff) {
if (!this.isOn) return; if (!this.isOn) return;
let stack; let stack;
@ -351,10 +377,7 @@ export const AutomatorBackend = {
}, },
findScript(id) { findScript(id) {
// I tried really hard to convert IDs from strings into numbers for some cleanup but I just kept getting constant return this._scripts.find(e => e.id === id);
// errors everywhere. It needs to be a number so that importing works properly without ID assignment being a mess,
// but apparently some deeper things seem to break in a way I can't easily fix.
return this._scripts.find(e => `${e.id}` === `${id}`);
}, },
_createDefaultScript() { _createDefaultScript() {
@ -365,13 +388,13 @@ export const AutomatorBackend = {
}, },
initializeFromSave() { initializeFromSave() {
const scriptIds = Object.keys(player.reality.automator.scripts); const scriptIds = Object.keys(player.reality.automator.scripts).map(id => parseInt(id, 10));
if (scriptIds.length === 0) { if (scriptIds.length === 0) {
scriptIds.push(this._createDefaultScript()); scriptIds.push(this._createDefaultScript());
} else { } else {
this._scripts = scriptIds.map(s => new AutomatorScript(s)); this._scripts = scriptIds.map(s => new AutomatorScript(s));
} }
if (!scriptIds.includes(`${this.state.topLevelScript}`)) this.state.topLevelScript = scriptIds[0]; if (!scriptIds.includes(this.state.topLevelScript)) this.state.topLevelScript = scriptIds[0];
const currentScript = this.findScript(this.state.topLevelScript); const currentScript = this.findScript(this.state.topLevelScript);
if (currentScript.commands) { if (currentScript.commands) {
const commands = currentScript.commands; const commands = currentScript.commands;
@ -392,10 +415,14 @@ export const AutomatorBackend = {
return newScript; return newScript;
}, },
// Note that deleting scripts leaves gaps in the automator script indexing since automator scripts can't be
// dynamically re-indexed while the automator is running without causing a stutter from recompiling scripts.
deleteScript(id) { deleteScript(id) {
// We need to delete scripts from two places - in the savefile and compiled AutomatorScript Objects
const saveId = Object.values(player.reality.automator.scripts).findIndex(s => s.id === id);
delete player.reality.automator.scripts[parseInt(Object.keys(player.reality.automator.scripts)[saveId], 10)];
const idx = this._scripts.findIndex(e => e.id === id); const idx = this._scripts.findIndex(e => e.id === id);
this._scripts.splice(idx, 1); this._scripts.splice(idx, 1);
delete player.reality.automator.scripts[id];
if (this._scripts.length === 0) { if (this._scripts.length === 0) {
this._createDefaultScript(); this._createDefaultScript();
} }

View File

@ -1,5 +1,5 @@
import { AutomatorGrammar } from "./parser.js"; import { AutomatorGrammar } from "./parser";
import { AutomatorLexer } from "./lexer.js"; import { AutomatorLexer } from "./lexer";
(function() { (function() {
function walkSuggestion(suggestion, prefix, output) { function walkSuggestion(suggestion, prefix, output) {
@ -60,7 +60,7 @@ import { AutomatorLexer } from "./lexer.js";
{ regex: /blob\s\s/ui, token: "blob" }, { regex: /blob\s\s/ui, token: "blob" },
{ {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
regex: /auto\s|if\s|pause\s|studies\s|tt\s|time theorems\s|until\s|wait\s|while\s|black[ \t]+hole\s|stored?[ \t]time\s|notify/ui, regex: /(auto|if|pause|studies|tt|time[ \t]+theorems?|until|wait|while|black[ \t]+hole|stored?[ \t]+game[ \t]+time|notify)\s/ui,
token: "keyword", token: "keyword",
next: "commandArgs" next: "commandArgs"
}, },

View File

@ -1,4 +1,4 @@
import { AutomatorLexer } from "./lexer.js"; import { AutomatorLexer } from "./lexer";
/** /**
* Note: the $ shorthand for the parser object is required by Chevrotain. Don't mess with it. * Note: the $ shorthand for the parser object is required by Chevrotain. Don't mess with it.
@ -559,9 +559,9 @@ export const AutomatorCommands = ((() => {
}) })
}, },
{ {
id: "storeTime", id: "storeGameTime",
rule: $ => () => { rule: $ => () => {
$.CONSUME(T.StoreTime); $.CONSUME(T.StoreGameTime);
$.OR([ $.OR([
{ ALT: () => $.CONSUME(T.On) }, { ALT: () => $.CONSUME(T.On) },
{ ALT: () => $.CONSUME(T.Off) }, { ALT: () => $.CONSUME(T.Off) },
@ -569,10 +569,10 @@ export const AutomatorCommands = ((() => {
]); ]);
}, },
validate: (ctx, V) => { validate: (ctx, V) => {
ctx.startLine = ctx.StoreTime[0].startLine; ctx.startLine = ctx.StoreGameTime[0].startLine;
if (!Enslaved.isUnlocked) { if (!Enslaved.isUnlocked) {
V.addError(ctx.StoreTime[0], "You do not yet know how to store time", V.addError(ctx.StoreGameTime[0], "You do not yet know how to store game time",
"Unlock the ability to store time"); "Unlock the ability to store game time");
return false; return false;
} }
return true; return true;
@ -581,9 +581,9 @@ export const AutomatorCommands = ((() => {
if (ctx.Use) return () => { if (ctx.Use) return () => {
if (Enslaved.isUnlocked) { if (Enslaved.isUnlocked) {
Enslaved.useStoredTime(false); Enslaved.useStoredTime(false);
AutomatorData.logCommandEvent(`Stored time used`, ctx.startLine); AutomatorData.logCommandEvent(`Stored game time used`, ctx.startLine);
} else { } else {
AutomatorData.logCommandEvent(`Attempted to use stored time, but failed (not unlocked yet)`, AutomatorData.logCommandEvent(`Attempted to use stored game time, but failed (not unlocked yet)`,
ctx.startLine); ctx.startLine);
} }
return AUTOMATOR_COMMAND_STATUS.NEXT_INSTRUCTION; return AUTOMATOR_COMMAND_STATUS.NEXT_INSTRUCTION;
@ -591,14 +591,14 @@ export const AutomatorCommands = ((() => {
const on = Boolean(ctx.On); const on = Boolean(ctx.On);
return () => { return () => {
if (on !== player.celestials.enslaved.isStoring) Enslaved.toggleStoreBlackHole(); if (on !== player.celestials.enslaved.isStoring) Enslaved.toggleStoreBlackHole();
AutomatorData.logCommandEvent(`Storing time toggled ${ctx.On ? "ON" : "OFF"}`, ctx.startLine); AutomatorData.logCommandEvent(`Storing game time toggled ${ctx.On ? "ON" : "OFF"}`, ctx.startLine);
return AUTOMATOR_COMMAND_STATUS.NEXT_INSTRUCTION; return AUTOMATOR_COMMAND_STATUS.NEXT_INSTRUCTION;
}; };
}, },
blockify: ctx => ({ blockify: ctx => ({
// eslint-disable-next-line no-nested-ternary // eslint-disable-next-line no-nested-ternary
target: ctx.Use ? "USE" : (ctx.On ? "ON" : "OFF"), target: ctx.Use ? "USE" : (ctx.On ? "ON" : "OFF"),
...automatorBlocksMap["STORE TIME"] ...automatorBlocksMap["STORE GAME TIME"]
}) })
}, },
{ {
@ -723,7 +723,7 @@ export const AutomatorCommands = ((() => {
if (missingStudyCount === 0) { if (missingStudyCount === 0) {
AutomatorData.logCommandEvent(`Fully loaded study preset ${ctx.Preset[0].image}`, ctx.startLine); AutomatorData.logCommandEvent(`Fully loaded study preset ${ctx.Preset[0].image}`, ctx.startLine);
} else if (afterCount > beforeCount) { } else if (afterCount > beforeCount) {
AutomatorData.logCommandEvent(`Partially loaded study preset ${ctx.Preset[0].image} AutomatorData.logCommandEvent(`Partially loaded study preset ${ctx.Preset[0].image}
(missing ${quantifyInt("study", missingStudyCount)})`, ctx.startLine); (missing ${quantifyInt("study", missingStudyCount)})`, ctx.startLine);
} }
return ctx.Nowait !== undefined || missingStudyCount === 0 return ctx.Nowait !== undefined || missingStudyCount === 0

View File

@ -35,19 +35,17 @@ export const AutomatorPoints = {
} }
}; };
GameDatabase.reality.otherAutomatorPoints = (function() { GameDatabase.reality.otherAutomatorPoints = [
return [ {
{ name: "Reality Count",
name: "Reality Count", automatorPoints: () => 2 * Math.clampMax(Currency.realities.value, 100),
automatorPoints: () => 2 * Math.clampMax(Currency.realities.value, 100), shortDescription: () => `+${formatInt(2)} per Reality, up to ${formatInt(100)} Realities`,
shortDescription: () => `+${formatInt(2)} per Reality, up to ${formatInt(100)} Realities`, symbol: "Ϟ",
symbol: "Ϟ", },
}, {
{ name: "Black Hole",
name: "Black Hole", automatorPoints: () => (BlackHole(1).isUnlocked ? 10 : 0),
automatorPoints: () => (BlackHole(1).isUnlocked ? 10 : 0), shortDescription: () => `Unlocking gives ${formatInt(10)} AP`,
shortDescription: () => `Unlocking gives ${formatInt(10)} AP`, symbol: "<i class='fas fa-circle'></i>",
symbol: "<i class='fas fa-circle'></i>", },
}, ];
];
}());

View File

@ -1,6 +1,6 @@
import { AutomatorCommands } from "./automator-commands.js"; import { AutomatorCommands } from "./automator-commands";
import { AutomatorGrammar } from "./parser.js"; import { AutomatorGrammar } from "./parser";
import { AutomatorLexer } from "./lexer.js"; import { AutomatorLexer } from "./lexer";
(function() { (function() {
if (AutomatorGrammar === undefined) { if (AutomatorGrammar === undefined) {

View File

@ -1,5 +1,5 @@
import "./compiler.js"; import "./compiler";
import "./automator-codemirror.js"; import "./automator-codemirror";
export { AutomatorGrammar } from "./parser.js"; export { AutomatorGrammar } from "./parser";
export { standardizeAutomatorCurrencyName } from "./lexer.js"; export { standardizeAutomatorCurrencyName } from "./lexer";

View File

@ -2,7 +2,8 @@
/* eslint-disable require-unicode-regexp */ /* eslint-disable require-unicode-regexp */
/* eslint-disable camelcase */ /* eslint-disable camelcase */
import { createToken, Lexer } from "chevrotain"; import { createToken, Lexer } from "chevrotain";
import { DC } from "../constants.js";
import { DC } from "../constants";
export const AutomatorLexer = (() => { export const AutomatorLexer = (() => {
const createCategory = name => createToken({ name, pattern: Lexer.NA, longer_alt: Identifier }); const createCategory = name => createToken({ name, pattern: Lexer.NA, longer_alt: Identifier });
@ -304,8 +305,8 @@ export const AutomatorLexer = (() => {
createKeyword("BlackHole", /black[ \t]+hole/i, { createKeyword("BlackHole", /black[ \t]+hole/i, {
$autocomplete: "black hole", $autocomplete: "black hole",
}); });
createKeyword("StoreTime", /stored?[ \t]+time/i, { createKeyword("StoreGameTime", /stored?[ \t]+game[ \t]+time/i, {
$autocomplete: "store time", $autocomplete: "store game time",
}); });
createKeyword("Dilation", /dilation/i); createKeyword("Dilation", /dilation/i);

View File

@ -1,6 +1,7 @@
import { Parser, EOF } from "chevrotain"; import { EOF, Parser } from "chevrotain";
import { AutomatorCommands } from "./automator-commands.js";
import { AutomatorLexer } from "./lexer.js"; import { AutomatorCommands } from "./automator-commands";
import { AutomatorLexer } from "./lexer";
export const AutomatorGrammar = (function() { export const AutomatorGrammar = (function() {
const T = AutomatorLexer.tokenMap; const T = AutomatorLexer.tokenMap;

View File

@ -1,12 +1,8 @@
import { GameMechanicState, SetPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index.js"; import { DC } from "./constants";
import { DC } from "./constants.js"; import FullScreenAnimationHandler from "./full-screen-animation-handler";
import { SpeedrunMilestones } from "./speedrun.js";
export function bigCrunchAnimation() { export function bigCrunchAnimation() {
document.body.style.animation = "implode 2s 1"; FullScreenAnimationHandler.display("a-implode", 2);
setTimeout(() => {
document.body.style.animation = "";
}, 2000);
} }
function handleChallengeCompletion() { function handleChallengeCompletion() {
@ -25,7 +21,7 @@ function handleChallengeCompletion() {
export function bigCrunchResetRequest(disableAnimation = false) { export function bigCrunchResetRequest(disableAnimation = false) {
if (!Player.canCrunch) return; if (!Player.canCrunch) return;
if (!disableAnimation && player.options.animations.bigCrunch && document.body.style.animation === "") { if (!disableAnimation && player.options.animations.bigCrunch && !FullScreenAnimationHandler.isDisplaying) {
bigCrunchAnimation(); bigCrunchAnimation();
setTimeout(bigCrunchReset, 1000); setTimeout(bigCrunchReset, 1000);
} else { } else {
@ -52,10 +48,10 @@ export function bigCrunchReset() {
if (Pelle.isDoomed) PelleStrikes.infinity.trigger(); if (Pelle.isDoomed) PelleStrikes.infinity.trigger();
EventHub.dispatch(GAME_EVENT.BIG_CRUNCH_AFTER); EventHub.dispatch(GAME_EVENT.BIG_CRUNCH_AFTER);
if (firstInfinity && !Pelle.isDoomed) Modal.message.show(`Upon Infinity, all Dimensions, Dimension Boosts, and Antimatter if (firstInfinity && !Pelle.isDoomed) Modal.message.show(`Upon Infinity, all Dimensions, Dimension Boosts, and
Galaxies are reset, but in return, you gain an Infinity Point (IP). This allows you to buy multiple upgrades that Antimatter Galaxies are reset, but in return, you gain an Infinity Point (IP). This allows you to buy multiple
you can find in the Infinity tab. You will also gain one Infinity, which is the stat shown in the Statistics upgrades that you can find in the Infinity tab. You will also gain one Infinity, which is the stat shown in the
tab.`); Statistics tab.`);
} }
function bigCrunchUpdateStatistics() { function bigCrunchUpdateStatistics() {
@ -152,311 +148,6 @@ export function secondSoftReset(forcedNDReset = false) {
AchievementTimers.marathon2.reset(); AchievementTimers.marathon2.reset();
} }
class ChargedInfinityUpgradeState extends GameMechanicState {
constructor(config, upgrade) {
super(config);
this._upgrade = upgrade;
}
get isEffectActive() {
return this._upgrade.isBought && this._upgrade.isCharged;
}
}
export class InfinityUpgrade extends SetPurchasableMechanicState {
constructor(config, requirement) {
super(config);
if (Array.isArray(requirement) || typeof requirement === "function") {
this._requirements = requirement;
} else if (requirement === undefined) {
this._requirements = [];
} else {
this._requirements = [requirement];
}
if (config.charged) {
this._chargedEffect = new ChargedInfinityUpgradeState(config.charged, this);
}
}
get currency() {
return Currency.infinityPoints;
}
get set() {
return player.infinityUpgrades;
}
get isAvailableForPurchase() {
return typeof this._requirements === "function" ? this._requirements()
: this._requirements.every(x => x.isBought);
}
get isEffectActive() {
return this.isBought && !this.isCharged;
}
get chargedEffect() {
return this._chargedEffect;
}
purchase() {
if (super.purchase()) {
// This applies the 4th column of infinity upgrades retroactively
if (this.config.id.includes("skip")) skipResetsIfPossible();
EventHub.dispatch(GAME_EVENT.INFINITY_UPGRADE_BOUGHT);
return true;
}
if (this.canCharge) {
this.charge();
return true;
}
return false;
}
get hasChargeEffect() {
return this.config.charged !== undefined;
}
get isCharged() {
return player.celestials.ra.charged.has(this.id);
}
get canCharge() {
return this.isBought &&
this.hasChargeEffect &&
!this.isCharged &&
Ra.chargesLeft !== 0 &&
!Pelle.isDisabled("chargedInfinityUpgrades");
}
charge() {
player.celestials.ra.charged.add(this.id);
}
disCharge() {
player.celestials.ra.charged.delete(this.id);
}
}
export function totalIPMult() {
if (Effarig.isRunning && Effarig.currentStage === EFFARIG_STAGES.INFINITY) {
return DC.D1;
}
let ipMult = DC.D1
.times(ShopPurchase.IPPurchases.currentMult)
.timesEffectsOf(
TimeStudy(41),
TimeStudy(51),
TimeStudy(141),
TimeStudy(142),
TimeStudy(143),
Achievement(85),
Achievement(93),
Achievement(116),
Achievement(125),
Achievement(141).effects.ipGain,
InfinityUpgrade.ipMult,
DilationUpgrade.ipMultDT,
GlyphEffect.ipMult
);
ipMult = ipMult.times(Replicanti.amount.powEffectOf(AlchemyResource.exponential));
return ipMult;
}
export function disChargeAll() {
const upgrades = [
InfinityUpgrade.totalTimeMult,
InfinityUpgrade.dim18mult,
InfinityUpgrade.dim36mult,
InfinityUpgrade.resetBoost,
InfinityUpgrade.buy10Mult,
InfinityUpgrade.dim27mult,
InfinityUpgrade.dim45mult,
InfinityUpgrade.galaxyBoost,
InfinityUpgrade.thisInfinityTimeMult,
InfinityUpgrade.unspentIPMult,
InfinityUpgrade.dimboostMult,
InfinityUpgrade.ipGen
];
for (const upgrade of upgrades) {
if (upgrade.isCharged) {
upgrade.disCharge();
}
}
player.celestials.ra.disCharge = false;
}
(function() {
const db = GameDatabase.infinity.upgrades;
const upgrade = (config, requirement) => new InfinityUpgrade(config, requirement);
InfinityUpgrade.totalTimeMult = upgrade(db.totalTimeMult);
InfinityUpgrade.dim18mult = upgrade(db.dim18mult, InfinityUpgrade.totalTimeMult);
InfinityUpgrade.dim36mult = upgrade(db.dim36mult, InfinityUpgrade.dim18mult);
InfinityUpgrade.resetBoost = upgrade(db.resetBoost, InfinityUpgrade.dim36mult);
InfinityUpgrade.buy10Mult = upgrade(db.buy10Mult);
InfinityUpgrade.dim27mult = upgrade(db.dim27mult, InfinityUpgrade.buy10Mult);
InfinityUpgrade.dim45mult = upgrade(db.dim45mult, InfinityUpgrade.dim27mult);
InfinityUpgrade.galaxyBoost = upgrade(db.galaxyBoost, InfinityUpgrade.dim45mult);
InfinityUpgrade.thisInfinityTimeMult = upgrade(db.thisInfinityTimeMult);
InfinityUpgrade.unspentIPMult = upgrade(db.unspentIPMult, InfinityUpgrade.thisInfinityTimeMult);
InfinityUpgrade.dimboostMult = upgrade(db.dimboostMult, InfinityUpgrade.unspentIPMult);
InfinityUpgrade.ipGen = upgrade(db.ipGen, InfinityUpgrade.dimboostMult);
InfinityUpgrade.skipReset1 = upgrade(db.skipReset1);
InfinityUpgrade.skipReset2 = upgrade(db.skipReset2, InfinityUpgrade.skipReset1);
InfinityUpgrade.skipReset3 = upgrade(db.skipReset3, InfinityUpgrade.skipReset2);
InfinityUpgrade.skipResetGalaxy = upgrade(db.skipResetGalaxy, InfinityUpgrade.skipReset3);
InfinityUpgrade.ipOffline = upgrade(db.ipOffline, () => Achievement(41).isUnlocked);
}());
// The repeatable 2xIP upgrade has an odd cost structure - it follows a shallow exponential (step *10) up to e3M, at
// which point it follows a steeper one (step *1e10) up to e6M before finally hardcapping. At the hardcap, there's
// an extra bump that increases the multipler itself from e993k to e1M. All these numbers are specified in
// GameDatabase.infinity.upgrades.ipMult
class InfinityIPMultUpgrade extends GameMechanicState {
get cost() {
if (this.purchaseCount >= this.purchasesAtIncrease) {
return this.config.costIncreaseThreshold
.times(Decimal.pow(this.costIncrease, this.purchaseCount - this.purchasesAtIncrease));
}
return Decimal.pow(this.costIncrease, this.purchaseCount + 1);
}
get purchaseCount() {
return player.IPMultPurchases;
}
get purchasesAtIncrease() {
return this.config.costIncreaseThreshold.log10() - 1;
}
get hasIncreasedCost() {
return this.purchaseCount >= this.purchasesAtIncrease;
}
get costIncrease() {
return this.hasIncreasedCost ? 1e10 : 10;
}
get isCapped() {
return this.cost.gte(this.config.costCap);
}
get isBought() {
return this.isCapped;
}
get isRequirementSatisfied() {
return Achievement(41).isUnlocked;
}
get canBeBought() {
return !Pelle.isDoomed && !this.isCapped && Currency.infinityPoints.gte(this.cost) && this.isRequirementSatisfied;
}
// This is only ever called with amount = 1 or within buyMax under conditions that ensure the scaling doesn't
// change mid-purchase
purchase(amount = 1) {
if (!this.canBeBought) return;
if (!TimeStudy(181).isBought) {
Autobuyer.bigCrunch.bumpAmount(DC.D2.pow(amount));
}
Currency.infinityPoints.subtract(Decimal.sumGeometricSeries(amount, this.cost, this.costIncrease, 0));
player.IPMultPurchases += amount;
GameUI.update();
}
buyMax() {
if (!this.canBeBought) return;
if (!this.hasIncreasedCost) {
// Only allow IP below the softcap to be used
const availableIP = Currency.infinityPoints.value.clampMax(this.config.costIncreaseThreshold);
const purchases = Decimal.affordGeometricSeries(availableIP, this.cost, this.costIncrease, 0).toNumber();
if (purchases <= 0) return;
this.purchase(purchases);
}
// Do not replace it with `if else` - it's specifically designed to process two sides of threshold separately
// (for example, we have 1e4000000 IP and no mult - first it will go to (but not including) 1e3000000 and then
// it will go in this part)
if (this.hasIncreasedCost) {
const availableIP = Currency.infinityPoints.value.clampMax(this.config.costCap);
const purchases = Decimal.affordGeometricSeries(availableIP, this.cost, this.costIncrease, 0).toNumber();
if (purchases <= 0) return;
this.purchase(purchases);
}
}
}
InfinityUpgrade.ipMult = new InfinityIPMultUpgrade(GameDatabase.infinity.upgrades.ipMult);
export class BreakInfinityUpgrade extends SetPurchasableMechanicState {
get currency() {
return Currency.infinityPoints;
}
get set() {
return player.infinityUpgrades;
}
onPurchased() {
if (this.id === "postGalaxy") {
SpeedrunMilestones(7).tryComplete();
PelleStrikes.powerGalaxies.trigger();
}
}
}
(function() {
const db = GameDatabase.infinity.breakUpgrades;
const upgrade = props => new BreakInfinityUpgrade(props);
BreakInfinityUpgrade.totalAMMult = upgrade(db.totalAMMult);
BreakInfinityUpgrade.currentAMMult = upgrade(db.currentAMMult);
BreakInfinityUpgrade.galaxyBoost = upgrade(db.galaxyBoost);
BreakInfinityUpgrade.infinitiedMult = upgrade(db.infinitiedMult);
BreakInfinityUpgrade.achievementMult = upgrade(db.achievementMult);
BreakInfinityUpgrade.slowestChallengeMult = upgrade(db.slowestChallengeMult);
BreakInfinityUpgrade.infinitiedGen = upgrade(db.infinitiedGen);
BreakInfinityUpgrade.autobuyMaxDimboosts = upgrade(db.autobuyMaxDimboosts);
BreakInfinityUpgrade.autobuyerSpeed = upgrade(db.autobuyerSpeed);
}());
class RebuyableBreakInfinityUpgradeState extends RebuyableMechanicState {
get currency() {
return Currency.infinityPoints;
}
get boughtAmount() {
return player.infinityRebuyables[this.id];
}
set boughtAmount(value) {
player.infinityRebuyables[this.id] = value;
}
get isCapped() {
return this.boughtAmount === this.config.maxUpgrades;
}
}
BreakInfinityUpgrade.tickspeedCostMult = new class extends RebuyableBreakInfinityUpgradeState {
onPurchased() {
GameCache.tickSpeedMultDecrease.invalidate();
}
}(GameDatabase.infinity.breakUpgrades.tickspeedCostMult);
BreakInfinityUpgrade.dimCostMult = new class extends RebuyableBreakInfinityUpgradeState {
onPurchased() {
GameCache.dimensionMultDecrease.invalidate();
}
}(GameDatabase.infinity.breakUpgrades.dimCostMult);
BreakInfinityUpgrade.ipGen = new RebuyableBreakInfinityUpgradeState(GameDatabase.infinity.breakUpgrades.ipGen);
export function preProductionGenerateIP(diff) { export function preProductionGenerateIP(diff) {
if (InfinityUpgrade.ipGen.isBought) { if (InfinityUpgrade.ipGen.isBought) {
const genPeriod = Time.bestInfinity.totalMilliseconds * 10; const genPeriod = Time.bestInfinity.totalMilliseconds * 10;

View File

@ -1,5 +1,5 @@
import { DC } from "./constants.js"; import { DC } from "./constants";
import { SpeedrunMilestones } from "./speedrun.js"; import { SpeedrunMilestones } from "./speedrun";
class BlackHoleUpgradeState { class BlackHoleUpgradeState {
constructor(config) { constructor(config) {

View File

@ -0,0 +1,48 @@
import { RebuyableMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index";
import { SpeedrunMilestones } from "./speedrun";
export class BreakInfinityUpgradeState extends SetPurchasableMechanicState {
get currency() {
return Currency.infinityPoints;
}
get set() {
return player.infinityUpgrades;
}
onPurchased() {
if (this.id === "postGalaxy") {
SpeedrunMilestones(7).tryComplete();
PelleStrikes.powerGalaxies.trigger();
}
}
}
class RebuyableBreakInfinityUpgradeState extends RebuyableMechanicState {
get currency() {
return Currency.infinityPoints;
}
get boughtAmount() {
return player.infinityRebuyables[this.id];
}
set boughtAmount(value) {
player.infinityRebuyables[this.id] = value;
}
get isCapped() {
return this.boughtAmount === this.config.maxUpgrades;
}
onPurchased() {
this.config.onPurchased?.();
}
}
export const BreakInfinityUpgrade = mapGameDataToObject(
GameDatabase.infinity.breakUpgrades,
config => (config.rebuyable
? new RebuyableBreakInfinityUpgradeState(config)
: new BreakInfinityUpgradeState(config))
);

View File

@ -1,7 +1,9 @@
import { GameDatabase } from "../secret-formula/game-database.js"; import { BitUpgradeState, GameMechanicState } from "../game-mechanics/index";
import { GameMechanicState, BitUpgradeState } from "../game-mechanics/index.js"; import { GameDatabase } from "../secret-formula/game-database";
import { CelestialQuotes } from "./quotes.js";
import { SpeedrunMilestones } from "../speedrun.js"; import { SpeedrunMilestones } from "../speedrun";
import { CelestialQuotes } from "./quotes";
/** /**
* Information about how to format runUnlocks: * Information about how to format runUnlocks:

View File

@ -1,10 +1,10 @@
import { Teresa } from "./teresa.js"; import { Effarig } from "./effarig";
import { Effarig } from "./effarig.js"; import { Enslaved } from "./enslaved";
import { Enslaved } from "./enslaved.js"; import { Laitela } from "./laitela/laitela";
import { V } from "./V.js";
import { Ra } from "./ra/ra.js";
import { Laitela } from "./laitela/laitela.js";
import { Pelle } from "./pelle/pelle"; import { Pelle } from "./pelle/pelle";
import { Ra } from "./ra/ra";
import { Teresa } from "./teresa";
import { V } from "./V";
export const Celestials = { export const Celestials = {
teresa: Teresa, teresa: Teresa,
@ -44,7 +44,7 @@ GameDatabase.celestials.descriptions = [
Tachyon Particle production and Dilated Time production are severely reduced Tachyon Particle production and Dilated Time production are severely reduced
Time Theorem generation from Dilation Glyphs is disabled Time Theorem generation from Dilation Glyphs is disabled
Certain challenge goals have been increased Certain challenge goals have been increased
Stored Time is discharged at a reduced effectiveness (exponent^${format(0.55, 2, 2)}) `; Stored game time is discharged at a reduced effectiveness (exponent^${format(0.55, 2, 2)}) `;
} }
}, },
{ {

View File

@ -1,7 +1,9 @@
import { GameDatabase } from "../secret-formula/game-database.js"; import { BitUpgradeState } from "../game-mechanics/index";
import { BitUpgradeState } from "../game-mechanics/index.js"; import { GameDatabase } from "../secret-formula/game-database";
import { CelestialQuotes } from "./quotes.js";
import { DC } from "../constants.js"; import { DC } from "../constants";
import { CelestialQuotes } from "./quotes";
export const EFFARIG_STAGES = { export const EFFARIG_STAGES = {
INFINITY: 1, INFINITY: 1,
@ -176,41 +178,14 @@ class EffarigUnlockState extends BitUpgradeState {
purchase() { purchase() {
if (this.isUnlocked || !Currency.relicShards.purchase(this.cost)) return; if (this.isUnlocked || !Currency.relicShards.purchase(this.cost)) return;
this.unlock(); this.unlock();
switch (this) { this.config.onPurchased?.();
case EffarigUnlock.adjuster:
Effarig.quotes.show(Effarig.quotes.UNLOCK_WEIGHTS);
ui.view.tabs.reality.openGlyphWeights = true;
Tab.reality.glyphs.show();
break;
case EffarigUnlock.glyphFilter:
Effarig.quotes.show(Effarig.quotes.UNLOCK_GLYPH_FILTER);
player.reality.showSidebarPanel = GLYPH_SIDEBAR_MODE.FILTER_SETTINGS;
break;
case EffarigUnlock.setSaves:
Effarig.quotes.show(Effarig.quotes.UNLOCK_SET_SAVES);
player.reality.showSidebarPanel = GLYPH_SIDEBAR_MODE.SAVED_SETS;
break;
case EffarigUnlock.run:
Effarig.quotes.show(Effarig.quotes.UNLOCK_RUN);
break;
default:
throw new Error("Unknown Effarig upgrade");
}
} }
} }
export const EffarigUnlock = (function() { export const EffarigUnlock = mapGameDataToObject(
const db = GameDatabase.celestials.effarig.unlocks; GameDatabase.celestials.effarig.unlocks,
return { config => new EffarigUnlockState(config)
adjuster: new EffarigUnlockState(db.adjuster), );
glyphFilter: new EffarigUnlockState(db.glyphFilter),
setSaves: new EffarigUnlockState(db.setSaves),
run: new EffarigUnlockState(db.run),
infinity: new EffarigUnlockState(db.infinity),
eternity: new EffarigUnlockState(db.eternity),
reality: new EffarigUnlockState(db.reality),
};
}());
EventHub.logic.on(GAME_EVENT.TAB_CHANGED, () => { EventHub.logic.on(GAME_EVENT.TAB_CHANGED, () => {
if (Tab.celestials.effarig.isOpen) Effarig.quotes.show(Effarig.quotes.INITIAL); if (Tab.celestials.effarig.isOpen) Effarig.quotes.show(Effarig.quotes.INITIAL);

View File

@ -1,6 +1,7 @@
import { GameDatabase } from "../secret-formula/game-database.js"; import { BitUpgradeState } from "../game-mechanics/index";
import { BitUpgradeState } from "../game-mechanics/index.js"; import { GameDatabase } from "../secret-formula/game-database";
import { CelestialQuotes } from "./quotes.js";
import { CelestialQuotes } from "./quotes";
export const ENSLAVED_UNLOCKS = { export const ENSLAVED_UNLOCKS = {
FREE_TICKSPEED_SOFTCAP: { FREE_TICKSPEED_SOFTCAP: {
@ -265,19 +266,10 @@ class EnslavedProgressState extends BitUpgradeState {
} }
} }
export const EnslavedProgress = (function() { export const EnslavedProgress = mapGameDataToObject(
const db = GameDatabase.celestials.enslaved.progress; GameDatabase.celestials.enslaved.progress,
return { config => new EnslavedProgressState(config)
hintsUnlocked: new EnslavedProgressState(db.hintsUnlocked), );
ec1: new EnslavedProgressState(db.ec1),
feelEternity: new EnslavedProgressState(db.feelEternity),
ec6: new EnslavedProgressState(db.ec6),
c10: new EnslavedProgressState(db.c10),
secretStudy: new EnslavedProgressState(db.secretStudy),
storedTime: new EnslavedProgressState(db.storedTime),
challengeCombo: new EnslavedProgressState(db.challengeCombo),
};
}());
export const Tesseracts = { export const Tesseracts = {
get bought() { get bought() {

View File

@ -1,5 +1,5 @@
import { DimensionState } from "../../dimensions/dimension.js"; import { DC } from "../../constants";
import { DC } from "../../constants.js"; import { DimensionState } from "../../dimensions/dimension";
/** /**
* Constants for easily adjusting values * Constants for easily adjusting values

View File

@ -1,6 +1,7 @@
import { CelestialQuotes } from "../quotes.js"; import { CelestialQuotes } from "../quotes";
import { DC } from "../../constants.js"; import { DC } from "../../constants";
import { DarkMatterDimensions } from "./dark-matter-dimension.js";
import { DarkMatterDimensions } from "./dark-matter-dimension";
export const Laitela = { export const Laitela = {
displayName: "Lai'tela", displayName: "Lai'tela",

View File

@ -1,4 +1,5 @@
import { GameMechanicState } from "../../game-mechanics/index.js"; import { GameMechanicState } from "../../game-mechanics/index";
import { deepmergeAll } from "@/utility/deepmerge"; import { deepmergeAll } from "@/utility/deepmerge";
class SingularityMilestoneState extends GameMechanicState { class SingularityMilestoneState extends GameMechanicState {
@ -30,14 +31,18 @@ class SingularityMilestoneState extends GameMechanicState {
return Currency.singularities.gte(this.start); return Currency.singularities.gte(this.start);
} }
get increaseThreshold() {
return this.config.increaseThreshold;
}
nerfCompletions(completions) { nerfCompletions(completions) {
const softcap = this.config.increaseThreshold; const softcap = this.increaseThreshold;
if (!softcap || (completions < softcap)) return completions; if (!softcap || (completions < softcap)) return completions;
return softcap + (completions - softcap) / 3; return softcap + (completions - softcap) / 3;
} }
unnerfCompletions(completions) { unnerfCompletions(completions) {
const softcap = this.config.increaseThreshold; const softcap = this.increaseThreshold;
if (!softcap || (completions < softcap)) return completions; if (!softcap || (completions < softcap)) return completions;
return softcap + (completions - softcap) * 3; return softcap + (completions - softcap) * 3;
} }
@ -94,42 +99,13 @@ class SingularityMilestoneState extends GameMechanicState {
} }
} }
export const SingularityMilestone = (function() { export const SingularityMilestone = mapGameDataToObject(
const db = GameDatabase.celestials.singularityMilestones; GameDatabase.celestials.singularityMilestones,
return { config => new SingularityMilestoneState(config)
continuumMult: new SingularityMilestoneState(db.continuumMult), );
darkMatterMult: new SingularityMilestoneState(db.darkMatterMult),
darkEnergyMult: new SingularityMilestoneState(db.darkEnergyMult),
darkDimensionCostReduction: new SingularityMilestoneState(db.darkDimensionCostReduction),
singularityMult: new SingularityMilestoneState(db.singularityMult),
darkDimensionIntervalReduction: new SingularityMilestoneState(db.darkDimensionIntervalReduction),
ascensionIntervalScaling: new SingularityMilestoneState(db.ascensionIntervalScaling),
autoCondense: new SingularityMilestoneState(db.autoCondense),
darkDimensionAutobuyers: new SingularityMilestoneState(db.darkDimensionAutobuyers),
darkAutobuyerSpeed: new SingularityMilestoneState(db.darkAutobuyerSpeed),
improvedSingularityCap: new SingularityMilestoneState(db.improvedSingularityCap),
darkFromTesseracts: new SingularityMilestoneState(db.darkFromTesseracts),
dilatedTimeFromSingularities: new SingularityMilestoneState(db.dilatedTimeFromSingularities),
darkFromGlyphLevel: new SingularityMilestoneState(db.darkFromGlyphLevel),
gamespeedFromSingularities: new SingularityMilestoneState(db.gamespeedFromSingularities),
darkFromTheorems: new SingularityMilestoneState(db.darkFromTheorems),
dim4Generation: new SingularityMilestoneState(db.dim4Generation),
darkFromDM4: new SingularityMilestoneState(db.darkFromDM4),
theoremPowerFromSingularities: new SingularityMilestoneState(db.theoremPowerFromSingularities),
darkFromGamespeed: new SingularityMilestoneState(db.darkFromGamespeed),
glyphLevelFromSingularities: new SingularityMilestoneState(db.glyphLevelFromSingularities),
darkFromDilatedTime: new SingularityMilestoneState(db.darkFromDilatedTime),
tesseractMultFromSingularities: new SingularityMilestoneState(db.tesseractMultFromSingularities),
improvedAscensionDM: new SingularityMilestoneState(db.improvedAscensionDM),
realityDEMultiplier: new SingularityMilestoneState(db.realityDEMultiplier),
intervalCostScalingReduction: new SingularityMilestoneState(db.intervalCostScalingReduction),
multFromInfinitied: new SingularityMilestoneState(db.multFromInfinitied),
infinitiedPow: new SingularityMilestoneState(db.infinitiedPow),
};
}());
export const SingularityMilestones = { export const SingularityMilestones = {
all: Object.values(SingularityMilestone), all: SingularityMilestone.all,
lastNotified: player.celestials.laitela.lastCheckedMilestones, lastNotified: player.celestials.laitela.lastCheckedMilestones,
get sorted() { get sorted() {
@ -227,7 +203,7 @@ export const SingularityMilestones = {
// Sorted list of all the values where a singularity milestone exists, used for "new milestone" styling // Sorted list of all the values where a singularity milestone exists, used for "new milestone" styling
const SingularityMilestoneThresholds = (function() { const SingularityMilestoneThresholds = (function() {
return Object.values(GameDatabase.celestials.singularityMilestones) return SingularityMilestones.all
.map(m => Array.range(0, Math.min(50, m.limit)) .map(m => Array.range(0, Math.min(50, m.limit))
.filter(r => !m.increaseThreshold || r <= m.increaseThreshold || .filter(r => !m.increaseThreshold || r <= m.increaseThreshold ||
(r > m.increaseThreshold && ((r - m.increaseThreshold) % 3) === 2)) (r > m.increaseThreshold && ((r - m.increaseThreshold) % 3) === 2))

View File

@ -1,5 +1,6 @@
import { DC } from "../../constants"; import { DC } from "../../constants";
import { RebuyableMechanicState } from "../../game-mechanics/rebuyable"; import { RebuyableMechanicState } from "../../game-mechanics/rebuyable";
import { PelleRifts } from "./rifts"; import { PelleRifts } from "./rifts";
export const GalaxyGenerator = { export const GalaxyGenerator = {
@ -114,9 +115,7 @@ export class GalaxyGeneratorUpgrade extends RebuyableMechanicState {
} }
} }
export const GalaxyGeneratorUpgrades = (function() { export const GalaxyGeneratorUpgrades = mapGameDataToObject(
return mapGameDataToObject( GameDatabase.celestials.pelle.galaxyGeneratorUpgrades,
GameDatabase.celestials.pelle.galaxyGeneratorUpgrades, config => new GalaxyGeneratorUpgrade(config)
config => new GalaxyGeneratorUpgrade(config) );
);
}());

View File

@ -1,9 +1,11 @@
import { DC } from "../../constants";
import { Currency } from "../../currency"; import { Currency } from "../../currency";
import { DC } from "../../constants";
import { RebuyableMechanicState } from "../../game-mechanics/rebuyable"; import { RebuyableMechanicState } from "../../game-mechanics/rebuyable";
import { SetPurchasableMechanicState } from "../../utils"; import { SetPurchasableMechanicState } from "../../utils";
import { CelestialQuotes } from "../quotes";
import zalgo from "./zalgo"; import zalgo from "./zalgo";
import { CelestialQuotes } from "../quotes.js";
const disabledMechanicUnlocks = { const disabledMechanicUnlocks = {
achievements: () => ({}), achievements: () => ({}),
@ -116,7 +118,8 @@ export const Pelle = {
}, },
get disabledAchievements() { get disabledAchievements() {
return [143, 142, 141, 133, 125, 118, 117, 111, 104, 103, 92, 91, 78, 76, 74, 65, 55, 54, 37]; return [164, 143, 142, 141, 137, 134, 133, 132, 125, 118, 117, 113, 111, 104, 103, 93, 92, 91, 87, 85, 78, 76,
74, 65, 55, 54, 37];
}, },
get uselessInfinityUpgrades() { get uselessInfinityUpgrades() {
@ -453,15 +456,13 @@ export class PelleUpgradeState extends SetPurchasableMechanicState {
} }
export const PelleUpgrade = (function() { export const PelleUpgrade = mapGameDataToObject(
return mapGameDataToObject( GameDatabase.celestials.pelle.upgrades,
GameDatabase.celestials.pelle.upgrades, config => (config.rebuyable
config => (config.rebuyable ? new RebuyablePelleUpgradeState(config)
? new RebuyablePelleUpgradeState(config) : new PelleUpgradeState(config)
: new PelleUpgradeState(config) )
) );
);
}());
PelleUpgrade.rebuyables = PelleUpgrade.all.filter(u => u.isRebuyable); PelleUpgrade.rebuyables = PelleUpgrade.all.filter(u => u.isRebuyable);
PelleUpgrade.singles = PelleUpgrade.all.filter(u => !u.isRebuyable); PelleUpgrade.singles = PelleUpgrade.all.filter(u => !u.isRebuyable);

View File

@ -170,11 +170,9 @@ class RiftState extends GameMechanicState {
} }
} }
export const PelleRifts = (function() { export const PelleRifts = mapGameDataToObject(
return mapGameDataToObject( GameDatabase.celestials.pelle.rifts,
GameDatabase.celestials.pelle.rifts, config => new RiftState(config)
config => new RiftState(config) );
);
}());
PelleRifts.totalMilestones = () => PelleRifts.all.flatMap(x => x.milestones).countWhere(x => x.canBeApplied); PelleRifts.totalMilestones = () => PelleRifts.all.flatMap(x => x.milestones).countWhere(x => x.canBeApplied);

View File

@ -56,9 +56,7 @@ class PelleStrikeState extends BitUpgradeState {
} }
} }
export const PelleStrikes = (function() { export const PelleStrikes = mapGameDataToObject(
return mapGameDataToObject( GameDatabase.celestials.pelle.strikes,
GameDatabase.celestials.pelle.strikes, config => new PelleStrikeState(config)
config => new PelleStrikeState(config) );
);
}());

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "../../game-mechanics/index.js"; import { GameMechanicState } from "../../game-mechanics/index";
/** /**
* @abstract * @abstract
@ -224,44 +224,16 @@ class AlchemyReaction {
} }
} }
export const AlchemyResource = (function() { export const AlchemyResource = mapGameDataToObject(
function createResource(resource) { GameDatabase.celestials.alchemy.resources,
const config = GameDatabase.celestials.alchemy.resources[resource]; config => (config.isBaseResource
config.id = resource; ? new BasicAlchemyResourceState(config)
if (config.isBaseResource) { : new AdvancedAlchemyResourceState(config))
return new BasicAlchemyResourceState(config); );
}
return new AdvancedAlchemyResourceState(config);
}
return {
power: createResource(ALCHEMY_RESOURCE.POWER),
infinity: createResource(ALCHEMY_RESOURCE.INFINITY),
time: createResource(ALCHEMY_RESOURCE.TIME),
replication: createResource(ALCHEMY_RESOURCE.REPLICATION),
dilation: createResource(ALCHEMY_RESOURCE.DILATION),
cardinality: createResource(ALCHEMY_RESOURCE.CARDINALITY),
eternity: createResource(ALCHEMY_RESOURCE.ETERNITY),
dimensionality: createResource(ALCHEMY_RESOURCE.DIMENSIONALITY),
inflation: createResource(ALCHEMY_RESOURCE.INFLATION),
alternation: createResource(ALCHEMY_RESOURCE.ALTERNATION),
effarig: createResource(ALCHEMY_RESOURCE.EFFARIG),
synergism: createResource(ALCHEMY_RESOURCE.SYNERGISM),
momentum: createResource(ALCHEMY_RESOURCE.MOMENTUM),
decoherence: createResource(ALCHEMY_RESOURCE.DECOHERENCE),
exponential: createResource(ALCHEMY_RESOURCE.EXPONENTIAL),
force: createResource(ALCHEMY_RESOURCE.FORCE),
uncountability: createResource(ALCHEMY_RESOURCE.UNCOUNTABILITY),
boundless: createResource(ALCHEMY_RESOURCE.BOUNDLESS),
multiversal: createResource(ALCHEMY_RESOURCE.MULTIVERSAL),
unpredictability: createResource(ALCHEMY_RESOURCE.UNPREDICTABILITY),
reality: createResource(ALCHEMY_RESOURCE.REALITY)
};
}());
export const AlchemyResources = { export const AlchemyResources = {
all: Object.values(AlchemyResource), all: AlchemyResource.all,
base: Object.values(AlchemyResource).filter(r => r.isBaseResource) base: AlchemyResource.all.filter(r => r.isBaseResource)
}; };
export const AlchemyReactions = (function() { export const AlchemyReactions = (function() {
@ -269,7 +241,7 @@ export const AlchemyReactions = (function() {
function mapReagents(resource) { function mapReagents(resource) {
return resource.config.reagents return resource.config.reagents
.map(r => ({ .map(r => ({
resource: AlchemyResources.all[r.resource], resource: AlchemyResources.all.find(x => x.id === r.resource),
cost: r.amount cost: r.amount
})); }));
} }

View File

@ -1,5 +1,5 @@
import { GameMechanicState, BitUpgradeState } from "../../game-mechanics/index.js"; import { BitUpgradeState, GameMechanicState } from "../../game-mechanics/index";
import { CelestialQuotes } from "../quotes.js"; import { CelestialQuotes } from "../quotes";
class RaUnlockState extends BitUpgradeState { class RaUnlockState extends BitUpgradeState {
get bits() { return player.celestials.ra.unlockBits; } get bits() { return player.celestials.ra.unlockBits; }

View File

@ -1,6 +1,7 @@
import { GameDatabase } from "../secret-formula/game-database.js"; import { BitUpgradeState, RebuyableMechanicState } from "../game-mechanics/index";
import { BitUpgradeState, RebuyableMechanicState } from "../game-mechanics/index.js"; import { GameDatabase } from "../secret-formula/game-database";
import { CelestialQuotes } from "./quotes.js";
import { CelestialQuotes } from "./quotes";
export const Teresa = { export const Teresa = {
timePoured: 0, timePoured: 0,
@ -172,17 +173,10 @@ export const TeresaUnlocks = mapGameDataToObject(
config => new TeresaUnlockState(config) config => new TeresaUnlockState(config)
); );
export const PerkShopUpgrade = (function() { export const PerkShopUpgrade = mapGameDataToObject(
const db = GameDatabase.celestials.perkShop; GameDatabase.celestials.perkShop,
return { config => new PerkShopUpgradeState(config)
glyphLevel: new PerkShopUpgradeState(db.glyphLevel), );
rmMult: new PerkShopUpgradeState(db.rmMult),
bulkDilation: new PerkShopUpgradeState(db.bulkDilation),
autoSpeed: new PerkShopUpgradeState(db.autoSpeed),
musicGlyph: new PerkShopUpgradeState(db.musicGlyph),
fillMusicGlyph: new PerkShopUpgradeState(db.fillMusicGlyph),
};
}());
EventHub.logic.on(GAME_EVENT.TAB_CHANGED, () => { EventHub.logic.on(GAME_EVENT.TAB_CHANGED, () => {
if (Tab.celestials.teresa.isOpen) Teresa.quotes.show(Teresa.quotes.INITIAL); if (Tab.celestials.teresa.isOpen) Teresa.quotes.show(Teresa.quotes.INITIAL);

View File

@ -1,5 +1,5 @@
import { GameMechanicState } from "./game-mechanics/index.js"; import { DC } from "./constants";
import { DC } from "./constants.js"; import { GameMechanicState } from "./game-mechanics/index";
// This function does *not* reset anything. Only call it when you've already // This function does *not* reset anything. Only call it when you've already
// done all the non-UI stuff. Right now the only UI thing to do is switch to // done all the non-UI stuff. Right now the only UI thing to do is switch to

View File

@ -1,4 +1,4 @@
import { DC } from "./constants.js"; import { DC } from "./constants";
/** /**

View File

@ -1,6 +1,8 @@
import { DC } from "./constants.js";
import { sha512_256 } from "js-sha512"; import { sha512_256 } from "js-sha512";
import { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
/* eslint-disable no-console */ /* eslint-disable no-console */
// Disabling no-console here seems // Disabling no-console here seems
// reasonable, since these are the devtools after all // reasonable, since these are the devtools after all
@ -92,17 +94,16 @@ dev.tripleEverything = function() {
}; };
dev.barrelRoll = function() { dev.barrelRoll = function() {
document.body.style.animation = "barrelRoll 5s 1"; FullScreenAnimationHandler.display("a-barrel-roll", 5);
setTimeout(() => document.body.style.animation = "", 5000);
}; };
dev.spin3d = function() { dev.spin3d = function() {
if (document.body.style.animation === "") document.body.style.animation = "spin3d 3s infinite"; if (document.body.style.animation === "") document.body.style.animation = "a-spin3d 3s infinite";
else document.body.style.animation = ""; else document.body.style.animation = "";
}; };
dev.spin4d = function() { dev.spin4d = function() {
if (document.body.style.animation === "") document.body.style.animation = "spin4d 3s infinite"; if (document.body.style.animation === "") document.body.style.animation = "a-spin4d 3s infinite";
else document.body.style.animation = ""; else document.body.style.animation = "";
}; };
@ -165,7 +166,7 @@ dev.resetDilation = function() {
// when making a special glyph, so no max-params // when making a special glyph, so no max-params
// eslint-disable-next-line max-params // eslint-disable-next-line max-params
dev.giveSpecialGlyph = function(color, symbol, level, rawLevel = level) { dev.giveSpecialGlyph = function(color, symbol, level, rawLevel = level) {
if (!specialGlyphSymbols.hasOwnProperty(symbol)) return; if (!Object.prototype.hasOwnProperty.call(specialGlyphSymbols, symbol)) return;
if (Glyphs.freeInventorySpace === 0) return; if (Glyphs.freeInventorySpace === 0) return;
const glyph = GlyphGenerator.randomGlyph({ actualLevel: level, rawLevel }); const glyph = GlyphGenerator.randomGlyph({ actualLevel: level, rawLevel });
glyph.symbol = symbol; glyph.symbol = symbol;

View File

@ -1,20 +1,15 @@
import { SetPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index.js"; import { RebuyableMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index";
import { DC } from "./constants.js"; import { DC } from "./constants";
import { SpeedrunMilestones } from "./speedrun.js"; import FullScreenAnimationHandler from "./full-screen-animation-handler";
import { SpeedrunMilestones } from "./speedrun";
export function animateAndDilate() { export function animateAndDilate() {
document.body.style.animation = "dilate 2s 1 linear"; FullScreenAnimationHandler.display("a-dilate", 2);
setTimeout(() => {
document.body.style.animation = "";
}, 2000);
setTimeout(startDilatedEternity, 1000); setTimeout(startDilatedEternity, 1000);
} }
export function animateAndUndilate() { export function animateAndUndilate() {
document.body.style.animation = "undilate 2s 1 linear"; FullScreenAnimationHandler.display("a-undilate", 2);
setTimeout(() => {
document.body.style.animation = "";
}, 2000);
setTimeout(() => { setTimeout(() => {
eternity(false, false, { switchingDilation: true }); eternity(false, false, { switchingDilation: true });
}, 1000); }, 1000);
@ -22,7 +17,7 @@ export function animateAndUndilate() {
export function startDilatedEternityRequest() { export function startDilatedEternityRequest() {
if (!PlayerProgress.dilationUnlocked() || (Pelle.isDoomed && !Pelle.canDilateInPelle)) return; if (!PlayerProgress.dilationUnlocked() || (Pelle.isDoomed && !Pelle.canDilateInPelle)) return;
const playAnimation = player.options.animations.dilation && document.body.style.animation === ""; const playAnimation = player.options.animations.dilation && !FullScreenAnimationHandler.isDisplaying;
if (player.dilation.active) { if (player.dilation.active) {
// TODO Dilation modal // TODO Dilation modal
if (playAnimation) { if (playAnimation) {
@ -227,26 +222,12 @@ class RebuyableDilationUpgradeState extends RebuyableMechanicState {
} }
} }
export const DilationUpgrade = (function() { export const DilationUpgrade = mapGameDataToObject(
const db = GameDatabase.eternity.dilation; GameDatabase.eternity.dilation,
return { config => (config.rebuyable
dtGain: new RebuyableDilationUpgradeState(db.dtGain), ? new RebuyableDilationUpgradeState(config)
galaxyThreshold: new RebuyableDilationUpgradeState(db.galaxyThreshold), : new DilationUpgradeState(config))
tachyonGain: new RebuyableDilationUpgradeState(db.tachyonGain), );
doubleGalaxies: new DilationUpgradeState(db.doubleGalaxies),
tdMultReplicanti: new DilationUpgradeState(db.tdMultReplicanti),
ndMultDT: new DilationUpgradeState(db.ndMultDT),
ipMultDT: new DilationUpgradeState(db.ipMultDT),
timeStudySplit: new DilationUpgradeState(db.timeStudySplit),
dilationPenalty: new DilationUpgradeState(db.dilationPenalty),
ttGenerator: new DilationUpgradeState(db.ttGenerator),
dtGainPelle: new RebuyableDilationUpgradeState(db.dtGainPelle),
galaxyMultiplier: new RebuyableDilationUpgradeState(db.galaxyMultiplier),
tickspeedPower: new RebuyableDilationUpgradeState(db.tickspeedPower),
galaxyThresholdPelle: new DilationUpgradeState(db.galaxyThresholdPelle),
flatDilationMult: new DilationUpgradeState(db.flatDilationMult),
};
}());
export const DilationUpgrades = { export const DilationUpgrades = {
rebuyable: [ rebuyable: [
@ -254,11 +235,5 @@ export const DilationUpgrades = {
DilationUpgrade.galaxyThreshold, DilationUpgrade.galaxyThreshold,
DilationUpgrade.tachyonGain, DilationUpgrade.tachyonGain,
], ],
fromId: (function() { fromId: id => DilationUpgrade.all.find(x => x.id === id)
const upgradesById = [];
for (const upgrade of Object.values(DilationUpgrade)) {
upgradesById[upgrade.id] = upgrade;
}
return id => upgradesById[id];
}()),
}; };

View File

@ -1,4 +1,4 @@
import { DC } from "./constants.js"; import { DC } from "./constants";
class DimBoostRequirement { class DimBoostRequirement {
constructor(tier, amount) { constructor(tier, amount) {

View File

@ -1,5 +1,6 @@
import { DimensionState } from "./dimension.js"; import { DC } from "../constants";
import { DC } from "../constants.js";
import { DimensionState } from "./dimension";
// Multiplier applied to all Antimatter Dimensions, regardless of tier. This is cached using a Lazy // Multiplier applied to all Antimatter Dimensions, regardless of tier. This is cached using a Lazy
// and invalidated every update. // and invalidated every update.

View File

@ -1,5 +1,6 @@
import { DimensionState } from "./dimension.js"; import { DC } from "../constants";
import { DC } from "../constants.js";
import { DimensionState } from "./dimension";
export function infinityDimensionCommonMultiplier() { export function infinityDimensionCommonMultiplier() {
let mult = new Decimal(ShopPurchase.allDimPurchases.currentMult) let mult = new Decimal(ShopPurchase.allDimPurchases.currentMult)

View File

@ -1,5 +1,6 @@
import { DimensionState } from "./dimension.js"; import { DC } from "../constants";
import { DC } from "../constants.js";
import { DimensionState } from "./dimension";
export function buySingleTimeDimension(tier) { export function buySingleTimeDimension(tier) {
const dim = TimeDimension(tier); const dim = TimeDimension(tier);

View File

@ -1,5 +1,6 @@
import { GameMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index.js"; import { GameMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index";
import { DC } from "./constants.js"; import { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
function giveEternityRewards(auto) { function giveEternityRewards(auto) {
player.records.bestEternity.time = Math.min(player.records.thisEternity.time, player.records.bestEternity.time); player.records.bestEternity.time = Math.min(player.records.thisEternity.time, player.records.bestEternity.time);
@ -57,10 +58,7 @@ function giveEternityRewards(auto) {
} }
export function eternityAnimation() { export function eternityAnimation() {
document.body.style.animation = "eternify 3s 1"; FullScreenAnimationHandler.display("a-eternify", 3);
setTimeout(() => {
document.body.style.animation = "";
}, 3000);
} }
export function eternityResetRequest() { export function eternityResetRequest() {
@ -89,7 +87,7 @@ export function eternity(force, auto, specialConditions = {}) {
initializeChallengeCompletions(); initializeChallengeCompletions();
initializeResourcesAfterEternity(); initializeResourcesAfterEternity();
if (!EternityMilestone.keepAutobuyers.isReached) { if (!EternityMilestone.keepAutobuyers.isReached && !(Pelle.isDoomed && PelleUpgrade.keepAutobuyers.canBeApplied)) {
// Fix infinity because it can only break after big crunch autobuyer interval is maxed // Fix infinity because it can only break after big crunch autobuyer interval is maxed
player.break = false; player.break = false;
} }
@ -176,7 +174,7 @@ function applyRealityUpgradesAfterEternity() {
function askEternityConfirmation() { function askEternityConfirmation() {
if (player.options.confirmations.eternity) { if (player.options.confirmations.eternity) {
Modal.eternity.show(); Modal.eternity.show();
} else if (player.options.animations.eternity && document.body.style.animation === "") { } else if (player.options.animations.eternity && !FullScreenAnimationHandler.isDisplaying) {
eternityAnimation(); eternityAnimation();
setTimeout(eternity, 2250); setTimeout(eternity, 2250);
} else { } else {
@ -196,44 +194,12 @@ export class EternityMilestoneState {
return Currency.eternities.gte(this.config.eternities); return Currency.eternities.gte(this.config.eternities);
} }
} }
export const EternityMilestone = mapGameDataToObject(
export const EternityMilestone = (function() { GameDatabase.eternity.milestones,
const db = GameDatabase.eternity.milestones; config => (config.isBaseResource
const infinityDims = Array.dimensionTiers ? new EternityMilestoneState(config)
.map(tier => new EternityMilestoneState(db[`autobuyerID${tier}`])); : new EternityMilestoneState(config))
return { );
autobuyerIPMult: new EternityMilestoneState(db.autobuyerIPMult),
keepAutobuyers: new EternityMilestoneState(db.keepAutobuyers),
autobuyerReplicantiGalaxy: new EternityMilestoneState(db.autobuyerReplicantiGalaxy),
keepInfinityUpgrades: new EternityMilestoneState(db.keepInfinityUpgrades),
bigCrunchModes: new EternityMilestoneState(db.bigCrunchModes),
autoEP: new EternityMilestoneState(db.autoEP),
autoIC: new EternityMilestoneState(db.autoIC),
autobuyMaxGalaxies: new EternityMilestoneState(db.autobuyMaxGalaxies),
unlockReplicanti: new EternityMilestoneState(db.unlockReplicanti),
autobuyerID: tier => infinityDims[tier - 1],
keepBreakUpgrades: new EternityMilestoneState(db.keepBreakUpgrades),
autoUnlockID: new EternityMilestoneState(db.autoUnlockID),
unlockAllND: new EternityMilestoneState(db.unlockAllND),
replicantiNoReset: new EternityMilestoneState(db.replicantiNoReset),
autobuyerReplicantiChance: new EternityMilestoneState(db.autobuyerReplicantiChance),
autobuyerReplicantiInterval: new EternityMilestoneState(db.autobuyerReplicantiInterval),
autobuyerReplicantiMaxGalaxies: new EternityMilestoneState(db.autobuyerReplicantiMaxGalaxies),
autobuyerEternity: new EternityMilestoneState(db.autobuyerEternity),
autoEternities: new EternityMilestoneState(db.autoEternities),
autoInfinities: new EternityMilestoneState(db.autoInfinities),
};
}());
export const EternityMilestones = {
// This is a bit of a hack because autobuyerID is a function that returns EternityMilestoneState objects instead of a
// EternityMilestoneState object itself
all: Object.values(EternityMilestone)
.filter(m => typeof m !== "function")
.concat(Array.dimensionTiers
.map(tier => new EternityMilestoneState(GameDatabase.eternity.milestones[`autobuyerID${tier}`]))
)
};
class EternityUpgradeState extends SetPurchasableMechanicState { class EternityUpgradeState extends SetPurchasableMechanicState {
get currency() { get currency() {
@ -321,16 +287,9 @@ class EPMultiplierState extends GameMechanicState {
} }
} }
export const EternityUpgrade = mapGameDataToObject(
GameDatabase.eternity.upgrades,
config => new EternityUpgradeState(config)
);
export const EternityUpgrade = (function() { EternityUpgrade.epMult = new EPMultiplierState();
const db = GameDatabase.eternity.upgrades;
return {
idMultEP: new EternityUpgradeState(db.idMultEP),
idMultEternities: new EternityUpgradeState(db.idMultEternities),
idMultICRecords: new EternityUpgradeState(db.idMultICRecords),
tdMultAchs: new EternityUpgradeState(db.tdMultAchs),
tdMultTheorems: new EternityUpgradeState(db.tdMultTheorems),
tdMultRealTime: new EternityUpgradeState(db.tdMultRealTime),
epMult: new EPMultiplierState(),
};
}());

View File

@ -1,6 +1,6 @@
import { GameMechanicState } from "./game-mechanics/index.js"; import { DC } from "./constants";
import { DC } from "./constants.js";
import { deepmergeAll } from "@/utility/deepmerge"; import { deepmergeAll } from "@/utility/deepmerge";
import { GameMechanicState } from "./game-mechanics/index";
export function startEternityChallenge() { export function startEternityChallenge() {
initializeChallengeCompletions(); initializeChallengeCompletions();

View File

@ -0,0 +1,16 @@
export default {
isDisplaying: false,
displayForce(name, duration) {
document.body.style.animation = `${name} ${duration}s 1`;
this.isDisplaying = true;
setTimeout(() => {
document.body.style.animation = "";
this.isDisplaying = false;
}, duration * 1000);
},
display(name, duration) {
if (!this.isDisplaying) {
this.displayForce(name, duration);
}
}
};

View File

@ -1,4 +1,4 @@
import { PurchasableMechanicState } from "./puchasable.js"; import { PurchasableMechanicState } from "./puchasable";
/** /**
* @abstract * @abstract

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "./game-mechanic.js"; import { GameMechanicState } from "./game-mechanic";
/** /**
* @abstract * @abstract

View File

@ -1,4 +1,4 @@
import { Effect } from "./effect.js"; import { Effect } from "./effect";
/** /**
* @abstract * @abstract

View File

@ -1,8 +1,8 @@
export * from "./effect.js"; export * from "./effect";
export * from "./effects.js"; export * from "./effects";
export * from "./game-mechanic.js"; export * from "./game-mechanic";
export * from "./bit-upgrade-state.js"; export * from "./bit-upgrade-state";
export * from "./puchasable.js"; export * from "./puchasable";
export * from "./set-purchasable.js"; export * from "./set-purchasable";
export * from "./bit-purchasable.js"; export * from "./bit-purchasable";
export * from "./rebuyable.js"; export * from "./rebuyable";

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "./game-mechanic.js"; import { GameMechanicState } from "./game-mechanic";
/** /**
* @abstract * @abstract

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "./game-mechanic.js"; import { GameMechanicState } from "./game-mechanic";
/** /**
* @abstract * @abstract

View File

@ -1,4 +1,4 @@
import { PurchasableMechanicState } from "./puchasable.js"; import { PurchasableMechanicState } from "./puchasable";
/** /**
* @abstract * @abstract

View File

@ -1,90 +1,92 @@
export * from "./glyph-effects.js"; export * from "./glyph-effects";
export * from "./player.js"; export * from "./player";
export * from "./automator/automator-backend.js"; export * from "./automator/automator-backend";
export * from "./performance-stats.js"; export * from "./performance-stats";
export * from "./currency.js"; export * from "./currency";
export * from "./cache.js"; export * from "./cache";
export * from "./intervals.js"; export * from "./intervals";
export * from "./keyboard.js"; export * from "./keyboard";
export * from "./hotkeys.js"; export * from "./hotkeys";
export * from "./galaxy.js"; export * from "./galaxy";
export * from "./away-progress.js"; export * from "./away-progress";
export * from "./confirmations.js"; export * from "./confirmations";
export * from "./autobuyers/index.js"; export * from "./autobuyers/index";
export * from "./storage/index.js"; export * from "./storage/index";
export * from "./notations.js"; export * from "./notations";
export * from "./tutorial.js"; export * from "./tutorial";
export * from "./new-game.js"; export * from "./new-game";
export * from "./celestials/quotes.js"; export * from "./celestials/quotes";
export * from "./celestials/teresa.js"; export * from "./celestials/teresa";
export * from "./celestials/effarig.js"; export * from "./celestials/effarig";
export * from "./celestials/enslaved.js"; export * from "./celestials/enslaved";
export * from "./celestials/V.js"; export * from "./celestials/V";
export * from "./celestials/ra/ra.js"; export * from "./celestials/ra/ra";
export * from "./celestials/ra/alchemy.js"; export * from "./celestials/ra/alchemy";
export * from "./celestials/laitela/laitela.js"; export * from "./celestials/laitela/laitela";
export * from "./celestials/laitela/dark-matter-dimension.js"; export * from "./celestials/laitela/dark-matter-dimension";
export * from "./celestials/laitela/singularity.js"; export * from "./celestials/laitela/singularity";
export * from "./celestials/pelle/pelle.js"; export * from "./celestials/pelle/pelle";
export * from "./celestials/pelle/strikes.js"; export * from "./celestials/pelle/strikes";
export * from "./celestials/pelle/rifts.js"; export * from "./celestials/pelle/rifts";
export * from "./celestials/pelle/galaxy-generator.js"; export * from "./celestials/pelle/galaxy-generator";
export * from "./celestials/pelle/game-end.js"; export * from "./celestials/pelle/game-end";
export * from "./celestials/celestials.js"; export * from "./celestials/celestials";
export * from "./automator/index.js"; export * from "./automator/index";
export * from "./automator/automator-points.js"; export * from "./automator/automator-points";
export * from "./app/player-progress.js"; export * from "./app/player-progress";
export * from "./app/modal.js"; export * from "./app/modal";
export * from "./app/themes.js"; export * from "./app/themes";
export * from "./app/options.js"; export * from "./app/options";
export * from "./app/ui.js"; export * from "./app/ui";
export * from "./achievements/normal-achievement.js"; export * from "./achievements/normal-achievement";
export * from "./achievements/secret-achievement.js"; export * from "./achievements/secret-achievement";
export * from "./achievements/achievement-timer.js"; export * from "./achievements/achievement-timer";
export * from "./glyphs/glyph-core.js"; export * from "./glyphs/glyph-core";
export * from "./glyphs/glyph-effects.js"; export * from "./glyphs/glyph-effects";
export * from "./glyphs/glyph-generator.js"; export * from "./glyphs/glyph-generator";
export * from "./glyphs/glyph-purge-handler.js"; export * from "./glyphs/glyph-purge-handler";
export * from "./glyphs/auto-glyph-processor.js"; export * from "./glyphs/auto-glyph-processor";
export * from "./time.js"; export * from "./time";
export * from "./tickspeed.js"; export * from "./tickspeed";
export * from "./dimensions/antimatter-dimension.js"; export * from "./dimensions/antimatter-dimension";
export * from "./dimensions/infinity-dimension.js"; export * from "./dimensions/infinity-dimension";
export * from "./dimensions/time-dimension.js"; export * from "./dimensions/time-dimension";
export * from "./time-studies/index.js"; export * from "./time-studies/index";
export * from "./dimboost.js"; export * from "./dimboost";
export * from "./sacrifice.js"; export * from "./sacrifice";
export * from "./big_crunch.js"; export * from "./big_crunch";
export * from "./challenge.js"; export * from "./infinity-upgrades";
export * from "./eternity.js"; export * from "./break-infinity-upgrades";
export * from "./eternity_challenge.js"; export * from "./challenge";
export * from "./reality.js"; export * from "./eternity";
export * from "./replicanti.js"; export * from "./eternity_challenge";
export * from "./time-theorems.js"; export * from "./reality";
export * from "./reality-upgrades.js"; export * from "./replicanti";
export * from "./imaginary-upgrades.js"; export * from "./time-theorems";
export * from "./perks.js"; export * from "./reality-upgrades";
export * from "./dilation.js"; export * from "./imaginary-upgrades";
export * from "./black_hole.js"; export * from "./perks";
export * from "./machines.js"; export * from "./dilation";
export * from "./devtools.js"; export * from "./black_hole";
export * from "./news-ticker.js"; export * from "./machines";
export * from "./kong.js"; export * from "./devtools";
export * from "./ui/tabs.js"; export * from "./news-ticker";
export * from "./ui/tab-notifications.js"; export * from "./kong";
export * from "./speedrun.js"; export * from "./ui/tabs";
export * from "./ui/tab-notifications";
export * from "./speedrun";
export * from "./automator/script-templates.js"; export * from "./automator/script-templates";

View File

@ -1,5 +1,5 @@
import { GameDatabase } from "./secret-formula/game-database.js"; import { DC } from "./constants";
import { DC } from "./constants.js"; import { GameDatabase } from "./secret-formula/game-database";
// There is a little too much stuff about glyph effects to put in constants. // There is a little too much stuff about glyph effects to put in constants.

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "../game-mechanics/index.js"; import { GameMechanicState } from "../game-mechanics/index";
export const orderedEffectList = ["powerpow", "infinitypow", "replicationpow", "timepow", export const orderedEffectList = ["powerpow", "infinitypow", "replicationpow", "timepow",
"dilationpow", "timeshardpow", "powermult", "powerdimboost", "powerbuy10", "dilationpow", "timeshardpow", "powermult", "powerdimboost", "powerbuy10",
@ -640,18 +640,10 @@ export const Glyphs = {
class GlyphSacrificeState extends GameMechanicState { } class GlyphSacrificeState extends GameMechanicState { }
export const GlyphSacrifice = (function() { export const GlyphSacrifice = mapGameDataToObject(
const db = GameDatabase.reality.glyphSacrifice; GameDatabase.reality.glyphSacrifice,
return { config => new GlyphSacrificeState(config)
time: new GlyphSacrificeState(db.time), );
dilation: new GlyphSacrificeState(db.dilation),
replication: new GlyphSacrificeState(db.replication),
infinity: new GlyphSacrificeState(db.infinity),
power: new GlyphSacrificeState(db.power),
effarig: new GlyphSacrificeState(db.effarig),
reality: new GlyphSacrificeState(db.reality),
};
}());
export function recalculateAllGlyphs() { export function recalculateAllGlyphs() {
for (let i = 0; i < player.reality.glyphs.active.length; i++) { for (let i = 0; i < player.reality.glyphs.active.length; i++) {

View File

@ -1,6 +1,7 @@
import { GameKeyboard } from "./keyboard.js";
import Mousetrap from "mousetrap"; import Mousetrap from "mousetrap";
import { GameKeyboard } from "./keyboard";
// Add your hotkeys and combinations here // Add your hotkeys and combinations here
// GameKeyboard.bind for single press combinations // GameKeyboard.bind for single press combinations
// GameKeyboard.bindRepeatable for repeatable combinations // GameKeyboard.bindRepeatable for repeatable combinations

View File

@ -1,5 +1,5 @@
import { BitPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index.js"; import { BitPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index";
import { DC } from "./constants.js"; import { DC } from "./constants";
class ImaginaryUpgradeState extends BitPurchasableMechanicState { class ImaginaryUpgradeState extends BitPurchasableMechanicState {
constructor(config) { constructor(config) {

View File

@ -0,0 +1,213 @@
import { GameMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index";
import { DC } from "./constants";
class ChargedInfinityUpgradeState extends GameMechanicState {
constructor(config, upgrade) {
super(config);
this._upgrade = upgrade;
}
get isEffectActive() {
return this._upgrade.isBought && this._upgrade.isCharged;
}
}
export class InfinityUpgradeState extends SetPurchasableMechanicState {
constructor(config) {
super(config);
if (config.charged) {
this._chargedEffect = new ChargedInfinityUpgradeState(config.charged, this);
}
}
get currency() {
return Currency.infinityPoints;
}
get set() {
return player.infinityUpgrades;
}
get isAvailableForPurchase() {
return this.config.checkRequirement?.() ?? true;
}
get isEffectActive() {
return this.isBought && !this.isCharged;
}
get chargedEffect() {
return this._chargedEffect;
}
purchase() {
if (super.purchase()) {
// This applies the 4th column of infinity upgrades retroactively
if (this.config.id.includes("skip")) skipResetsIfPossible();
EventHub.dispatch(GAME_EVENT.INFINITY_UPGRADE_BOUGHT);
return true;
}
if (this.canCharge) {
this.charge();
return true;
}
return false;
}
get hasChargeEffect() {
return this.config.charged !== undefined;
}
get isCharged() {
return player.celestials.ra.charged.has(this.id);
}
get canCharge() {
return this.isBought &&
this.hasChargeEffect &&
!this.isCharged &&
Ra.chargesLeft !== 0 &&
!Pelle.isDisabled("chargedInfinityUpgrades");
}
charge() {
player.celestials.ra.charged.add(this.id);
}
disCharge() {
player.celestials.ra.charged.delete(this.id);
}
}
export function totalIPMult() {
if (Effarig.isRunning && Effarig.currentStage === EFFARIG_STAGES.INFINITY) {
return DC.D1;
}
let ipMult = DC.D1
.times(ShopPurchase.IPPurchases.currentMult)
.timesEffectsOf(
TimeStudy(41),
TimeStudy(51),
TimeStudy(141),
TimeStudy(142),
TimeStudy(143),
Achievement(85),
Achievement(93),
Achievement(116),
Achievement(125),
Achievement(141).effects.ipGain,
InfinityUpgrade.ipMult,
DilationUpgrade.ipMultDT,
GlyphEffect.ipMult
);
ipMult = ipMult.times(Replicanti.amount.powEffectOf(AlchemyResource.exponential));
return ipMult;
}
export function disChargeAll() {
const upgrades = [
InfinityUpgrade.totalTimeMult,
InfinityUpgrade.dim18mult,
InfinityUpgrade.dim36mult,
InfinityUpgrade.resetBoost,
InfinityUpgrade.buy10Mult,
InfinityUpgrade.dim27mult,
InfinityUpgrade.dim45mult,
InfinityUpgrade.galaxyBoost,
InfinityUpgrade.thisInfinityTimeMult,
InfinityUpgrade.unspentIPMult,
InfinityUpgrade.dimboostMult,
InfinityUpgrade.ipGen
];
for (const upgrade of upgrades) {
if (upgrade.isCharged) {
upgrade.disCharge();
}
}
player.celestials.ra.disCharge = false;
}
// The repeatable 2xIP upgrade has an odd cost structure - it follows a shallow exponential (step *10) up to e3M, at
// which point it follows a steeper one (step *1e10) up to e6M before finally hardcapping. At the hardcap, there's
// an extra bump that increases the multipler itself from e993k to e1M. All these numbers are specified in
// GameDatabase.infinity.upgrades.ipMult
class InfinityIPMultUpgrade extends GameMechanicState {
get cost() {
if (this.purchaseCount >= this.purchasesAtIncrease) {
return this.config.costIncreaseThreshold
.times(Decimal.pow(this.costIncrease, this.purchaseCount - this.purchasesAtIncrease));
}
return Decimal.pow(this.costIncrease, this.purchaseCount + 1);
}
get purchaseCount() {
return player.IPMultPurchases;
}
get purchasesAtIncrease() {
return this.config.costIncreaseThreshold.log10() - 1;
}
get hasIncreasedCost() {
return this.purchaseCount >= this.purchasesAtIncrease;
}
get costIncrease() {
return this.hasIncreasedCost ? 1e10 : 10;
}
get isCapped() {
return this.cost.gte(this.config.costCap);
}
get isBought() {
return this.isCapped;
}
get isRequirementSatisfied() {
return Achievement(41).isUnlocked;
}
get canBeBought() {
return !Pelle.isDoomed && !this.isCapped && Currency.infinityPoints.gte(this.cost) && this.isRequirementSatisfied;
}
// This is only ever called with amount = 1 or within buyMax under conditions that ensure the scaling doesn't
// change mid-purchase
purchase(amount = 1) {
if (!this.canBeBought) return;
if (!TimeStudy(181).isBought) {
Autobuyer.bigCrunch.bumpAmount(DC.D2.pow(amount));
}
Currency.infinityPoints.subtract(Decimal.sumGeometricSeries(amount, this.cost, this.costIncrease, 0));
player.IPMultPurchases += amount;
GameUI.update();
}
buyMax() {
if (!this.canBeBought) return;
if (!this.hasIncreasedCost) {
// Only allow IP below the softcap to be used
const availableIP = Currency.infinityPoints.value.clampMax(this.config.costIncreaseThreshold);
const purchases = Decimal.affordGeometricSeries(availableIP, this.cost, this.costIncrease, 0).toNumber();
if (purchases <= 0) return;
this.purchase(purchases);
}
// Do not replace it with `if else` - it's specifically designed to process two sides of threshold separately
// (for example, we have 1e4000000 IP and no mult - first it will go to (but not including) 1e3000000 and then
// it will go in this part)
if (this.hasIncreasedCost) {
const availableIP = Currency.infinityPoints.value.clampMax(this.config.costCap);
const purchases = Decimal.affordGeometricSeries(availableIP, this.cost, this.costIncrease, 0).toNumber();
if (purchases <= 0) return;
this.purchase(purchases);
}
}
}
export const InfinityUpgrade = mapGameDataToObject(
GameDatabase.infinity.upgrades,
config => (config.id === "ipMult"
? new InfinityIPMultUpgrade(config)
: new InfinityUpgradeState(config))
);

View File

@ -30,7 +30,10 @@ export const GameIntervals = (function() {
// Not a getter because getter will cause stack overflow // Not a getter because getter will cause stack overflow
all() { all() {
return Object.values(GameIntervals) return Object.values(GameIntervals)
.filter(i => i.hasOwnProperty("start") && i.hasOwnProperty("stop")); .filter(i =>
Object.prototype.hasOwnProperty.call(i, "start") &&
Object.prototype.hasOwnProperty.call(i, "stop")
);
}, },
start() { start() {
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow

View File

@ -1,4 +1,4 @@
import { RebuyableMechanicState } from "./game-mechanics/index.js"; import { RebuyableMechanicState } from "./game-mechanics/index";
export const kong = {}; export const kong = {};
@ -60,17 +60,10 @@ class ShopPurchaseState extends RebuyableMechanicState {
} }
} }
export const ShopPurchase = (function() { export const ShopPurchase = mapGameDataToObject(
const db = GameDatabase.shopPurchases; GameDatabase.shopPurchases,
return { config => new ShopPurchaseState(config)
dimPurchases: new ShopPurchaseState(db.dimPurchases), );
IPPurchases: new ShopPurchaseState(db.IPPurchases),
EPPurchases: new ShopPurchaseState(db.EPPurchases),
allDimPurchases: new ShopPurchaseState(db.allDimPurchases)
};
}());
ShopPurchase.all = Object.values(ShopPurchase);
kong.purchaseTimeSkip = function(cost) { kong.purchaseTimeSkip = function(cost) {
if (player.IAP.totalSTD - player.IAP.spentSTD < cost) return; if (player.IAP.totalSTD - player.IAP.spentSTD < cost) return;

View File

@ -1,4 +1,4 @@
import { DC } from "./constants.js"; import { DC } from "./constants";
export const MachineHandler = { export const MachineHandler = {
get baseRMCap() { return DC.E1000; }, get baseRMCap() { return DC.E1000; },

View File

@ -1,6 +1,7 @@
import { DC } from "./constants.js";
import { log as lngamma } from "gamma"; import { log as lngamma } from "gamma";
import { DC } from "./constants";
/* eslint-disable no-use-before-define */ /* eslint-disable no-use-before-define */
/* eslint-disable max-params */ /* eslint-disable max-params */

View File

@ -49,7 +49,7 @@ export const PerformanceStats = {
function render(rootBlock) { function render(rootBlock) {
indentLevel++; indentLevel++;
for (const blockName in rootBlock) { for (const blockName in rootBlock) {
if (!rootBlock.hasOwnProperty(blockName)) continue; if (!Object.prototype.hasOwnProperty.call(rootBlock, blockName)) continue;
const block = rootBlock[blockName]; const block = rootBlock[blockName];
const records = block.records; const records = block.records;
while (records.length > 1 && records.last().timestamp - records.first().timestamp > samplePeriod) { while (records.length > 1 && records.last().timestamp - records.first().timestamp > samplePeriod) {

View File

@ -1,4 +1,4 @@
import { SetPurchasableMechanicState } from "./game-mechanics/index.js"; import { SetPurchasableMechanicState } from "./game-mechanics/index";
class PerkState extends SetPurchasableMechanicState { class PerkState extends SetPurchasableMechanicState {
constructor(config) { constructor(config) {
@ -49,61 +49,13 @@ class PerkState extends SetPurchasableMechanicState {
} }
} }
export const Perk = (function() { export const Perk = mapGameDataToObject(
const db = GameDatabase.reality.perks; GameDatabase.reality.perks,
return { config => new PerkState(config)
firstPerk: new PerkState(db.firstPerk), );
startAM: new PerkState(db.startAM),
startIP1: new PerkState(db.startIP1),
startIP2: new PerkState(db.startIP2),
startEP1: new PerkState(db.startEP1),
startEP2: new PerkState(db.startEP2),
startEP3: new PerkState(db.startEP3),
startTP: new PerkState(db.startTP),
antimatterNoReset: new PerkState(db.antimatterNoReset),
studyPassive: new PerkState(db.studyPassive),
autounlockEU1: new PerkState(db.autounlockEU1),
autounlockEU2: new PerkState(db.autounlockEU2),
autounlockDilation1: new PerkState(db.autounlockDilation1),
autounlockDilation2: new PerkState(db.autounlockDilation2),
autounlockDilation3: new PerkState(db.autounlockDilation3),
autounlockTD: new PerkState(db.autounlockTD),
autounlockReality: new PerkState(db.autounlockReality),
bypassIDAntimatter: new PerkState(db.bypassIDAntimatter),
bypassTGReset: new PerkState(db.bypassTGReset),
bypassECDilation: new PerkState(db.bypassECDilation),
bypassEC1Lock: new PerkState(db.bypassEC1Lock),
bypassEC2Lock: new PerkState(db.bypassEC2Lock),
bypassEC3Lock: new PerkState(db.bypassEC3Lock),
bypassEC5Lock: new PerkState(db.bypassEC5Lock),
autocompleteEC1: new PerkState(db.autocompleteEC1),
autocompleteEC2: new PerkState(db.autocompleteEC2),
autocompleteEC3: new PerkState(db.autocompleteEC3),
studyActiveEP: new PerkState(db.studyActiveEP),
studyIdleEP: new PerkState(db.studyIdleEP),
studyECRequirement: new PerkState(db.studyECRequirement),
studyECBulk: new PerkState(db.studyECBulk),
retroactiveTP1: new PerkState(db.retroactiveTP1),
retroactiveTP2: new PerkState(db.retroactiveTP2),
retroactiveTP3: new PerkState(db.retroactiveTP3),
retroactiveTP4: new PerkState(db.retroactiveTP4),
autobuyerDilation: new PerkState(db.autobuyerDilation),
autobuyerFasterID: new PerkState(db.autobuyerFasterID),
autobuyerFasterReplicanti: new PerkState(db.autobuyerFasterReplicanti),
autobuyerFasterDilation: new PerkState(db.autobuyerFasterDilation),
ttFree: new PerkState(db.ttFree),
ttBuySingle: new PerkState(db.ttBuySingle),
ttBuyMax: new PerkState(db.ttBuyMax),
achievementGroup1: new PerkState(db.achievementGroup1),
achievementGroup2: new PerkState(db.achievementGroup2),
achievementGroup3: new PerkState(db.achievementGroup3),
achievementGroup4: new PerkState(db.achievementGroup4),
achievementGroup5: new PerkState(db.achievementGroup5)
};
}());
export const Perks = { export const Perks = {
all: Object.values(Perk), all: Perk.all,
/** /**
* @param {number} id * @param {number} id
* @returns {PerkState} * @returns {PerkState}

View File

@ -1,7 +1,7 @@
import { GlyphTypes } from "./glyph-effects.js"; import { AUTOMATOR_MODE, AUTOMATOR_TYPE } from "./automator/automator-backend";
import { AUTOMATOR_MODE, AUTOMATOR_TYPE } from "./automator/automator-backend.js"; import { DC } from "./constants";
import { DC } from "./constants.js";
import { deepmergeAll } from "@/utility/deepmerge"; import { deepmergeAll } from "@/utility/deepmerge";
import { GlyphTypes } from "./glyph-effects";
// This is actually reassigned when importing saves // This is actually reassigned when importing saves
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
@ -811,7 +811,8 @@ window.player = {
bigCrunch: true, bigCrunch: true,
replicantiGalaxy: true, replicantiGalaxy: true,
antimatterGalaxy: true, antimatterGalaxy: true,
dimensionBoost: true dimensionBoost: true,
switchAutomatorMode: true
}, },
awayProgress: { awayProgress: {
antimatter: true, antimatter: true,
@ -984,7 +985,7 @@ export function guardFromNaNValues(obj) {
} }
for (const key in obj) { for (const key in obj) {
if (!obj.hasOwnProperty(key)) continue; if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
// TODO: rework autobuyer saving // TODO: rework autobuyer saving
if (key === "automator") continue; if (key === "automator") continue;

View File

@ -1,4 +1,4 @@
import { BitPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index.js"; import { BitPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index";
class RealityUpgradeState extends BitPurchasableMechanicState { class RealityUpgradeState extends BitPurchasableMechanicState {
constructor(config) { constructor(config) {

View File

@ -1,4 +1,4 @@
import { DC } from "./constants.js"; import { DC } from "./constants";
/** /**
* Object that manages the selection of glyphs offered to the player * Object that manages the selection of glyphs offered to the player
@ -180,8 +180,8 @@ function triggerManualReality(realityProps) {
export function runRealityAnimation() { export function runRealityAnimation() {
document.getElementById("ui").style.userSelect = "none"; document.getElementById("ui").style.userSelect = "none";
document.getElementById("ui").style.animation = "realize 10s 1"; document.getElementById("ui").style.animation = "a-realize 10s 1";
document.getElementById("realityanimbg").style.animation = "realizebg 10s 1"; document.getElementById("realityanimbg").style.animation = "a-realizebg 10s 1";
document.getElementById("realityanimbg").style.display = "block"; document.getElementById("realityanimbg").style.display = "block";
setTimeout(() => { setTimeout(() => {
document.getElementById("realityanimbg").play(); document.getElementById("realityanimbg").play();

View File

@ -1,4 +1,4 @@
import { DC } from "./constants.js"; import { DC } from "./constants";
// Slowdown parameters for replicanti growth, interval will increase by scaleFactor for every scaleLog10 // Slowdown parameters for replicanti growth, interval will increase by scaleFactor for every scaleLog10
// OoM past the cap (default is 308.25 (log10 of 1.8e308), 1.2, Number.MAX_VALUE) // OoM past the cap (default is 308.25 (log10 of 1.8e308), 1.2, Number.MAX_VALUE)

View File

@ -1,4 +1,4 @@
import { DC } from "./constants.js"; import { DC } from "./constants";
export class Sacrifice { export class Sacrifice {
// This is tied to the "buying an 8th dimension" achievement in order to hide it from new players before they reach // This is tied to the "buying an 8th dimension" achievement in order to hide it from new players before they reach

View File

@ -1,5 +1,5 @@
import { GameDatabase } from "../game-database.js"; import { DC } from "../../constants";
import { DC } from "../../constants.js"; import { GameDatabase } from "../game-database";
GameDatabase.achievements.normal = [ GameDatabase.achievements.normal = [
{ {
@ -702,7 +702,7 @@ GameDatabase.achievements.normal = [
id: 102, id: 102,
name: "This mile took an eternity", name: "This mile took an eternity",
description: "Get all Eternity milestones.", description: "Get all Eternity milestones.",
checkRequirement: () => EternityMilestones.all.every(m => m.isReached), checkRequirement: () => EternityMilestone.all.every(m => m.isReached),
checkEvent: GAME_EVENT.GAME_TICK_AFTER checkEvent: GAME_EVENT.GAME_TICK_AFTER
}, },
{ {
@ -1305,7 +1305,8 @@ GameDatabase.achievements.normal = [
id: 182, id: 182,
name: "One more time", name: "One more time",
description: "Gain back all Antimatter Dimension autobuyers.", description: "Gain back all Antimatter Dimension autobuyers.",
checkRequirement: () => player.celestials.pelle.upgrades.has(4), checkRequirement: () => PelleUpgrade.antimatterDimAutobuyers1.canBeApplied &&
PelleUpgrade.antimatterDimAutobuyers2.canBeApplied,
checkEvent: GAME_EVENT.GAME_TICK_AFTER checkEvent: GAME_EVENT.GAME_TICK_AFTER
}, },
{ {

View File

@ -1,4 +1,4 @@
import { GameDatabase } from "../game-database.js"; import { GameDatabase } from "../game-database";
GameDatabase.achievements.secret = [ GameDatabase.achievements.secret = [
{ {

View File

@ -1,4 +1,4 @@
import { GameDatabase } from "./game-database.js"; import { GameDatabase } from "./game-database";
GameDatabase.awayProgressTypes = [ GameDatabase.awayProgressTypes = [
{ {

View File

@ -1,443 +1,462 @@
import { GameDatabase } from "../game-database.js"; import { DC } from "../../constants";
import { DC } from "../../constants.js"; import { GameDatabase } from "../game-database";
GameDatabase.celestials.alchemy = { GameDatabase.celestials.alchemy.resources = {
resources: { // T1 resources (Non-Effarig "base" resources)
// T1 resources (Non-Effarig "base" resources) "power": {
[ALCHEMY_RESOURCE.POWER]: { id: ALCHEMY_RESOURCE.POWER,
name: "Power", name: "Power",
symbol: "Ω", symbol: "Ω",
isBaseResource: true, isBaseResource: true,
effect: amount => 1 + amount / 200000, effect: amount => 1 + amount / 200000,
tier: 1, tier: 1,
uiOrder: 1, uiOrder: 1,
unlockedAt: 2, unlockedAt: 2,
description: "provides a multiplier to Antimatter Dimensions", description: "provides a multiplier to Antimatter Dimensions",
formatEffect: value => `Antimatter Dimension multipliers ${formatPow(value, 4, 4)}` formatEffect: value => `Antimatter Dimension multipliers ${formatPow(value, 4, 4)}`
}, },
[ALCHEMY_RESOURCE.INFINITY]: { "infinity": {
name: "Infinity", id: ALCHEMY_RESOURCE.INFINITY,
symbol: "∞", name: "Infinity",
isBaseResource: true, symbol: "∞",
effect: amount => 1 + amount / 200000, isBaseResource: true,
tier: 1, effect: amount => 1 + amount / 200000,
uiOrder: 2, tier: 1,
unlockedAt: 3, uiOrder: 2,
description: "provides a multiplier to Infinity Dimensions", unlockedAt: 3,
formatEffect: value => `Infinity Dimension multipliers ${formatPow(value, 4, 4)}` description: "provides a multiplier to Infinity Dimensions",
}, formatEffect: value => `Infinity Dimension multipliers ${formatPow(value, 4, 4)}`
[ALCHEMY_RESOURCE.TIME]: { },
name: "Time", "time": {
symbol: "Δ", id: ALCHEMY_RESOURCE.TIME,
isBaseResource: true, name: "Time",
effect: amount => 1 + amount / 200000, symbol: "Δ",
tier: 1, isBaseResource: true,
uiOrder: 3, effect: amount => 1 + amount / 200000,
unlockedAt: 4, tier: 1,
description: "provides a multiplier to Time Dimensions", uiOrder: 3,
formatEffect: value => `Time Dimension multipliers ${formatPow(value, 4, 4)}` unlockedAt: 4,
}, description: "provides a multiplier to Time Dimensions",
[ALCHEMY_RESOURCE.REPLICATION]: { formatEffect: value => `Time Dimension multipliers ${formatPow(value, 4, 4)}`
name: "Replication", },
symbol: "Ξ", "replication": {
isBaseResource: true, id: ALCHEMY_RESOURCE.REPLICATION,
effect: amount => Decimal.pow10(amount / 1000), name: "Replication",
tier: 1, symbol: "Ξ",
uiOrder: 4, isBaseResource: true,
unlockedAt: 5, effect: amount => Decimal.pow10(amount / 1000),
description: `increases Replication Speed`, tier: 1,
formatEffect: value => `Replication speed is increased by ${formatX(value, 2, 2)}` uiOrder: 4,
}, unlockedAt: 5,
[ALCHEMY_RESOURCE.DILATION]: { description: `increases Replication Speed`,
name: "Dilation", formatEffect: value => `Replication speed is increased by ${formatX(value, 2, 2)}`
symbol: "Ψ", },
isBaseResource: true, "dilation": {
effect: amount => Decimal.pow10(amount / 2000), id: ALCHEMY_RESOURCE.DILATION,
tier: 1, name: "Dilation",
uiOrder: 5, symbol: "Ψ",
unlockedAt: 6, isBaseResource: true,
description: "increases Dilated Time production", effect: amount => Decimal.pow10(amount / 2000),
formatEffect: value => `Dilated Time production is increased by ${formatX(value, 2, 2)}` tier: 1,
}, uiOrder: 5,
unlockedAt: 6,
description: "increases Dilated Time production",
formatEffect: value => `Dilated Time production is increased by ${formatX(value, 2, 2)}`
},
// T2 resources (combinations of pairs of T1 resources) // T2 resources (combinations of pairs of T1 resources)
[ALCHEMY_RESOURCE.CARDINALITY]: { "cardinality": {
name: "Cardinality", id: ALCHEMY_RESOURCE.CARDINALITY,
symbol: "α", name: "Cardinality",
isBaseResource: false, symbol: "α",
effect: amount => 1 + 0.2 / (1 + amount / 20000), isBaseResource: false,
tier: 2, effect: amount => 1 + 0.2 / (1 + amount / 20000),
uiOrder: 3, tier: 2,
unlockedAt: 8, uiOrder: 3,
get description() { return `reduces the slowdown per ${format(Number.MAX_VALUE, 2)} Replicanti`; }, unlockedAt: 8,
formatEffect: value => `Replicanti interval increases slower ${formatX(1.2, 1, 1)}` + get description() { return `reduces the slowdown per ${format(Number.MAX_VALUE, 2)} Replicanti`; },
`${formatX(value, 4, 4)} per ${format(Number.MAX_VALUE, 2)}`, formatEffect: value => `Replicanti interval increases slower ${formatX(1.2, 1, 1)}
reagents: [ ${formatX(value, 4, 4)} per ${format(Number.MAX_VALUE, 2)}`,
{ reagents: [
resource: ALCHEMY_RESOURCE.TIME, {
amount: 8 resource: ALCHEMY_RESOURCE.TIME,
}, amount: 8
{
resource: ALCHEMY_RESOURCE.REPLICATION,
amount: 7
}
]
},
[ALCHEMY_RESOURCE.ETERNITY]: {
name: "Eternity",
symbol: "τ",
isBaseResource: false,
effect: amount => 1 + amount / 15000,
tier: 2,
uiOrder: 2,
unlockedAt: 9,
description: "increases Eternity generation",
formatEffect: value => `Eternity generation ${formatPow(value, 4, 4)}`,
reagents: [
{
resource: ALCHEMY_RESOURCE.TIME,
amount: 11
},
{
resource: ALCHEMY_RESOURCE.INFINITY,
amount: 4
}
]
},
[ALCHEMY_RESOURCE.DIMENSIONALITY]: {
name: "Dimensionality",
symbol: "ρ",
isBaseResource: false,
effect: amount => Decimal.pow10(5 * amount),
tier: 2,
uiOrder: 1,
unlockedAt: 10,
description: "provides a multiplier to all dimensions",
formatEffect: value => `All Dimensions ${formatX(value)}`,
reagents: [
{
resource: ALCHEMY_RESOURCE.POWER,
amount: 10
},
{
resource: ALCHEMY_RESOURCE.INFINITY,
amount: 5
}
]
},
[ALCHEMY_RESOURCE.INFLATION]: {
name: "Inflation",
symbol: "λ",
isBaseResource: false,
effect: amount => Decimal.pow10(6e9 - 3e5 * amount),
tier: 2,
uiOrder: 5,
unlockedAt: 11,
description: "increases multiplier effect over a threshold",
formatEffect: value => `All Antimatter Dimension multipliers are ${formatPow(1.05, 2, 2)}
if they are above ${format(value)} `,
reagents: [
{
resource: ALCHEMY_RESOURCE.POWER,
amount: 9
},
{
resource: ALCHEMY_RESOURCE.DILATION,
amount: 6
}
]
},
[ALCHEMY_RESOURCE.ALTERNATION]: {
name: "Alternation",
symbol: "ω",
isBaseResource: false,
effect: amount => amount / 200000,
tier: 2,
uiOrder: 4,
unlockedAt: 12,
description: "increases the strength of Tachyon Galaxies based on Replicanti",
formatEffect: value => `Tachyon Galaxies are ${formatPercents(value, 2, 2)} stronger ` +
`per ${format(DC.E1E6)} Replicanti`,
reagents: [
{
resource: ALCHEMY_RESOURCE.REPLICATION,
amount: 5
},
{
resource: ALCHEMY_RESOURCE.DILATION,
amount: 10
}
]
},
// T3 resources (Effarig and conbinations of T1/T2 with Effarig)
[ALCHEMY_RESOURCE.EFFARIG]: {
name: "Effarig",
symbol: "Ϙ",
isBaseResource: true,
effect: amount => Math.pow(10, amount / 2500),
tier: 2,
uiOrder: 3.5,
unlockedAt: 7,
description: "increases Relic Shard gain",
formatEffect: value => `Relic Shard gain is multiplied ${formatX(value, 2, 2)}`
},
[ALCHEMY_RESOURCE.SYNERGISM]: {
name: "Synergism",
symbol: "π",
isBaseResource: false,
effect: amount => Math.clampMax(0.3 + Math.sqrt(amount / 15000), 1),
tier: 3,
uiOrder: 2,
unlockedAt: 13,
description: "increases the effectiveness of Alchemy Reactions",
formatEffect(value) {
const baseEffect = `Alchemy reaction efficiency ${formatPercents(0.3)}${formatPercents(value, 2, 2)}`;
if (player.reality.glyphs.sac.reality === 0) {
return baseEffect;
}
const increasedYield = formatPercents(value * Effects.sum(GlyphSacrifice.reality), 2, 2);
return `${baseEffect} (${increasedYield} after Glyph Sacrifice)`;
}, },
reagents: [ {
{ resource: ALCHEMY_RESOURCE.REPLICATION,
resource: ALCHEMY_RESOURCE.EFFARIG, amount: 7
amount: 3 }
}, ]
{ },
resource: ALCHEMY_RESOURCE.REPLICATION, "eternity": {
amount: 16 id: ALCHEMY_RESOURCE.ETERNITY,
}, name: "Eternity",
{ symbol: "τ",
resource: ALCHEMY_RESOURCE.INFINITY, isBaseResource: false,
amount: 14 effect: amount => 1 + amount / 15000,
} tier: 2,
] uiOrder: 2,
}, unlockedAt: 9,
[ALCHEMY_RESOURCE.MOMENTUM]: { description: "increases Eternity generation",
name: "Momentum", formatEffect: value => `Eternity generation ${formatPow(value, 4, 4)}`,
symbol: "μ", reagents: [
isBaseResource: false, {
effect: amount => 1 + amount / 125000, resource: ALCHEMY_RESOURCE.TIME,
tier: 3, amount: 11
uiOrder: 3, },
unlockedAt: 15, {
description: "provides a multiplier to all dimensions based on real time since unlock", resource: ALCHEMY_RESOURCE.INFINITY,
formatEffect: value => `All Dimensions ${formatPow(Ra.momentumValue, 4, 4)}, increasing by amount: 4
${format(0.002 * Achievement(175).effectOrDefault(1), 3, 3)} }
per real-time hour after the resource is unlocked, up to a maximum of ${formatPow(value, 4, 4)}`, ]
reagents: [ },
{ "dimensionality": {
resource: ALCHEMY_RESOURCE.EFFARIG, id: ALCHEMY_RESOURCE.DIMENSIONALITY,
amount: 11 name: "Dimensionality",
}, symbol: "ρ",
{ isBaseResource: false,
resource: ALCHEMY_RESOURCE.POWER, effect: amount => Decimal.pow10(5 * amount),
amount: 4 tier: 2,
}, uiOrder: 1,
{ unlockedAt: 10,
resource: ALCHEMY_RESOURCE.TIME, description: "provides a multiplier to all dimensions",
amount: 20 formatEffect: value => `All Dimensions ${formatX(value)}`,
} reagents: [
] {
}, resource: ALCHEMY_RESOURCE.POWER,
[ALCHEMY_RESOURCE.DECOHERENCE]: { amount: 10
name: "Decoherence", },
symbol: "ξ", {
isBaseResource: false, resource: ALCHEMY_RESOURCE.INFINITY,
effect: amount => 0.10 * Math.sqrt(amount / 10000), amount: 5
tier: 3, }
uiOrder: 4, ]
unlockedAt: 14, },
description: "causes refining to give all basic Alchemy Resources", "inflation": {
formatEffect: value => `Refined Glyphs also give ${formatPercents(value, 2)} of their value ` + id: ALCHEMY_RESOURCE.INFLATION,
"to all other base resources", name: "Inflation",
reagents: [ symbol: "λ",
{ isBaseResource: false,
resource: ALCHEMY_RESOURCE.EFFARIG, effect: amount => Decimal.pow10(6e9 - 3e5 * amount),
amount: 13 tier: 2,
}, uiOrder: 5,
{ unlockedAt: 11,
resource: ALCHEMY_RESOURCE.ALTERNATION, description: "increases multiplier effect over a threshold",
amount: 8 formatEffect: value => `All Antimatter Dimension multipliers are ${formatPow(1.05, 2, 2)}
} if they are above ${format(value)} `,
] reagents: [
}, {
resource: ALCHEMY_RESOURCE.POWER,
amount: 9
},
{
resource: ALCHEMY_RESOURCE.DILATION,
amount: 6
}
]
},
"alternation": {
id: ALCHEMY_RESOURCE.ALTERNATION,
name: "Alternation",
symbol: "ω",
isBaseResource: false,
effect: amount => amount / 200000,
tier: 2,
uiOrder: 4,
unlockedAt: 12,
description: "increases the strength of Tachyon Galaxies based on Replicanti",
formatEffect: value => `Tachyon Galaxies are ${formatPercents(value, 2, 2)} stronger
per ${format(DC.E1E6)} Replicanti`,
reagents: [
{
resource: ALCHEMY_RESOURCE.REPLICATION,
amount: 5
},
{
resource: ALCHEMY_RESOURCE.DILATION,
amount: 10
}
]
},
// T4 resources (resources which feed directly into the final resource) // T3 resources (Effarig and conbinations of T1/T2 with Effarig)
[ALCHEMY_RESOURCE.EXPONENTIAL]: { "effarig": {
name: "Exponential", id: ALCHEMY_RESOURCE.EFFARIG,
symbol: "Γ", name: "Effarig",
isBaseResource: false, symbol: "Ϙ",
effect: amount => 10 * Math.pow(amount / 10000, 2), isBaseResource: true,
tier: 4, effect: amount => Math.pow(10, amount / 2500),
uiOrder: 2, tier: 2,
unlockedAt: 18, uiOrder: 3.5,
description: "multiplies Infinity Points by Replicanti", unlockedAt: 7,
formatEffect: value => `Infinity Points multiplied by Replicanti${formatPow(value, 2, 3)}`, description: "increases Relic Shard gain",
reagents: [ formatEffect: value => `Relic Shard gain is multiplied ${formatX(value, 2, 2)}`
{ },
resource: ALCHEMY_RESOURCE.INFLATION, "synergism": {
amount: 18 id: ALCHEMY_RESOURCE.SYNERGISM,
}, name: "Synergism",
{ symbol: "π",
resource: ALCHEMY_RESOURCE.SYNERGISM, isBaseResource: false,
amount: 3 effect: amount => Math.clampMax(0.3 + Math.sqrt(amount / 15000), 1),
} tier: 3,
] uiOrder: 2,
}, unlockedAt: 13,
[ALCHEMY_RESOURCE.FORCE]: { description: "increases the effectiveness of Alchemy Reactions",
name: "Force", formatEffect(value) {
symbol: "Φ", const baseEffect = `Alchemy reaction efficiency ${formatPercents(0.3)}${formatPercents(value, 2, 2)}`;
isBaseResource: false, if (player.reality.glyphs.sac.reality === 0) {
effect: amount => 5 * amount, return baseEffect;
tier: 4, }
uiOrder: 2, const increasedYield = formatPercents(value * Effects.sum(GlyphSacrifice.reality), 2, 2);
unlockedAt: 17, return `${baseEffect} (${increasedYield} after Glyph Sacrifice)`;
description: "multiplies Antimatter Dimensions by Reality Machines",
formatEffect: value => `Multiply Antimatter Dimensions by Reality Machines${formatPow(value, 2, 2)}`,
reagents: [
{
resource: ALCHEMY_RESOURCE.DIMENSIONALITY,
amount: 7
},
{
resource: ALCHEMY_RESOURCE.MOMENTUM,
amount: 8
}
]
},
[ALCHEMY_RESOURCE.UNCOUNTABILITY]: {
name: "Uncountability",
symbol: "Θ",
isBaseResource: false,
effect: amount => Math.sqrt(amount),
tier: 4,
uiOrder: 3,
unlockedAt: 19,
description: "passively generates Realities and Perk Points",
formatEffect: value => `Generate ${format(value, 2, 2)} Realities and Perk Points per second`,
reagents: [
{
resource: ALCHEMY_RESOURCE.INFINITY,
amount: 20
},
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 6
},
{
resource: ALCHEMY_RESOURCE.CARDINALITY,
amount: 16
}
]
},
[ALCHEMY_RESOURCE.BOUNDLESS]: {
name: "Boundless",
symbol: "Π",
isBaseResource: false,
effect: amount => amount / 80000,
tier: 4,
uiOrder: 1,
unlockedAt: 20,
description: "makes Tesseracts stronger",
formatEffect: value => `Tesseracts are +${formatPercents(value, 2, 2)} stronger`,
reagents: [
{
resource: ALCHEMY_RESOURCE.ETERNITY,
amount: 13
},
{
resource: ALCHEMY_RESOURCE.INFLATION,
amount: 18
}
]
},
[ALCHEMY_RESOURCE.MULTIVERSAL]: {
name: "Multiversal",
symbol: "Σ",
isBaseResource: false,
effect: amount => 5 * Math.pow(amount / 10000, 2),
tier: 4,
uiOrder: 5,
unlockedAt: 16,
description: "makes each Reality simulate more Realities",
formatEffect: value => `Each Reality simulates ${format(value, 2, 3)} additional Realities, giving all
the same rewards as if it was amplified`,
reagents: [
{
resource: ALCHEMY_RESOURCE.ALTERNATION,
amount: 16
},
{
resource: ALCHEMY_RESOURCE.DECOHERENCE,
amount: 3
}
]
},
[ALCHEMY_RESOURCE.UNPREDICTABILITY]: {
name: "Unpredictability",
symbol: "Λ",
isBaseResource: false,
effect: amount => amount / (10000 + amount),
tier: 4,
uiOrder: 4,
unlockedAt: 21,
description: "makes each Alchemy Reaction have a chance to happen twice",
formatEffect: value => `Any alchemy reaction has a ${formatPercents(value, 2, 2)}
chance of triggering again`,
reagents: [
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 15
},
{
resource: ALCHEMY_RESOURCE.DECOHERENCE,
amount: 3
},
{
resource: ALCHEMY_RESOURCE.SYNERGISM,
amount: 10
}
]
}, },
reagents: [
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 3
},
{
resource: ALCHEMY_RESOURCE.REPLICATION,
amount: 16
},
{
resource: ALCHEMY_RESOURCE.INFINITY,
amount: 14
}
]
},
"momentum": {
id: ALCHEMY_RESOURCE.MOMENTUM,
name: "Momentum",
symbol: "μ",
isBaseResource: false,
effect: amount => 1 + amount / 125000,
tier: 3,
uiOrder: 3,
unlockedAt: 15,
description: "provides a multiplier to all dimensions based on real time since unlock",
formatEffect: value => `All Dimensions ${formatPow(Ra.momentumValue, 4, 4)}, increasing by
${format(0.002 * Achievement(175).effectOrDefault(1), 3, 3)}
per real-time hour after the resource is unlocked, up to a maximum of ${formatPow(value, 4, 4)}`,
reagents: [
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 11
},
{
resource: ALCHEMY_RESOURCE.POWER,
amount: 4
},
{
resource: ALCHEMY_RESOURCE.TIME,
amount: 20
}
]
},
"decoherence": {
id: ALCHEMY_RESOURCE.DECOHERENCE,
name: "Decoherence",
symbol: "ξ",
isBaseResource: false,
effect: amount => 0.10 * Math.sqrt(amount / 10000),
tier: 3,
uiOrder: 4,
unlockedAt: 14,
description: "causes refining to give all basic Alchemy Resources",
formatEffect: value => `Refined Glyphs also give ${formatPercents(value, 2)} of their value ` +
"to all other base resources",
reagents: [
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 13
},
{
resource: ALCHEMY_RESOURCE.ALTERNATION,
amount: 8
}
]
},
// T5 (Reality) // T4 resources (resources which feed directly into the final resource)
[ALCHEMY_RESOURCE.REALITY]: { "exponential": {
name: "Reality", id: ALCHEMY_RESOURCE.EXPONENTIAL,
symbol: "Ϟ", name: "Exponential",
isBaseResource: false, symbol: "Γ",
effect: amount => Math.floor(amount), isBaseResource: false,
tier: 5, effect: amount => 10 * Math.pow(amount / 10000, 2),
unlockedAt: 25, tier: 4,
description: "allows creation of Reality Glyphs", uiOrder: 2,
formatEffect: value => `Consume all Reality resource to create a level ${formatInt(value)} Reality Glyph`, unlockedAt: 18,
reagents: [ description: "multiplies Infinity Points by Replicanti",
{ formatEffect: value => `Infinity Points multiplied by Replicanti${formatPow(value, 2, 3)}`,
resource: ALCHEMY_RESOURCE.EXPONENTIAL, reagents: [
amount: 1 {
}, resource: ALCHEMY_RESOURCE.INFLATION,
{ amount: 18
resource: ALCHEMY_RESOURCE.FORCE, },
amount: 1 {
}, resource: ALCHEMY_RESOURCE.SYNERGISM,
{ amount: 3
resource: ALCHEMY_RESOURCE.UNCOUNTABILITY, }
amount: 1 ]
}, },
{ "force": {
resource: ALCHEMY_RESOURCE.BOUNDLESS, id: ALCHEMY_RESOURCE.FORCE,
amount: 1 name: "Force",
}, symbol: "Φ",
{ isBaseResource: false,
resource: ALCHEMY_RESOURCE.MULTIVERSAL, effect: amount => 5 * amount,
amount: 1 tier: 4,
}, uiOrder: 2,
{ unlockedAt: 17,
resource: ALCHEMY_RESOURCE.UNPREDICTABILITY, description: "multiplies Antimatter Dimensions by Reality Machines",
amount: 1 formatEffect: value => `Multiply Antimatter Dimensions by Reality Machines${formatPow(value, 2, 2)}`,
} reagents: [
] {
}, resource: ALCHEMY_RESOURCE.DIMENSIONALITY,
amount: 7
},
{
resource: ALCHEMY_RESOURCE.MOMENTUM,
amount: 8
}
]
},
"uncountability": {
id: ALCHEMY_RESOURCE.UNCOUNTABILITY,
name: "Uncountability",
symbol: "Θ",
isBaseResource: false,
effect: amount => Math.sqrt(amount),
tier: 4,
uiOrder: 3,
unlockedAt: 19,
description: "passively generates Realities and Perk Points",
formatEffect: value => `Generate ${format(value, 2, 2)} Realities and Perk Points per second`,
reagents: [
{
resource: ALCHEMY_RESOURCE.INFINITY,
amount: 20
},
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 6
},
{
resource: ALCHEMY_RESOURCE.CARDINALITY,
amount: 16
}
]
},
"boundless": {
id: ALCHEMY_RESOURCE.BOUNDLESS,
name: "Boundless",
symbol: "Π",
isBaseResource: false,
effect: amount => amount / 80000,
tier: 4,
uiOrder: 1,
unlockedAt: 20,
description: "makes Tesseracts stronger",
formatEffect: value => `Tesseracts are +${formatPercents(value, 2, 2)} stronger`,
reagents: [
{
resource: ALCHEMY_RESOURCE.ETERNITY,
amount: 13
},
{
resource: ALCHEMY_RESOURCE.INFLATION,
amount: 18
}
]
},
"multiversal": {
id: ALCHEMY_RESOURCE.MULTIVERSAL,
name: "Multiversal",
symbol: "Σ",
isBaseResource: false,
effect: amount => 5 * Math.pow(amount / 10000, 2),
tier: 4,
uiOrder: 5,
unlockedAt: 16,
description: "makes each Reality simulate more Realities",
formatEffect: value => `Each Reality simulates ${format(value, 2, 3)} additional Realities, giving all
the same rewards as if it was amplified`,
reagents: [
{
resource: ALCHEMY_RESOURCE.ALTERNATION,
amount: 16
},
{
resource: ALCHEMY_RESOURCE.DECOHERENCE,
amount: 3
}
]
},
"unpredictability": {
id: ALCHEMY_RESOURCE.UNPREDICTABILITY,
name: "Unpredictability",
symbol: "Λ",
isBaseResource: false,
effect: amount => amount / (10000 + amount),
tier: 4,
uiOrder: 4,
unlockedAt: 21,
description: "makes each Alchemy Reaction have a chance to happen twice",
formatEffect: value => `Any alchemy reaction has a ${formatPercents(value, 2, 2)}
chance of triggering again`,
reagents: [
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 15
},
{
resource: ALCHEMY_RESOURCE.DECOHERENCE,
amount: 3
},
{
resource: ALCHEMY_RESOURCE.SYNERGISM,
amount: 10
}
]
},
// T5 (Reality)
"reality": {
id: ALCHEMY_RESOURCE.REALITY,
name: "Reality",
symbol: "Ϟ",
isBaseResource: false,
effect: amount => Math.floor(amount),
tier: 5,
unlockedAt: 25,
description: "allows creation of Reality Glyphs",
formatEffect: value => `Consume all Reality resource to create a level ${formatInt(value)} Reality Glyph`,
reagents: [
{
resource: ALCHEMY_RESOURCE.EXPONENTIAL,
amount: 1
},
{
resource: ALCHEMY_RESOURCE.FORCE,
amount: 1
},
{
resource: ALCHEMY_RESOURCE.UNCOUNTABILITY,
amount: 1
},
{
resource: ALCHEMY_RESOURCE.BOUNDLESS,
amount: 1
},
{
resource: ALCHEMY_RESOURCE.MULTIVERSAL,
amount: 1
},
{
resource: ALCHEMY_RESOURCE.UNPREDICTABILITY,
amount: 1
}
]
}, },
}; };

View File

@ -1,56 +1,70 @@
import { GameDatabase } from "../game-database.js"; import { DC } from "../../constants";
import { DC } from "../../constants.js"; import { GameDatabase } from "../game-database";
GameDatabase.celestials.effarig = { GameDatabase.celestials.effarig.unlocks = {
unlocks: { adjuster: {
adjuster: { id: 0,
id: 0, description: "Adjustable Glyph level factor weights",
description: "Adjustable Glyph level factor weights", cost: 1e7,
cost: 1e7 onPurchased: () => {
}, Effarig.quotes.show(Effarig.quotes.UNLOCK_WEIGHTS);
glyphFilter: { ui.view.tabs.reality.openGlyphWeights = true;
id: 1, Tab.reality.glyphs.show();
description: "Glyph Filtering", }
cost: 2e8 },
}, glyphFilter: {
setSaves: { id: 1,
id: 2, description: "Glyph Filtering",
description: "Glyph Set Saves", cost: 2e8,
cost: 3e9 onPurchased: () => {
}, Effarig.quotes.show(Effarig.quotes.UNLOCK_GLYPH_FILTER);
run: { player.reality.showSidebarPanel = GLYPH_SIDEBAR_MODE.FILTER_SETTINGS;
id: 3, }
description: "Effarig's Reality", },
cost: 5e11 setSaves: {
}, id: 2,
infinity: { description: "Glyph Set Saves",
id: 4, cost: 3e9,
label: "Infinity", onPurchased: () => {
get description() { Effarig.quotes.show(Effarig.quotes.UNLOCK_SET_SAVES);
if (Pelle.isDoomed) return "Any rewards from Effarig's Infinity have been disabled."; player.reality.showSidebarPanel = GLYPH_SIDEBAR_MODE.SAVED_SETS;
return ` Infinities raise the Replicanti cap }
},
run: {
id: 3,
description: "Effarig's Reality",
cost: 5e11,
onPurchased: () => {
Effarig.quotes.show(Effarig.quotes.UNLOCK_RUN);
}
},
infinity: {
id: 4,
label: "Infinity",
get description() {
if (Pelle.isDoomed) return "Any rewards from Effarig's Infinity have been disabled.";
return ` Infinities raise the Replicanti cap
Infinities increase your max Replicanti Galaxies Infinities increase your max Replicanti Galaxies
Base Infinity Point gain is capped at ${format(DC.E200)} in Effarig's Reality Base Infinity Point gain is capped at ${format(DC.E200)} in Effarig's Reality
Each type of Infinity Point multiplier is capped at ${format(DC.E50)} in Effarig's Reality`; Each type of Infinity Point multiplier is capped at ${format(DC.E50)} in Effarig's Reality`;
},
}, },
eternity: { },
id: 5, eternity: {
label: "Eternity", id: 5,
get description() { label: "Eternity",
if (Pelle.isDoomed) return "Any rewards from Effarig's Eternity have been disabled."; get description() {
return ` Eternities generates Infinities if (Pelle.isDoomed) return "Any rewards from Effarig's Eternity have been disabled.";
Infinity Points are no longer limited in any way in Effarig's Reality return ` Eternities generates Infinities
You have unlocked The Enslaved Ones`; Infinity Points are no longer limited in any way in Effarig's Reality
}, You have unlocked The Enslaved Ones`;
},
},
reality: {
id: 6,
label: "Reality",
get description() {
if (Pelle.isDoomed) return "Any rewards from Effarig's Reality have been disabled.";
return " You have unlocked Effarig Glyphs (You may equip at most one)";
}, },
reality: {
id: 6,
label: "Reality",
get description() {
if (Pelle.isDoomed) return "Any rewards from Effarig's Reality have been disabled.";
return " You have unlocked Effarig Glyphs (You may equip at most one)";
},
}
} }
}; };

View File

@ -1,4 +1,4 @@
import { GameDatabase } from "../game-database.js"; import { GameDatabase } from "../game-database";
GameDatabase.celestials.enslaved = { GameDatabase.celestials.enslaved = {
// Note that "condition" isn't displayed in-game. These are meant to be indicators here of // Note that "condition" isn't displayed in-game. These are meant to be indicators here of
@ -60,7 +60,8 @@ GameDatabase.celestials.enslaved = {
glyphHints: [ glyphHints: [
"Infinity and Dilation Glyphs seem confined too tightly to be useful at all.", "Infinity and Dilation Glyphs seem confined too tightly to be useful at all.",
"Power and Time Glyphs are particularly strong here.", "Power and Time Glyphs are particularly strong here.",
"Effarig Glyphs are only useful with the right effects, but you can complete the Reality without one. " + `Effarig Glyphs are only useful with the right effects, but you can complete the Reality without one.
"A Replication Glyph is very helpful, but it's not strictly necessary or quite as strong " + A Replication Glyph is very helpful, but it's not strictly necessary or quite as strong
"as Power and Time."] as Power and Time.`
]
}; };

View File

@ -1,66 +1,65 @@
import { GameDatabase } from "../game-database.js"; import { GameDatabase } from "../game-database";
GameDatabase.celestials.pelle.galaxyGeneratorUpgrades = (function() { const formatCost = c => format(c, 2);
const formatCost = c => format(c, 2);
const rebuyable = config => { const rebuyable = config => {
const { id, description, cost, effect, formatEffect, currency, currencyLabel } = config; const { id, description, cost, effect, formatEffect, currency, currencyLabel } = config;
return {
id,
description,
cost: () => cost(player.celestials.pelle.rebuyables[id]),
formatCost,
effect: (x = player.celestials.pelle.rebuyables[id]) => effect(x),
formatEffect,
currency,
currencyLabel
};
};
return { return {
additive: rebuyable({ id,
id: "galaxyGeneratorAdditive", description,
description: "Increase base Galaxy generation by 2", cost: () => cost(player.celestials.pelle.rebuyables[id]),
cost: x => Math.pow(3, x), formatCost,
effect: x => x * 2, effect: (x = player.celestials.pelle.rebuyables[id]) => effect(x),
formatEffect: x => `${format(x, 2, 2)}/s`, formatEffect,
currency: () => Currency.galaxyGeneratorGalaxies, currency,
currencyLabel: "Galaxy" currencyLabel
}),
multiplicative: rebuyable({
id: "galaxyGeneratorMultiplicative",
description: "Multiply Galaxy generation",
cost: x => Math.pow(10, x),
effect: x => Decimal.pow(2.5, x),
formatEffect: x => formatX(x, 2, 1),
currency: () => Currency.galaxyGeneratorGalaxies,
currencyLabel: "Galaxy"
}),
antimatterMult: rebuyable({
id: "galaxyGeneratorAntimatterMult",
description: "Multiply Galaxy generation",
cost: x => Decimal.pow("1e100000000", 10 ** x),
effect: x => Decimal.pow(2, x),
formatEffect: x => formatX(x, 2),
currency: () => Currency.antimatter,
currencyLabel: "Antimatter"
}),
IPMult: rebuyable({
id: "galaxyGeneratorIPMult",
description: "Multiply Galaxy generation",
cost: x => Decimal.pow("1e2000000", 100 ** x),
effect: x => Decimal.pow(2, x),
formatEffect: x => formatX(x, 2),
currency: () => Currency.infinityPoints,
currencyLabel: "Infinity Point"
}),
EPMult: rebuyable({
id: "galaxyGeneratorEPMult",
description: "Multiply Galaxy generation",
cost: x => Decimal.pow("1e10000", 1000 ** x),
effect: x => Decimal.pow(2, x),
formatEffect: x => formatX(x, 2),
currency: () => Currency.eternityPoints,
currencyLabel: "Eternity Point"
}),
}; };
}()); };
GameDatabase.celestials.pelle.galaxyGeneratorUpgrades = {
additive: rebuyable({
id: "galaxyGeneratorAdditive",
description: "Increase base Galaxy generation by 2",
cost: x => Math.pow(3, x),
effect: x => x * 2,
formatEffect: x => `${format(x, 2, 2)}/s`,
currency: () => Currency.galaxyGeneratorGalaxies,
currencyLabel: "Galaxy"
}),
multiplicative: rebuyable({
id: "galaxyGeneratorMultiplicative",
description: "Multiply Galaxy generation",
cost: x => Math.pow(10, x),
effect: x => Decimal.pow(2.5, x),
formatEffect: x => formatX(x, 2, 1),
currency: () => Currency.galaxyGeneratorGalaxies,
currencyLabel: "Galaxy"
}),
antimatterMult: rebuyable({
id: "galaxyGeneratorAntimatterMult",
description: "Multiply Galaxy generation",
cost: x => Decimal.pow("1e100000000", 10 ** x),
effect: x => Decimal.pow(2, x),
formatEffect: x => formatX(x, 2),
currency: () => Currency.antimatter,
currencyLabel: "Antimatter"
}),
IPMult: rebuyable({
id: "galaxyGeneratorIPMult",
description: "Multiply Galaxy generation",
cost: x => Decimal.pow("1e2000000", 100 ** x),
effect: x => Decimal.pow(2, x),
formatEffect: x => formatX(x, 2),
currency: () => Currency.infinityPoints,
currencyLabel: "Infinity Point"
}),
EPMult: rebuyable({
id: "galaxyGeneratorEPMult",
description: "Multiply Galaxy generation",
cost: x => Decimal.pow("1e10000", 1000 ** x),
effect: x => Decimal.pow(2, x),
formatEffect: x => formatX(x, 2),
currency: () => Currency.eternityPoints,
currencyLabel: "Eternity Point"
}),
};

Some files were not shown because too many files have changed in this diff Show More