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": [
"eslint:recommended",
"plugin:import/recommended",
"plugin:vue/recommended"
],
"env": {
@ -14,7 +15,46 @@
"sourceType": "module",
"parser": "@babel/eslint-parser"
},
"settings": {
"import/resolver": {
"alias": {
"map": [
["@", "./src"]
],
"extensions": [".js", ".vue"]
}
}
},
"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-template-curly-in-string": "warn",
"array-callback-return": "error",
@ -32,7 +72,6 @@
"allowElseIf": false
}
],
"vue/one-component-per-file": "error",
"vue/component-definition-name-casing": "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 {
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 {
constructor(config) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import { Autobuyer } from "./autobuyer.js";
import { Autobuyer } from "./autobuyer";
export const Autobuyers = (function() {
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 {
get data() {

View File

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

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js";
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
Autobuyer.darkMatterDimsAscension =
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 {
get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js";
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
class DilationUpgradeAutobuyerState extends IntervaledAutobuyerState {
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 {
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 {
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 {
get data() {

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import { Autobuyer, AutobuyerState } from "./autobuyer.js";
import { Autobuyer, AutobuyerState } from "./autobuyer";
class RealityUpgradeAutobuyerState extends AutobuyerState {
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 {
get data() {

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js";
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
class ReplicantiUpgradeAutobuyerState extends IntervaledAutobuyerState {
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 {
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 {
get data() {

View File

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

View File

@ -1,4 +1,4 @@
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer.js";
import { Autobuyer, IntervaledAutobuyerState } from "./autobuyer";
class TimeDimensionAutobuyerState extends IntervaledAutobuyerState {
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 {
get data() {

View File

@ -111,7 +111,6 @@ class AutomatorStackEntry {
export class AutomatorScript {
constructor(id) {
if (!id) throw new Error("Invalid Automator script ID");
this._id = id;
this.compile();
}
@ -183,7 +182,7 @@ export const AutomatorData = {
createNewScript(newScript, name) {
const newScriptID = Object.values(player.reality.automator.scripts).length + 1;
player.reality.automator.scripts[newScriptID] = {
id: `${newScriptID}`,
id: newScriptID,
name,
content: newScript
};
@ -243,12 +242,31 @@ export const AutomatorBackend = {
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() {
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() {
if (this.stack.top === null)
if (!this.stack.top)
return -1;
return this.stack.top.lineNumber;
},
@ -257,6 +275,14 @@ export const AutomatorBackend = {
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) {
if (!this.isOn) return;
let stack;
@ -351,10 +377,7 @@ export const AutomatorBackend = {
},
findScript(id) {
// I tried really hard to convert IDs from strings into numbers for some cleanup but I just kept getting constant
// 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}`);
return this._scripts.find(e => e.id === id);
},
_createDefaultScript() {
@ -365,13 +388,13 @@ export const AutomatorBackend = {
},
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) {
scriptIds.push(this._createDefaultScript());
} else {
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);
if (currentScript.commands) {
const commands = currentScript.commands;
@ -392,10 +415,14 @@ export const AutomatorBackend = {
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) {
// 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);
this._scripts.splice(idx, 1);
delete player.reality.automator.scripts[id];
if (this._scripts.length === 0) {
this._createDefaultScript();
}

View File

@ -1,5 +1,5 @@
import { AutomatorGrammar } from "./parser.js";
import { AutomatorLexer } from "./lexer.js";
import { AutomatorGrammar } from "./parser";
import { AutomatorLexer } from "./lexer";
(function() {
function walkSuggestion(suggestion, prefix, output) {
@ -60,7 +60,7 @@ import { AutomatorLexer } from "./lexer.js";
{ regex: /blob\s\s/ui, token: "blob" },
{
// 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",
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.
@ -559,9 +559,9 @@ export const AutomatorCommands = ((() => {
})
},
{
id: "storeTime",
id: "storeGameTime",
rule: $ => () => {
$.CONSUME(T.StoreTime);
$.CONSUME(T.StoreGameTime);
$.OR([
{ ALT: () => $.CONSUME(T.On) },
{ ALT: () => $.CONSUME(T.Off) },
@ -569,10 +569,10 @@ export const AutomatorCommands = ((() => {
]);
},
validate: (ctx, V) => {
ctx.startLine = ctx.StoreTime[0].startLine;
ctx.startLine = ctx.StoreGameTime[0].startLine;
if (!Enslaved.isUnlocked) {
V.addError(ctx.StoreTime[0], "You do not yet know how to store time",
"Unlock the ability to store time");
V.addError(ctx.StoreGameTime[0], "You do not yet know how to store game time",
"Unlock the ability to store game time");
return false;
}
return true;
@ -581,9 +581,9 @@ export const AutomatorCommands = ((() => {
if (ctx.Use) return () => {
if (Enslaved.isUnlocked) {
Enslaved.useStoredTime(false);
AutomatorData.logCommandEvent(`Stored time used`, ctx.startLine);
AutomatorData.logCommandEvent(`Stored game time used`, ctx.startLine);
} 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);
}
return AUTOMATOR_COMMAND_STATUS.NEXT_INSTRUCTION;
@ -591,14 +591,14 @@ export const AutomatorCommands = ((() => {
const on = Boolean(ctx.On);
return () => {
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;
};
},
blockify: ctx => ({
// eslint-disable-next-line no-nested-ternary
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) {
AutomatorData.logCommandEvent(`Fully loaded study preset ${ctx.Preset[0].image}`, ctx.startLine);
} 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);
}
return ctx.Nowait !== undefined || missingStudyCount === 0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,8 @@
import { GameMechanicState, SetPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index.js";
import { DC } from "./constants.js";
import { SpeedrunMilestones } from "./speedrun.js";
import { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
export function bigCrunchAnimation() {
document.body.style.animation = "implode 2s 1";
setTimeout(() => {
document.body.style.animation = "";
}, 2000);
FullScreenAnimationHandler.display("a-implode", 2);
}
function handleChallengeCompletion() {
@ -25,7 +21,7 @@ function handleChallengeCompletion() {
export function bigCrunchResetRequest(disableAnimation = false) {
if (!Player.canCrunch) return;
if (!disableAnimation && player.options.animations.bigCrunch && document.body.style.animation === "") {
if (!disableAnimation && player.options.animations.bigCrunch && !FullScreenAnimationHandler.isDisplaying) {
bigCrunchAnimation();
setTimeout(bigCrunchReset, 1000);
} else {
@ -52,10 +48,10 @@ export function bigCrunchReset() {
if (Pelle.isDoomed) PelleStrikes.infinity.trigger();
EventHub.dispatch(GAME_EVENT.BIG_CRUNCH_AFTER);
if (firstInfinity && !Pelle.isDoomed) Modal.message.show(`Upon Infinity, all Dimensions, Dimension Boosts, and Antimatter
Galaxies are reset, but in return, you gain an Infinity Point (IP). This allows you to buy multiple upgrades that
you can find in the Infinity tab. You will also gain one Infinity, which is the stat shown in the Statistics
tab.`);
if (firstInfinity && !Pelle.isDoomed) Modal.message.show(`Upon Infinity, all Dimensions, Dimension Boosts, and
Antimatter Galaxies are reset, but in return, you gain an Infinity Point (IP). This allows you to buy multiple
upgrades that you can find in the Infinity tab. You will also gain one Infinity, which is the stat shown in the
Statistics tab.`);
}
function bigCrunchUpdateStatistics() {
@ -152,311 +148,6 @@ export function secondSoftReset(forcedNDReset = false) {
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) {
if (InfinityUpgrade.ipGen.isBought) {
const genPeriod = Time.bestInfinity.totalMilliseconds * 10;

View File

@ -1,5 +1,5 @@
import { DC } from "./constants.js";
import { SpeedrunMilestones } from "./speedrun.js";
import { DC } from "./constants";
import { SpeedrunMilestones } from "./speedrun";
class BlackHoleUpgradeState {
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 { GameMechanicState, BitUpgradeState } from "../game-mechanics/index.js";
import { CelestialQuotes } from "./quotes.js";
import { SpeedrunMilestones } from "../speedrun.js";
import { BitUpgradeState, GameMechanicState } from "../game-mechanics/index";
import { GameDatabase } from "../secret-formula/game-database";
import { SpeedrunMilestones } from "../speedrun";
import { CelestialQuotes } from "./quotes";
/**
* Information about how to format runUnlocks:

View File

@ -1,10 +1,10 @@
import { Teresa } from "./teresa.js";
import { Effarig } from "./effarig.js";
import { Enslaved } from "./enslaved.js";
import { V } from "./V.js";
import { Ra } from "./ra/ra.js";
import { Laitela } from "./laitela/laitela.js";
import { Effarig } from "./effarig";
import { Enslaved } from "./enslaved";
import { Laitela } from "./laitela/laitela";
import { Pelle } from "./pelle/pelle";
import { Ra } from "./ra/ra";
import { Teresa } from "./teresa";
import { V } from "./V";
export const Celestials = {
teresa: Teresa,
@ -44,7 +44,7 @@ GameDatabase.celestials.descriptions = [
Tachyon Particle production and Dilated Time production are severely reduced
Time Theorem generation from Dilation Glyphs is disabled
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.js";
import { CelestialQuotes } from "./quotes.js";
import { DC } from "../constants.js";
import { BitUpgradeState } from "../game-mechanics/index";
import { GameDatabase } from "../secret-formula/game-database";
import { DC } from "../constants";
import { CelestialQuotes } from "./quotes";
export const EFFARIG_STAGES = {
INFINITY: 1,
@ -176,41 +178,14 @@ class EffarigUnlockState extends BitUpgradeState {
purchase() {
if (this.isUnlocked || !Currency.relicShards.purchase(this.cost)) return;
this.unlock();
switch (this) {
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");
}
this.config.onPurchased?.();
}
}
export const EffarigUnlock = (function() {
const db = GameDatabase.celestials.effarig.unlocks;
return {
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),
};
}());
export const EffarigUnlock = mapGameDataToObject(
GameDatabase.celestials.effarig.unlocks,
config => new EffarigUnlockState(config)
);
EventHub.logic.on(GAME_EVENT.TAB_CHANGED, () => {
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.js";
import { CelestialQuotes } from "./quotes.js";
import { BitUpgradeState } from "../game-mechanics/index";
import { GameDatabase } from "../secret-formula/game-database";
import { CelestialQuotes } from "./quotes";
export const ENSLAVED_UNLOCKS = {
FREE_TICKSPEED_SOFTCAP: {
@ -265,19 +266,10 @@ class EnslavedProgressState extends BitUpgradeState {
}
}
export const EnslavedProgress = (function() {
const db = GameDatabase.celestials.enslaved.progress;
return {
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 EnslavedProgress = mapGameDataToObject(
GameDatabase.celestials.enslaved.progress,
config => new EnslavedProgressState(config)
);
export const Tesseracts = {
get bought() {

View File

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

View File

@ -1,6 +1,7 @@
import { CelestialQuotes } from "../quotes.js";
import { DC } from "../../constants.js";
import { DarkMatterDimensions } from "./dark-matter-dimension.js";
import { CelestialQuotes } from "../quotes";
import { DC } from "../../constants";
import { DarkMatterDimensions } from "./dark-matter-dimension";
export const Laitela = {
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";
class SingularityMilestoneState extends GameMechanicState {
@ -30,14 +31,18 @@ class SingularityMilestoneState extends GameMechanicState {
return Currency.singularities.gte(this.start);
}
get increaseThreshold() {
return this.config.increaseThreshold;
}
nerfCompletions(completions) {
const softcap = this.config.increaseThreshold;
const softcap = this.increaseThreshold;
if (!softcap || (completions < softcap)) return completions;
return softcap + (completions - softcap) / 3;
}
unnerfCompletions(completions) {
const softcap = this.config.increaseThreshold;
const softcap = this.increaseThreshold;
if (!softcap || (completions < softcap)) return completions;
return softcap + (completions - softcap) * 3;
}
@ -94,42 +99,13 @@ class SingularityMilestoneState extends GameMechanicState {
}
}
export const SingularityMilestone = (function() {
const db = GameDatabase.celestials.singularityMilestones;
return {
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 SingularityMilestone = mapGameDataToObject(
GameDatabase.celestials.singularityMilestones,
config => new SingularityMilestoneState(config)
);
export const SingularityMilestones = {
all: Object.values(SingularityMilestone),
all: SingularityMilestone.all,
lastNotified: player.celestials.laitela.lastCheckedMilestones,
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
const SingularityMilestoneThresholds = (function() {
return Object.values(GameDatabase.celestials.singularityMilestones)
return SingularityMilestones.all
.map(m => Array.range(0, Math.min(50, m.limit))
.filter(r => !m.increaseThreshold || r <= m.increaseThreshold ||
(r > m.increaseThreshold && ((r - m.increaseThreshold) % 3) === 2))

View File

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

View File

@ -1,9 +1,11 @@
import { DC } from "../../constants";
import { Currency } from "../../currency";
import { DC } from "../../constants";
import { RebuyableMechanicState } from "../../game-mechanics/rebuyable";
import { SetPurchasableMechanicState } from "../../utils";
import { CelestialQuotes } from "../quotes";
import zalgo from "./zalgo";
import { CelestialQuotes } from "../quotes.js";
const disabledMechanicUnlocks = {
achievements: () => ({}),
@ -116,7 +118,8 @@ export const Pelle = {
},
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() {
@ -453,15 +456,13 @@ export class PelleUpgradeState extends SetPurchasableMechanicState {
}
export const PelleUpgrade = (function() {
return mapGameDataToObject(
GameDatabase.celestials.pelle.upgrades,
config => (config.rebuyable
? new RebuyablePelleUpgradeState(config)
: new PelleUpgradeState(config)
)
);
}());
export const PelleUpgrade = mapGameDataToObject(
GameDatabase.celestials.pelle.upgrades,
config => (config.rebuyable
? new RebuyablePelleUpgradeState(config)
: new PelleUpgradeState(config)
)
);
PelleUpgrade.rebuyables = 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() {
return mapGameDataToObject(
GameDatabase.celestials.pelle.rifts,
config => new RiftState(config)
);
}());
export const PelleRifts = mapGameDataToObject(
GameDatabase.celestials.pelle.rifts,
config => new RiftState(config)
);
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() {
return mapGameDataToObject(
GameDatabase.celestials.pelle.strikes,
config => new PelleStrikeState(config)
);
}());
export const PelleStrikes = mapGameDataToObject(
GameDatabase.celestials.pelle.strikes,
config => new PelleStrikeState(config)
);

View File

@ -1,4 +1,4 @@
import { GameMechanicState } from "../../game-mechanics/index.js";
import { GameMechanicState } from "../../game-mechanics/index";
/**
* @abstract
@ -224,44 +224,16 @@ class AlchemyReaction {
}
}
export const AlchemyResource = (function() {
function createResource(resource) {
const config = GameDatabase.celestials.alchemy.resources[resource];
config.id = resource;
if (config.isBaseResource) {
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 AlchemyResource = mapGameDataToObject(
GameDatabase.celestials.alchemy.resources,
config => (config.isBaseResource
? new BasicAlchemyResourceState(config)
: new AdvancedAlchemyResourceState(config))
);
export const AlchemyResources = {
all: Object.values(AlchemyResource),
base: Object.values(AlchemyResource).filter(r => r.isBaseResource)
all: AlchemyResource.all,
base: AlchemyResource.all.filter(r => r.isBaseResource)
};
export const AlchemyReactions = (function() {
@ -269,7 +241,7 @@ export const AlchemyReactions = (function() {
function mapReagents(resource) {
return resource.config.reagents
.map(r => ({
resource: AlchemyResources.all[r.resource],
resource: AlchemyResources.all.find(x => x.id === r.resource),
cost: r.amount
}));
}

View File

@ -1,5 +1,5 @@
import { GameMechanicState, BitUpgradeState } from "../../game-mechanics/index.js";
import { CelestialQuotes } from "../quotes.js";
import { BitUpgradeState, GameMechanicState } from "../../game-mechanics/index";
import { CelestialQuotes } from "../quotes";
class RaUnlockState extends BitUpgradeState {
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.js";
import { CelestialQuotes } from "./quotes.js";
import { BitUpgradeState, RebuyableMechanicState } from "../game-mechanics/index";
import { GameDatabase } from "../secret-formula/game-database";
import { CelestialQuotes } from "./quotes";
export const Teresa = {
timePoured: 0,
@ -172,17 +173,10 @@ export const TeresaUnlocks = mapGameDataToObject(
config => new TeresaUnlockState(config)
);
export const PerkShopUpgrade = (function() {
const db = GameDatabase.celestials.perkShop;
return {
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),
};
}());
export const PerkShopUpgrade = mapGameDataToObject(
GameDatabase.celestials.perkShop,
config => new PerkShopUpgradeState(config)
);
EventHub.logic.on(GAME_EVENT.TAB_CHANGED, () => {
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.js";
import { DC } from "./constants";
import { GameMechanicState } from "./game-mechanics/index";
// 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

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 { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
/* eslint-disable no-console */
// Disabling no-console here seems
// reasonable, since these are the devtools after all
@ -92,17 +94,16 @@ dev.tripleEverything = function() {
};
dev.barrelRoll = function() {
document.body.style.animation = "barrelRoll 5s 1";
setTimeout(() => document.body.style.animation = "", 5000);
FullScreenAnimationHandler.display("a-barrel-roll", 5);
};
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 = "";
};
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 = "";
};
@ -165,7 +166,7 @@ dev.resetDilation = function() {
// when making a special glyph, so no max-params
// eslint-disable-next-line max-params
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;
const glyph = GlyphGenerator.randomGlyph({ actualLevel: level, rawLevel });
glyph.symbol = symbol;

View File

@ -1,20 +1,15 @@
import { SetPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index.js";
import { DC } from "./constants.js";
import { SpeedrunMilestones } from "./speedrun.js";
import { RebuyableMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index";
import { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
import { SpeedrunMilestones } from "./speedrun";
export function animateAndDilate() {
document.body.style.animation = "dilate 2s 1 linear";
setTimeout(() => {
document.body.style.animation = "";
}, 2000);
FullScreenAnimationHandler.display("a-dilate", 2);
setTimeout(startDilatedEternity, 1000);
}
export function animateAndUndilate() {
document.body.style.animation = "undilate 2s 1 linear";
setTimeout(() => {
document.body.style.animation = "";
}, 2000);
FullScreenAnimationHandler.display("a-undilate", 2);
setTimeout(() => {
eternity(false, false, { switchingDilation: true });
}, 1000);
@ -22,7 +17,7 @@ export function animateAndUndilate() {
export function startDilatedEternityRequest() {
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) {
// TODO Dilation modal
if (playAnimation) {
@ -227,26 +222,12 @@ class RebuyableDilationUpgradeState extends RebuyableMechanicState {
}
}
export const DilationUpgrade = (function() {
const db = GameDatabase.eternity.dilation;
return {
dtGain: new RebuyableDilationUpgradeState(db.dtGain),
galaxyThreshold: new RebuyableDilationUpgradeState(db.galaxyThreshold),
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 DilationUpgrade = mapGameDataToObject(
GameDatabase.eternity.dilation,
config => (config.rebuyable
? new RebuyableDilationUpgradeState(config)
: new DilationUpgradeState(config))
);
export const DilationUpgrades = {
rebuyable: [
@ -254,11 +235,5 @@ export const DilationUpgrades = {
DilationUpgrade.galaxyThreshold,
DilationUpgrade.tachyonGain,
],
fromId: (function() {
const upgradesById = [];
for (const upgrade of Object.values(DilationUpgrade)) {
upgradesById[upgrade.id] = upgrade;
}
return id => upgradesById[id];
}()),
fromId: id => DilationUpgrade.all.find(x => x.id === id)
};

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import { GameMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index.js";
import { DC } from "./constants.js";
import { GameMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index";
import { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
function giveEternityRewards(auto) {
player.records.bestEternity.time = Math.min(player.records.thisEternity.time, player.records.bestEternity.time);
@ -57,10 +58,7 @@ function giveEternityRewards(auto) {
}
export function eternityAnimation() {
document.body.style.animation = "eternify 3s 1";
setTimeout(() => {
document.body.style.animation = "";
}, 3000);
FullScreenAnimationHandler.display("a-eternify", 3);
}
export function eternityResetRequest() {
@ -89,7 +87,7 @@ export function eternity(force, auto, specialConditions = {}) {
initializeChallengeCompletions();
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
player.break = false;
}
@ -176,7 +174,7 @@ function applyRealityUpgradesAfterEternity() {
function askEternityConfirmation() {
if (player.options.confirmations.eternity) {
Modal.eternity.show();
} else if (player.options.animations.eternity && document.body.style.animation === "") {
} else if (player.options.animations.eternity && !FullScreenAnimationHandler.isDisplaying) {
eternityAnimation();
setTimeout(eternity, 2250);
} else {
@ -196,44 +194,12 @@ export class EternityMilestoneState {
return Currency.eternities.gte(this.config.eternities);
}
}
export const EternityMilestone = (function() {
const db = GameDatabase.eternity.milestones;
const infinityDims = Array.dimensionTiers
.map(tier => new EternityMilestoneState(db[`autobuyerID${tier}`]));
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}`]))
)
};
export const EternityMilestone = mapGameDataToObject(
GameDatabase.eternity.milestones,
config => (config.isBaseResource
? new EternityMilestoneState(config)
: new EternityMilestoneState(config))
);
class EternityUpgradeState extends SetPurchasableMechanicState {
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() {
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(),
};
}());
EternityUpgrade.epMult = new EPMultiplierState();

View File

@ -1,6 +1,6 @@
import { GameMechanicState } from "./game-mechanics/index.js";
import { DC } from "./constants.js";
import { DC } from "./constants";
import { deepmergeAll } from "@/utility/deepmerge";
import { GameMechanicState } from "./game-mechanics/index";
export function startEternityChallenge() {
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,90 +1,92 @@
export * from "./glyph-effects.js";
export * from "./player.js";
export * from "./glyph-effects";
export * from "./player";
export * from "./automator/automator-backend.js";
export * from "./performance-stats.js";
export * from "./currency.js";
export * from "./cache.js";
export * from "./intervals.js";
export * from "./keyboard.js";
export * from "./hotkeys.js";
export * from "./galaxy.js";
export * from "./away-progress.js";
export * from "./confirmations.js";
export * from "./automator/automator-backend";
export * from "./performance-stats";
export * from "./currency";
export * from "./cache";
export * from "./intervals";
export * from "./keyboard";
export * from "./hotkeys";
export * from "./galaxy";
export * from "./away-progress";
export * from "./confirmations";
export * from "./autobuyers/index.js";
export * from "./storage/index.js";
export * from "./autobuyers/index";
export * from "./storage/index";
export * from "./notations.js";
export * from "./tutorial.js";
export * from "./notations";
export * from "./tutorial";
export * from "./new-game.js";
export * from "./new-game";
export * from "./celestials/quotes.js";
export * from "./celestials/teresa.js";
export * from "./celestials/effarig.js";
export * from "./celestials/enslaved.js";
export * from "./celestials/V.js";
export * from "./celestials/ra/ra.js";
export * from "./celestials/ra/alchemy.js";
export * from "./celestials/laitela/laitela.js";
export * from "./celestials/laitela/dark-matter-dimension.js";
export * from "./celestials/laitela/singularity.js";
export * from "./celestials/pelle/pelle.js";
export * from "./celestials/pelle/strikes.js";
export * from "./celestials/pelle/rifts.js";
export * from "./celestials/pelle/galaxy-generator.js";
export * from "./celestials/pelle/game-end.js";
export * from "./celestials/celestials.js";
export * from "./celestials/quotes";
export * from "./celestials/teresa";
export * from "./celestials/effarig";
export * from "./celestials/enslaved";
export * from "./celestials/V";
export * from "./celestials/ra/ra";
export * from "./celestials/ra/alchemy";
export * from "./celestials/laitela/laitela";
export * from "./celestials/laitela/dark-matter-dimension";
export * from "./celestials/laitela/singularity";
export * from "./celestials/pelle/pelle";
export * from "./celestials/pelle/strikes";
export * from "./celestials/pelle/rifts";
export * from "./celestials/pelle/galaxy-generator";
export * from "./celestials/pelle/game-end";
export * from "./celestials/celestials";
export * from "./automator/index.js";
export * from "./automator/automator-points.js";
export * from "./automator/index";
export * from "./automator/automator-points";
export * from "./app/player-progress.js";
export * from "./app/modal.js";
export * from "./app/themes.js";
export * from "./app/options.js";
export * from "./app/ui.js";
export * from "./app/player-progress";
export * from "./app/modal";
export * from "./app/themes";
export * from "./app/options";
export * from "./app/ui";
export * from "./achievements/normal-achievement.js";
export * from "./achievements/secret-achievement.js";
export * from "./achievements/achievement-timer.js";
export * from "./achievements/normal-achievement";
export * from "./achievements/secret-achievement";
export * from "./achievements/achievement-timer";
export * from "./glyphs/glyph-core.js";
export * from "./glyphs/glyph-effects.js";
export * from "./glyphs/glyph-generator.js";
export * from "./glyphs/glyph-purge-handler.js";
export * from "./glyphs/auto-glyph-processor.js";
export * from "./glyphs/glyph-core";
export * from "./glyphs/glyph-effects";
export * from "./glyphs/glyph-generator";
export * from "./glyphs/glyph-purge-handler";
export * from "./glyphs/auto-glyph-processor";
export * from "./time.js";
export * from "./tickspeed.js";
export * from "./time";
export * from "./tickspeed";
export * from "./dimensions/antimatter-dimension.js";
export * from "./dimensions/infinity-dimension.js";
export * from "./dimensions/time-dimension.js";
export * from "./dimensions/antimatter-dimension";
export * from "./dimensions/infinity-dimension";
export * from "./dimensions/time-dimension";
export * from "./time-studies/index.js";
export * from "./time-studies/index";
export * from "./dimboost.js";
export * from "./sacrifice.js";
export * from "./big_crunch.js";
export * from "./challenge.js";
export * from "./eternity.js";
export * from "./eternity_challenge.js";
export * from "./reality.js";
export * from "./replicanti.js";
export * from "./time-theorems.js";
export * from "./reality-upgrades.js";
export * from "./imaginary-upgrades.js";
export * from "./perks.js";
export * from "./dilation.js";
export * from "./black_hole.js";
export * from "./machines.js";
export * from "./devtools.js";
export * from "./news-ticker.js";
export * from "./kong.js";
export * from "./ui/tabs.js";
export * from "./ui/tab-notifications.js";
export * from "./speedrun.js";
export * from "./dimboost";
export * from "./sacrifice";
export * from "./big_crunch";
export * from "./infinity-upgrades";
export * from "./break-infinity-upgrades";
export * from "./challenge";
export * from "./eternity";
export * from "./eternity_challenge";
export * from "./reality";
export * from "./replicanti";
export * from "./time-theorems";
export * from "./reality-upgrades";
export * from "./imaginary-upgrades";
export * from "./perks";
export * from "./dilation";
export * from "./black_hole";
export * from "./machines";
export * from "./devtools";
export * from "./news-ticker";
export * from "./kong";
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.js";
import { DC } from "./constants";
import { GameDatabase } from "./secret-formula/game-database";
// 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",
"dilationpow", "timeshardpow", "powermult", "powerdimboost", "powerbuy10",
@ -640,18 +640,10 @@ export const Glyphs = {
class GlyphSacrificeState extends GameMechanicState { }
export const GlyphSacrifice = (function() {
const db = GameDatabase.reality.glyphSacrifice;
return {
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 const GlyphSacrifice = mapGameDataToObject(
GameDatabase.reality.glyphSacrifice,
config => new GlyphSacrificeState(config)
);
export function recalculateAllGlyphs() {
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 { GameKeyboard } from "./keyboard";
// Add your hotkeys and combinations here
// GameKeyboard.bind for single press combinations
// GameKeyboard.bindRepeatable for repeatable combinations

View File

@ -1,5 +1,5 @@
import { BitPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index.js";
import { DC } from "./constants.js";
import { BitPurchasableMechanicState, RebuyableMechanicState } from "./game-mechanics/index";
import { DC } from "./constants";
class ImaginaryUpgradeState extends BitPurchasableMechanicState {
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
all() {
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() {
// 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 = {};
@ -60,17 +60,10 @@ class ShopPurchaseState extends RebuyableMechanicState {
}
}
export const ShopPurchase = (function() {
const db = GameDatabase.shopPurchases;
return {
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);
export const ShopPurchase = mapGameDataToObject(
GameDatabase.shopPurchases,
config => new ShopPurchaseState(config)
);
kong.purchaseTimeSkip = function(cost) {
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 = {
get baseRMCap() { return DC.E1000; },

View File

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

View File

@ -49,7 +49,7 @@ export const PerformanceStats = {
function render(rootBlock) {
indentLevel++;
for (const blockName in rootBlock) {
if (!rootBlock.hasOwnProperty(blockName)) continue;
if (!Object.prototype.hasOwnProperty.call(rootBlock, blockName)) continue;
const block = rootBlock[blockName];
const records = block.records;
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 {
constructor(config) {
@ -49,61 +49,13 @@ class PerkState extends SetPurchasableMechanicState {
}
}
export const Perk = (function() {
const db = GameDatabase.reality.perks;
return {
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 Perk = mapGameDataToObject(
GameDatabase.reality.perks,
config => new PerkState(config)
);
export const Perks = {
all: Object.values(Perk),
all: Perk.all,
/**
* @param {number} id
* @returns {PerkState}

View File

@ -1,7 +1,7 @@
import { GlyphTypes } from "./glyph-effects.js";
import { AUTOMATOR_MODE, AUTOMATOR_TYPE } from "./automator/automator-backend.js";
import { DC } from "./constants.js";
import { AUTOMATOR_MODE, AUTOMATOR_TYPE } from "./automator/automator-backend";
import { DC } from "./constants";
import { deepmergeAll } from "@/utility/deepmerge";
import { GlyphTypes } from "./glyph-effects";
// This is actually reassigned when importing saves
// eslint-disable-next-line prefer-const
@ -811,7 +811,8 @@ window.player = {
bigCrunch: true,
replicantiGalaxy: true,
antimatterGalaxy: true,
dimensionBoost: true
dimensionBoost: true,
switchAutomatorMode: true
},
awayProgress: {
antimatter: true,
@ -984,7 +985,7 @@ export function guardFromNaNValues(obj) {
}
for (const key in obj) {
if (!obj.hasOwnProperty(key)) continue;
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
// TODO: rework autobuyer saving
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 {
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
@ -180,8 +180,8 @@ function triggerManualReality(realityProps) {
export function runRealityAnimation() {
document.getElementById("ui").style.userSelect = "none";
document.getElementById("ui").style.animation = "realize 10s 1";
document.getElementById("realityanimbg").style.animation = "realizebg 10s 1";
document.getElementById("ui").style.animation = "a-realize 10s 1";
document.getElementById("realityanimbg").style.animation = "a-realizebg 10s 1";
document.getElementById("realityanimbg").style.display = "block";
setTimeout(() => {
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
// 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 {
// 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.js";
import { DC } from "../../constants";
import { GameDatabase } from "../game-database";
GameDatabase.achievements.normal = [
{
@ -702,7 +702,7 @@ GameDatabase.achievements.normal = [
id: 102,
name: "This mile took an eternity",
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
},
{
@ -1305,7 +1305,8 @@ GameDatabase.achievements.normal = [
id: 182,
name: "One more time",
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
},
{

View File

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

View File

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

View File

@ -1,443 +1,462 @@
import { GameDatabase } from "../game-database.js";
import { DC } from "../../constants.js";
import { DC } from "../../constants";
import { GameDatabase } from "../game-database";
GameDatabase.celestials.alchemy = {
resources: {
// T1 resources (Non-Effarig "base" resources)
[ALCHEMY_RESOURCE.POWER]: {
name: "Power",
symbol: "Ω",
isBaseResource: true,
effect: amount => 1 + amount / 200000,
tier: 1,
uiOrder: 1,
unlockedAt: 2,
description: "provides a multiplier to Antimatter Dimensions",
formatEffect: value => `Antimatter Dimension multipliers ${formatPow(value, 4, 4)}`
},
[ALCHEMY_RESOURCE.INFINITY]: {
name: "Infinity",
symbol: "∞",
isBaseResource: true,
effect: amount => 1 + amount / 200000,
tier: 1,
uiOrder: 2,
unlockedAt: 3,
description: "provides a multiplier to Infinity Dimensions",
formatEffect: value => `Infinity Dimension multipliers ${formatPow(value, 4, 4)}`
},
[ALCHEMY_RESOURCE.TIME]: {
name: "Time",
symbol: "Δ",
isBaseResource: true,
effect: amount => 1 + amount / 200000,
tier: 1,
uiOrder: 3,
unlockedAt: 4,
description: "provides a multiplier to Time Dimensions",
formatEffect: value => `Time Dimension multipliers ${formatPow(value, 4, 4)}`
},
[ALCHEMY_RESOURCE.REPLICATION]: {
name: "Replication",
symbol: "Ξ",
isBaseResource: true,
effect: amount => Decimal.pow10(amount / 1000),
tier: 1,
uiOrder: 4,
unlockedAt: 5,
description: `increases Replication Speed`,
formatEffect: value => `Replication speed is increased by ${formatX(value, 2, 2)}`
},
[ALCHEMY_RESOURCE.DILATION]: {
name: "Dilation",
symbol: "Ψ",
isBaseResource: true,
effect: amount => Decimal.pow10(amount / 2000),
tier: 1,
uiOrder: 5,
unlockedAt: 6,
description: "increases Dilated Time production",
formatEffect: value => `Dilated Time production is increased by ${formatX(value, 2, 2)}`
},
GameDatabase.celestials.alchemy.resources = {
// T1 resources (Non-Effarig "base" resources)
"power": {
id: ALCHEMY_RESOURCE.POWER,
name: "Power",
symbol: "Ω",
isBaseResource: true,
effect: amount => 1 + amount / 200000,
tier: 1,
uiOrder: 1,
unlockedAt: 2,
description: "provides a multiplier to Antimatter Dimensions",
formatEffect: value => `Antimatter Dimension multipliers ${formatPow(value, 4, 4)}`
},
"infinity": {
id: ALCHEMY_RESOURCE.INFINITY,
name: "Infinity",
symbol: "∞",
isBaseResource: true,
effect: amount => 1 + amount / 200000,
tier: 1,
uiOrder: 2,
unlockedAt: 3,
description: "provides a multiplier to Infinity Dimensions",
formatEffect: value => `Infinity Dimension multipliers ${formatPow(value, 4, 4)}`
},
"time": {
id: ALCHEMY_RESOURCE.TIME,
name: "Time",
symbol: "Δ",
isBaseResource: true,
effect: amount => 1 + amount / 200000,
tier: 1,
uiOrder: 3,
unlockedAt: 4,
description: "provides a multiplier to Time Dimensions",
formatEffect: value => `Time Dimension multipliers ${formatPow(value, 4, 4)}`
},
"replication": {
id: ALCHEMY_RESOURCE.REPLICATION,
name: "Replication",
symbol: "Ξ",
isBaseResource: true,
effect: amount => Decimal.pow10(amount / 1000),
tier: 1,
uiOrder: 4,
unlockedAt: 5,
description: `increases Replication Speed`,
formatEffect: value => `Replication speed is increased by ${formatX(value, 2, 2)}`
},
"dilation": {
id: ALCHEMY_RESOURCE.DILATION,
name: "Dilation",
symbol: "Ψ",
isBaseResource: true,
effect: amount => Decimal.pow10(amount / 2000),
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)
[ALCHEMY_RESOURCE.CARDINALITY]: {
name: "Cardinality",
symbol: "α",
isBaseResource: false,
effect: amount => 1 + 0.2 / (1 + amount / 20000),
tier: 2,
uiOrder: 3,
unlockedAt: 8,
get description() { return `reduces the slowdown per ${format(Number.MAX_VALUE, 2)} Replicanti`; },
formatEffect: value => `Replicanti interval increases slower ${formatX(1.2, 1, 1)}` +
`${formatX(value, 4, 4)} per ${format(Number.MAX_VALUE, 2)}`,
reagents: [
{
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)`;
// T2 resources (combinations of pairs of T1 resources)
"cardinality": {
id: ALCHEMY_RESOURCE.CARDINALITY,
name: "Cardinality",
symbol: "α",
isBaseResource: false,
effect: amount => 1 + 0.2 / (1 + amount / 20000),
tier: 2,
uiOrder: 3,
unlockedAt: 8,
get description() { return `reduces the slowdown per ${format(Number.MAX_VALUE, 2)} Replicanti`; },
formatEffect: value => `Replicanti interval increases slower ${formatX(1.2, 1, 1)}
${formatX(value, 4, 4)} per ${format(Number.MAX_VALUE, 2)}`,
reagents: [
{
resource: ALCHEMY_RESOURCE.TIME,
amount: 8
},
reagents: [
{
resource: ALCHEMY_RESOURCE.EFFARIG,
amount: 3
},
{
resource: ALCHEMY_RESOURCE.REPLICATION,
amount: 16
},
{
resource: ALCHEMY_RESOURCE.INFINITY,
amount: 14
}
]
},
[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
}
]
},
[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
}
]
},
{
resource: ALCHEMY_RESOURCE.REPLICATION,
amount: 7
}
]
},
"eternity": {
id: 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
}
]
},
"dimensionality": {
id: 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
}
]
},
"inflation": {
id: 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
}
]
},
"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)
[ALCHEMY_RESOURCE.EXPONENTIAL]: {
name: "Exponential",
symbol: "Γ",
isBaseResource: false,
effect: amount => 10 * Math.pow(amount / 10000, 2),
tier: 4,
uiOrder: 2,
unlockedAt: 18,
description: "multiplies Infinity Points by Replicanti",
formatEffect: value => `Infinity Points multiplied by Replicanti${formatPow(value, 2, 3)}`,
reagents: [
{
resource: ALCHEMY_RESOURCE.INFLATION,
amount: 18
},
{
resource: ALCHEMY_RESOURCE.SYNERGISM,
amount: 3
}
]
},
[ALCHEMY_RESOURCE.FORCE]: {
name: "Force",
symbol: "Φ",
isBaseResource: false,
effect: amount => 5 * amount,
tier: 4,
uiOrder: 2,
unlockedAt: 17,
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
}
]
// T3 resources (Effarig and conbinations of T1/T2 with Effarig)
"effarig": {
id: 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)}`
},
"synergism": {
id: 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.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)
[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
}
]
},
// T4 resources (resources which feed directly into the final resource)
"exponential": {
id: ALCHEMY_RESOURCE.EXPONENTIAL,
name: "Exponential",
symbol: "Γ",
isBaseResource: false,
effect: amount => 10 * Math.pow(amount / 10000, 2),
tier: 4,
uiOrder: 2,
unlockedAt: 18,
description: "multiplies Infinity Points by Replicanti",
formatEffect: value => `Infinity Points multiplied by Replicanti${formatPow(value, 2, 3)}`,
reagents: [
{
resource: ALCHEMY_RESOURCE.INFLATION,
amount: 18
},
{
resource: ALCHEMY_RESOURCE.SYNERGISM,
amount: 3
}
]
},
"force": {
id: ALCHEMY_RESOURCE.FORCE,
name: "Force",
symbol: "Φ",
isBaseResource: false,
effect: amount => 5 * amount,
tier: 4,
uiOrder: 2,
unlockedAt: 17,
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
}
]
},
"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.js";
import { DC } from "../../constants";
import { GameDatabase } from "../game-database";
GameDatabase.celestials.effarig = {
unlocks: {
adjuster: {
id: 0,
description: "Adjustable Glyph level factor weights",
cost: 1e7
},
glyphFilter: {
id: 1,
description: "Glyph Filtering",
cost: 2e8
},
setSaves: {
id: 2,
description: "Glyph Set Saves",
cost: 3e9
},
run: {
id: 3,
description: "Effarig's Reality",
cost: 5e11
},
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
GameDatabase.celestials.effarig.unlocks = {
adjuster: {
id: 0,
description: "Adjustable Glyph level factor weights",
cost: 1e7,
onPurchased: () => {
Effarig.quotes.show(Effarig.quotes.UNLOCK_WEIGHTS);
ui.view.tabs.reality.openGlyphWeights = true;
Tab.reality.glyphs.show();
}
},
glyphFilter: {
id: 1,
description: "Glyph Filtering",
cost: 2e8,
onPurchased: () => {
Effarig.quotes.show(Effarig.quotes.UNLOCK_GLYPH_FILTER);
player.reality.showSidebarPanel = GLYPH_SIDEBAR_MODE.FILTER_SETTINGS;
}
},
setSaves: {
id: 2,
description: "Glyph Set Saves",
cost: 3e9,
onPurchased: () => {
Effarig.quotes.show(Effarig.quotes.UNLOCK_SET_SAVES);
player.reality.showSidebarPanel = GLYPH_SIDEBAR_MODE.SAVED_SETS;
}
},
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
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`;
},
},
eternity: {
id: 5,
label: "Eternity",
get description() {
if (Pelle.isDoomed) return "Any rewards from Effarig's Eternity have been disabled.";
return ` Eternities generates Infinities
Infinity Points are no longer limited in any way in Effarig's Reality
You have unlocked The Enslaved Ones`;
},
},
eternity: {
id: 5,
label: "Eternity",
get description() {
if (Pelle.isDoomed) return "Any rewards from Effarig's Eternity have been disabled.";
return ` Eternities generates Infinities
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 = {
// Note that "condition" isn't displayed in-game. These are meant to be indicators here of
@ -60,7 +60,8 @@ GameDatabase.celestials.enslaved = {
glyphHints: [
"Infinity and Dilation Glyphs seem confined too tightly to be useful at all.",
"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. " +
"A Replication Glyph is very helpful, but it's not strictly necessary or quite as strong " +
"as Power and Time."]
`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
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 { 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
};
};
const rebuyable = config => {
const { id, description, cost, effect, formatEffect, currency, currencyLabel } = config;
return {
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"
}),
id,
description,
cost: () => cost(player.celestials.pelle.rebuyables[id]),
formatCost,
effect: (x = player.celestials.pelle.rebuyables[id]) => effect(x),
formatEffect,
currency,
currencyLabel
};
}());
};
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