mirror of
https://github.com/IvarK/AntimatterDimensionsSourceCode.git
synced 2024-09-20 11:01:45 +00:00
Merge branch 'master' into make-all-fixed-elements-into-one-container
This commit is contained in:
commit
74006d53d9
|
@ -45,9 +45,9 @@
|
|||
}
|
||||
],
|
||||
"keyframes-name-pattern": [
|
||||
"^([_a-z][a-z0-9]*)([-_]{1,2}[a-z0-9]+)*$",
|
||||
"^a-([-_]{0,2}[a-z0-9]+)*$",
|
||||
{
|
||||
"message": "Expected keyframe name to be kebab-case"
|
||||
"message": "Keyframe name must begin with `a-` and be kebab-case"
|
||||
}
|
||||
],
|
||||
"selector-id-pattern": [
|
||||
|
|
|
@ -57,36 +57,32 @@ 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 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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { sha512_256 } from "js-sha512";
|
||||
|
||||
import FullScreenAnimationHandler from "../full-screen-animation-handler";
|
||||
|
||||
export class GameOptions {
|
||||
|
@ -67,7 +68,7 @@ export function isSecretImport(data) {
|
|||
export function tryImportSecret(data) {
|
||||
const index = secretImportIndex(data);
|
||||
if (index === 0) {
|
||||
FullScreenAnimationHandler.display("barrelRoll", 5);
|
||||
FullScreenAnimationHandler.display("a-barrel-roll", 5);
|
||||
SecretAchievement(15).unlock();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -97,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}`);
|
||||
|
|
|
@ -28,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() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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>",
|
||||
},
|
||||
];
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import { GameMechanicState, RebuyableMechanicState, SetPurchasableMechanicState } from "./game-mechanics/index";
|
||||
import { DC } from "./constants";
|
||||
import FullScreenAnimationHandler from "./full-screen-animation-handler";
|
||||
import { SpeedrunMilestones } from "./speedrun";
|
||||
|
||||
export function bigCrunchAnimation() {
|
||||
FullScreenAnimationHandler.display("implode", 2);
|
||||
FullScreenAnimationHandler.display("a-implode", 2);
|
||||
}
|
||||
|
||||
function handleChallengeCompletion() {
|
||||
|
@ -150,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;
|
||||
|
|
48
javascripts/core/break-infinity-upgrades.js
Normal file
48
javascripts/core/break-infinity-upgrades.js
Normal 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))
|
||||
);
|
|
@ -178,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);
|
||||
|
|
|
@ -266,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() {
|
||||
|
|
|
@ -31,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;
|
||||
}
|
||||
|
@ -95,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() {
|
||||
|
@ -228,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))
|
||||
|
|
|
@ -115,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)
|
||||
);
|
||||
|
|
|
@ -118,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() {
|
||||
|
@ -455,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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -173,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);
|
||||
|
|
|
@ -94,16 +94,16 @@ dev.tripleEverything = function() {
|
|||
};
|
||||
|
||||
dev.barrelRoll = function() {
|
||||
FullScreenAnimationHandler.display("barrelRoll", 5);
|
||||
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 = "";
|
||||
};
|
||||
|
||||
|
@ -166,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;
|
||||
|
|
|
@ -4,12 +4,12 @@ import FullScreenAnimationHandler from "./full-screen-animation-handler";
|
|||
import { SpeedrunMilestones } from "./speedrun";
|
||||
|
||||
export function animateAndDilate() {
|
||||
FullScreenAnimationHandler.display("dilate", 2);
|
||||
FullScreenAnimationHandler.display("a-dilate", 2);
|
||||
setTimeout(startDilatedEternity, 1000);
|
||||
}
|
||||
|
||||
export function animateAndUndilate() {
|
||||
FullScreenAnimationHandler.display("undilate", 2);
|
||||
FullScreenAnimationHandler.display("a-undilate", 2);
|
||||
setTimeout(() => {
|
||||
eternity(false, false, { switchingDilation: true });
|
||||
}, 1000);
|
||||
|
@ -222,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: [
|
||||
|
@ -249,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)
|
||||
};
|
||||
|
|
|
@ -58,7 +58,7 @@ function giveEternityRewards(auto) {
|
|||
}
|
||||
|
||||
export function eternityAnimation() {
|
||||
FullScreenAnimationHandler.display("eternify", 3);
|
||||
FullScreenAnimationHandler.display("a-eternify", 3);
|
||||
}
|
||||
|
||||
export function eternityResetRequest() {
|
||||
|
@ -87,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;
|
||||
}
|
||||
|
@ -194,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() {
|
||||
|
@ -319,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();
|
||||
|
|
|
@ -68,6 +68,8 @@ export * from "./time-studies/index";
|
|||
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";
|
||||
|
|
|
@ -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++) {
|
||||
|
|
213
javascripts/core/infinity-upgrades.js
Normal file
213
javascripts/core/infinity-upgrades.js
Normal 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))
|
||||
);
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,443 +1,462 @@
|
|||
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
|
||||
}
|
||||
]
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,56 +1,70 @@
|
|||
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)";
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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.`
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,66 +1,65 @@
|
|||
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"
|
||||
}),
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,190 +1,189 @@
|
|||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.celestials.pelle.upgrades = (function() {
|
||||
const formatCost = c => format(c, 2);
|
||||
// eslint-disable-next-line max-params
|
||||
const expWithIncreasedScale = (base1, base2, incScale, coeff, x) =>
|
||||
Decimal.pow(base1, x).times(Decimal.pow(base2, x - incScale).max(1)).times(coeff);
|
||||
const formatCost = c => format(c, 2);
|
||||
// eslint-disable-next-line max-params
|
||||
const expWithIncreasedScale = (base1, base2, incScale, coeff, x) =>
|
||||
Decimal.pow(base1, x).times(Decimal.pow(base2, x - incScale).max(1)).times(coeff);
|
||||
|
||||
const rebuyable = config => {
|
||||
const { id, description, cost, effect, formatEffect, cap } = config;
|
||||
return {
|
||||
id,
|
||||
description,
|
||||
cost: () => expWithIncreasedScale(...cost, player.celestials.pelle.rebuyables[id]),
|
||||
formatCost,
|
||||
cap,
|
||||
effect: (x = player.celestials.pelle.rebuyables[id]) => effect(x),
|
||||
formatEffect,
|
||||
rebuyable: true
|
||||
};
|
||||
};
|
||||
const rebuyable = config => {
|
||||
const { id, description, cost, effect, formatEffect, cap } = config;
|
||||
return {
|
||||
antimatterDimensionMult: rebuyable({
|
||||
id: "antimatterDimensionMult",
|
||||
description: "Gain a multiplier to Antimatter Dimensions",
|
||||
cost: [10, 1e3, 41, 100],
|
||||
effect: x => Pelle.antimatterDimensionMult(x),
|
||||
formatEffect: x => formatX(x, 2, 2),
|
||||
cap: 44
|
||||
}),
|
||||
timeSpeedMult: rebuyable({
|
||||
id: "timeSpeedMult",
|
||||
description: "Gain a multiplier to game speed",
|
||||
cost: [20, 1e3, 30, 1e5],
|
||||
effect: x => Decimal.pow(1.3, x),
|
||||
formatEffect: x => formatX(x, 2, 2),
|
||||
cap: 35
|
||||
}),
|
||||
glyphLevels: rebuyable({
|
||||
id: "glyphLevels",
|
||||
description: "Increase the Glyph level allowed in Pelle",
|
||||
cost: [30, 1e3, 25, 1e15],
|
||||
effect: x => Math.floor(((3 * (x + 1)) - 2) ** 1.6),
|
||||
formatEffect: x => formatInt(x),
|
||||
cap: 26
|
||||
}),
|
||||
infConversion: rebuyable({
|
||||
id: "infConversion",
|
||||
description: "Increase Infinity Power conversion rate",
|
||||
cost: [40, 1e3, 20, 1e18],
|
||||
effect: x => (x * 3.5) ** 0.37,
|
||||
formatEffect: x => `+${format(x, 2, 2)}`,
|
||||
cap: 21
|
||||
}),
|
||||
galaxyPower: rebuyable({
|
||||
id: "galaxyPower",
|
||||
description: "Multiply Galaxy power",
|
||||
cost: [1000, 1e3, 10, 1e30],
|
||||
effect: x => 1 + x / 50,
|
||||
formatEffect: x => formatX(x, 2, 2),
|
||||
cap: 9
|
||||
}),
|
||||
antimatterDimAutobuyers1: {
|
||||
id: 0,
|
||||
description: "Gain back Autobuyers for Antimatter Dimensions 1-4",
|
||||
cost: 1e5,
|
||||
formatCost,
|
||||
},
|
||||
dimBoostAutobuyer: {
|
||||
id: 1,
|
||||
description: "Gain back the Autobuyer for Dimension Boosts",
|
||||
cost: 5e5,
|
||||
formatCost,
|
||||
},
|
||||
keepAutobuyers: {
|
||||
id: 2,
|
||||
description: "Keep your Autobuyer upgrades on Armageddon",
|
||||
cost: 5e6,
|
||||
formatCost,
|
||||
},
|
||||
antimatterDimAutobuyers2: {
|
||||
id: 3,
|
||||
description: "Gain back Autobuyers for Antimatter Dimensions 5-8",
|
||||
cost: 2.5e7,
|
||||
formatCost,
|
||||
},
|
||||
galaxyAutobuyer: {
|
||||
id: 4,
|
||||
description: "Gain back the Autobuyer for Antimatter Galaxies",
|
||||
cost: 1e8,
|
||||
formatCost,
|
||||
},
|
||||
tickspeedAutobuyer: {
|
||||
id: 5,
|
||||
description: "Gain back the Autobuyer for Tickspeed",
|
||||
cost: 1e9,
|
||||
formatCost,
|
||||
},
|
||||
keepInfinityUpgrades: {
|
||||
id: 6,
|
||||
description: "Keep Infinity Upgrades on Armageddon",
|
||||
cost: 1e10,
|
||||
formatCost,
|
||||
},
|
||||
keepBreakInfinityUpgrades: {
|
||||
id: 7,
|
||||
description: "Keep Break Infinity Upgrades on Armageddon",
|
||||
cost: 1e12,
|
||||
formatCost,
|
||||
},
|
||||
IDAutobuyers: {
|
||||
id: 8,
|
||||
description: "Gain back Infinity Dimension Autobuyers",
|
||||
cost: 1e14,
|
||||
formatCost,
|
||||
},
|
||||
keepInfinityChallenges: {
|
||||
id: 9,
|
||||
description: "You keep your Infinity Challenge unlocks and completions through Armageddons",
|
||||
cost: 1e15,
|
||||
formatCost,
|
||||
},
|
||||
replicantiAutobuyers: {
|
||||
id: 10,
|
||||
description: "Gain back Replicanti Upgrade Autobuyers",
|
||||
cost: 1e17,
|
||||
formatCost,
|
||||
},
|
||||
replicantiGalaxyNoReset: {
|
||||
id: 11,
|
||||
description: "Replicanti Galaxies don't reset on Infinity",
|
||||
cost: 1e19,
|
||||
formatCost,
|
||||
},
|
||||
eternitiesNoReset: {
|
||||
id: 12,
|
||||
description: "Eternities do not reset on Armageddon",
|
||||
cost: 1e20,
|
||||
formatCost,
|
||||
},
|
||||
timeStudiesNoReset: {
|
||||
id: 13,
|
||||
description: "Time Studies and Theorems do not reset on Armageddon",
|
||||
cost: 1e21,
|
||||
formatCost,
|
||||
},
|
||||
replicantiStayUnlocked: {
|
||||
id: 14,
|
||||
description: "Replicanti stays unlocked on Armageddon",
|
||||
cost: 1e22,
|
||||
formatCost,
|
||||
},
|
||||
keepEternityUpgrades: {
|
||||
id: 15,
|
||||
description: "Keep Eternity Upgrades on Armageddon",
|
||||
cost: 1e24,
|
||||
formatCost,
|
||||
},
|
||||
TDAutobuyers: {
|
||||
id: 16,
|
||||
description: "Gain back Time Dimension Autobuyers",
|
||||
cost: 1e25,
|
||||
formatCost,
|
||||
},
|
||||
keepEternityChallenges: {
|
||||
id: 17,
|
||||
description: "You keep your Eternity Challenge completions through Armageddons",
|
||||
cost: 1e26,
|
||||
formatCost,
|
||||
},
|
||||
dimBoostResetsNothing: {
|
||||
id: 18,
|
||||
description: "Dimension Boosts no longer reset anything",
|
||||
cost: 1e30,
|
||||
formatCost,
|
||||
},
|
||||
dilationUpgradesNoReset: {
|
||||
id: 19,
|
||||
description: "Keep Dilation Upgrades on Armageddon",
|
||||
cost: 1e45,
|
||||
formatCost,
|
||||
},
|
||||
tachyonParticlesNoReset: {
|
||||
id: 20,
|
||||
description: "Keep Tachyon Particles on Armageddon",
|
||||
cost: 1e50,
|
||||
formatCost,
|
||||
}
|
||||
id,
|
||||
description,
|
||||
cost: () => expWithIncreasedScale(...cost, player.celestials.pelle.rebuyables[id]),
|
||||
formatCost,
|
||||
cap,
|
||||
effect: (x = player.celestials.pelle.rebuyables[id]) => effect(x),
|
||||
formatEffect,
|
||||
rebuyable: true
|
||||
};
|
||||
}());
|
||||
};
|
||||
|
||||
GameDatabase.celestials.pelle.upgrades = {
|
||||
antimatterDimensionMult: rebuyable({
|
||||
id: "antimatterDimensionMult",
|
||||
description: "Gain a multiplier to Antimatter Dimensions",
|
||||
cost: [10, 1e3, 41, 100],
|
||||
effect: x => Pelle.antimatterDimensionMult(x),
|
||||
formatEffect: x => formatX(x, 2, 2),
|
||||
cap: 44
|
||||
}),
|
||||
timeSpeedMult: rebuyable({
|
||||
id: "timeSpeedMult",
|
||||
description: "Gain a multiplier to game speed",
|
||||
cost: [20, 1e3, 30, 1e5],
|
||||
effect: x => Decimal.pow(1.3, x),
|
||||
formatEffect: x => formatX(x, 2, 2),
|
||||
cap: 35
|
||||
}),
|
||||
glyphLevels: rebuyable({
|
||||
id: "glyphLevels",
|
||||
description: "Increase the Glyph level allowed in Pelle",
|
||||
cost: [30, 1e3, 25, 1e15],
|
||||
effect: x => Math.floor(((3 * (x + 1)) - 2) ** 1.6),
|
||||
formatEffect: x => formatInt(x),
|
||||
cap: 26
|
||||
}),
|
||||
infConversion: rebuyable({
|
||||
id: "infConversion",
|
||||
description: "Increase Infinity Power conversion rate",
|
||||
cost: [40, 1e3, 20, 1e18],
|
||||
effect: x => (x * 3.5) ** 0.37,
|
||||
formatEffect: x => `+${format(x, 2, 2)}`,
|
||||
cap: 21
|
||||
}),
|
||||
galaxyPower: rebuyable({
|
||||
id: "galaxyPower",
|
||||
description: "Multiply Galaxy power",
|
||||
cost: [1000, 1e3, 10, 1e30],
|
||||
effect: x => 1 + x / 50,
|
||||
formatEffect: x => formatX(x, 2, 2),
|
||||
cap: 9
|
||||
}),
|
||||
antimatterDimAutobuyers1: {
|
||||
id: 0,
|
||||
description: "Gain back Autobuyers for Antimatter Dimensions 1-4",
|
||||
cost: 1e5,
|
||||
formatCost,
|
||||
},
|
||||
dimBoostAutobuyer: {
|
||||
id: 1,
|
||||
description: "Gain back the Autobuyer for Dimension Boosts",
|
||||
cost: 5e5,
|
||||
formatCost,
|
||||
},
|
||||
keepAutobuyers: {
|
||||
id: 2,
|
||||
description: "Keep your Autobuyer upgrades on Armageddon",
|
||||
cost: 5e6,
|
||||
formatCost,
|
||||
},
|
||||
antimatterDimAutobuyers2: {
|
||||
id: 3,
|
||||
description: "Gain back Autobuyers for Antimatter Dimensions 5-8",
|
||||
cost: 2.5e7,
|
||||
formatCost,
|
||||
},
|
||||
galaxyAutobuyer: {
|
||||
id: 4,
|
||||
description: "Gain back the Autobuyer for Antimatter Galaxies",
|
||||
cost: 1e8,
|
||||
formatCost,
|
||||
},
|
||||
tickspeedAutobuyer: {
|
||||
id: 5,
|
||||
description: "Gain back the Autobuyer for Tickspeed",
|
||||
cost: 1e9,
|
||||
formatCost,
|
||||
},
|
||||
keepInfinityUpgrades: {
|
||||
id: 6,
|
||||
description: "Keep Infinity Upgrades on Armageddon",
|
||||
cost: 1e10,
|
||||
formatCost,
|
||||
},
|
||||
keepBreakInfinityUpgrades: {
|
||||
id: 7,
|
||||
description: "Keep Break Infinity Upgrades on Armageddon",
|
||||
cost: 1e12,
|
||||
formatCost,
|
||||
},
|
||||
IDAutobuyers: {
|
||||
id: 8,
|
||||
description: "Gain back Infinity Dimension Autobuyers",
|
||||
cost: 1e14,
|
||||
formatCost,
|
||||
},
|
||||
keepInfinityChallenges: {
|
||||
id: 9,
|
||||
description: "You keep your Infinity Challenge unlocks and completions through Armageddons",
|
||||
cost: 1e15,
|
||||
formatCost,
|
||||
},
|
||||
replicantiAutobuyers: {
|
||||
id: 10,
|
||||
description: "Gain back Replicanti Upgrade Autobuyers",
|
||||
cost: 1e17,
|
||||
formatCost,
|
||||
},
|
||||
replicantiGalaxyNoReset: {
|
||||
id: 11,
|
||||
description: "Replicanti Galaxies don't reset on Infinity",
|
||||
cost: 1e19,
|
||||
formatCost,
|
||||
},
|
||||
eternitiesNoReset: {
|
||||
id: 12,
|
||||
description: "Eternities do not reset on Armageddon",
|
||||
cost: 1e20,
|
||||
formatCost,
|
||||
},
|
||||
timeStudiesNoReset: {
|
||||
id: 13,
|
||||
description: "Time Studies and Theorems do not reset on Armageddon",
|
||||
cost: 1e21,
|
||||
formatCost,
|
||||
},
|
||||
replicantiStayUnlocked: {
|
||||
id: 14,
|
||||
description: "Replicanti stays unlocked on Armageddon",
|
||||
cost: 1e22,
|
||||
formatCost,
|
||||
},
|
||||
keepEternityUpgrades: {
|
||||
id: 15,
|
||||
description: "Keep Eternity Upgrades on Armageddon",
|
||||
cost: 1e24,
|
||||
formatCost,
|
||||
},
|
||||
TDAutobuyers: {
|
||||
id: 16,
|
||||
description: "Gain back Time Dimension Autobuyers",
|
||||
cost: 1e25,
|
||||
formatCost,
|
||||
},
|
||||
keepEternityChallenges: {
|
||||
id: 17,
|
||||
description: "You keep your Eternity Challenge completions through Armageddons",
|
||||
cost: 1e26,
|
||||
formatCost,
|
||||
},
|
||||
dimBoostResetsNothing: {
|
||||
id: 18,
|
||||
description: "Dimension Boosts no longer reset anything",
|
||||
cost: 1e30,
|
||||
formatCost,
|
||||
},
|
||||
dilationUpgradesNoReset: {
|
||||
id: 19,
|
||||
description: "Keep Dilation Upgrades on Armageddon",
|
||||
cost: 1e45,
|
||||
formatCost,
|
||||
},
|
||||
tachyonParticlesNoReset: {
|
||||
id: 20,
|
||||
description: "Keep Tachyon Particles on Armageddon",
|
||||
cost: 1e50,
|
||||
formatCost,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,87 +1,87 @@
|
|||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.celestials.perkShop = (function() {
|
||||
function rebuyableCost(initialCost, increment, id) {
|
||||
return initialCost * Math.pow(increment, player.celestials.teresa.perkShop[id]);
|
||||
}
|
||||
function rebuyable(config) {
|
||||
return {
|
||||
id: config.id,
|
||||
cost: () => (config.cost ? config.cost() : rebuyableCost(config.initialCost, config.increment, config.id)),
|
||||
otherReq: config.otherReq,
|
||||
cap: config.cap,
|
||||
costCap: config.costCap,
|
||||
description: config.description,
|
||||
effect: () => config.effect(player.celestials.teresa.perkShop[config.id]),
|
||||
formatEffect: config.formatEffect,
|
||||
formatCost: config.formatCost,
|
||||
rebuyable: true
|
||||
};
|
||||
}
|
||||
function rebuyableCost(initialCost, increment, id) {
|
||||
return initialCost * Math.pow(increment, player.celestials.teresa.perkShop[id]);
|
||||
}
|
||||
function rebuyable(config) {
|
||||
const { id, otherReq, cap, costCap, description, formatEffect, formatCost } = config;
|
||||
return {
|
||||
glyphLevel: rebuyable({
|
||||
id: 0,
|
||||
initialCost: 1,
|
||||
increment: 2,
|
||||
description: () => `Increase Glyph levels by ${formatPercents(0.05)}`,
|
||||
effect: bought => Math.pow(1.05, bought),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1048576 : 2048),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? Math.pow(1.05, 20) : Math.pow(1.05, 11))
|
||||
}),
|
||||
rmMult: rebuyable({
|
||||
id: 1,
|
||||
initialCost: 1,
|
||||
increment: 2,
|
||||
description: "Double Reality Machine gain",
|
||||
effect: bought => Math.pow(2, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1048576 : 2048),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1048576 : 2048)
|
||||
}),
|
||||
bulkDilation: rebuyable({
|
||||
id: 2,
|
||||
initialCost: 100,
|
||||
increment: 2,
|
||||
description: "Buy twice as many Dilation Upgrades at once.",
|
||||
effect: bought => Math.pow(2, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1638400 : 1600),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 16384 : 16),
|
||||
}),
|
||||
autoSpeed: rebuyable({
|
||||
id: 3,
|
||||
initialCost: 1000,
|
||||
increment: 2,
|
||||
description: () => `Infinity Dimension, Time Dimension, Dilation,
|
||||
and Replicanti autobuyers are ${formatX(2)} faster.`,
|
||||
effect: bought => Math.pow(2, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 64000 : 4000),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 64 : 4)
|
||||
}),
|
||||
musicGlyph: rebuyable({
|
||||
id: 4,
|
||||
description: () => `Receive a Music Glyph of a random type that is ${formatPercents(0.8)} of your highest level.
|
||||
(Try clicking it!)`,
|
||||
cost: () => 1,
|
||||
formatCost: value => formatInt(value),
|
||||
costCap: () => Number.MAX_VALUE,
|
||||
cap: () => Number.MAX_VALUE
|
||||
}),
|
||||
// Only appears with the perk shop increase upgrade
|
||||
fillMusicGlyph: rebuyable({
|
||||
id: 5,
|
||||
description: () => `Fill all empty slots in your inventory with Music Glyphs`,
|
||||
cost: () => Math.clampMin(Glyphs.freeInventorySpace, 1),
|
||||
otherReq: () => Glyphs.freeInventorySpace > 0,
|
||||
formatCost: value => formatInt(value),
|
||||
costCap: () => Number.MAX_VALUE,
|
||||
cap: () => Number.MAX_VALUE
|
||||
}),
|
||||
id,
|
||||
cost: () => (config.cost ? config.cost() : rebuyableCost(config.initialCost, config.increment, config.id)),
|
||||
otherReq,
|
||||
cap,
|
||||
costCap,
|
||||
description,
|
||||
effect: () => config.effect(player.celestials.teresa.perkShop[config.id]),
|
||||
formatEffect,
|
||||
formatCost,
|
||||
rebuyable: true
|
||||
};
|
||||
}());
|
||||
}
|
||||
|
||||
GameDatabase.celestials.perkShop = {
|
||||
glyphLevel: rebuyable({
|
||||
id: 0,
|
||||
initialCost: 1,
|
||||
increment: 2,
|
||||
description: () => `Increase Glyph levels by ${formatPercents(0.05)}`,
|
||||
effect: bought => Math.pow(1.05, bought),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1048576 : 2048),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? Math.pow(1.05, 20) : Math.pow(1.05, 11))
|
||||
}),
|
||||
rmMult: rebuyable({
|
||||
id: 1,
|
||||
initialCost: 1,
|
||||
increment: 2,
|
||||
description: "Double Reality Machine gain",
|
||||
effect: bought => Math.pow(2, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1048576 : 2048),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1048576 : 2048)
|
||||
}),
|
||||
bulkDilation: rebuyable({
|
||||
id: 2,
|
||||
initialCost: 100,
|
||||
increment: 2,
|
||||
description: "Buy twice as many Dilation Upgrades at once.",
|
||||
effect: bought => Math.pow(2, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 1638400 : 1600),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 16384 : 16),
|
||||
}),
|
||||
autoSpeed: rebuyable({
|
||||
id: 3,
|
||||
initialCost: 1000,
|
||||
increment: 2,
|
||||
description: () => `Infinity Dimension, Time Dimension, Dilation,
|
||||
and Replicanti autobuyers are ${formatX(2)} faster.`,
|
||||
effect: bought => Math.pow(2, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
costCap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 64000 : 4000),
|
||||
cap: () => (Ra.unlocks.perkShopIncrease.canBeApplied ? 64 : 4)
|
||||
}),
|
||||
musicGlyph: rebuyable({
|
||||
id: 4,
|
||||
description: () => `Receive a Music Glyph of a random type that is ${formatPercents(0.8)} of your highest level.
|
||||
(Try clicking it!)`,
|
||||
cost: () => 1,
|
||||
formatCost: value => formatInt(value),
|
||||
costCap: () => Number.MAX_VALUE,
|
||||
cap: () => Number.MAX_VALUE
|
||||
}),
|
||||
// Only appears with the perk shop increase upgrade
|
||||
fillMusicGlyph: rebuyable({
|
||||
id: 5,
|
||||
description: () => `Fill all empty slots in your inventory with Music Glyphs`,
|
||||
cost: () => Math.clampMin(Glyphs.freeInventorySpace, 1),
|
||||
otherReq: () => Glyphs.freeInventorySpace > 0,
|
||||
formatCost: value => formatInt(value),
|
||||
costCap: () => Number.MAX_VALUE,
|
||||
cap: () => Number.MAX_VALUE
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -57,6 +57,10 @@ GameDatabase.confirmationTypes = [
|
|||
name: "Glyph Undo",
|
||||
option: "glyphUndo",
|
||||
isUnlocked: () => TeresaUnlocks.undo.canBeApplied,
|
||||
}, {
|
||||
name: "Switch Automator Editor",
|
||||
option: "switchAutomatorMode",
|
||||
isUnlocked: () => Player.automatorUnlocked,
|
||||
}, {
|
||||
name: "Reset Celestial",
|
||||
option: "resetCelestial",
|
||||
|
|
|
@ -1,190 +1,189 @@
|
|||
import { DC } from "../../constants";
|
||||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.eternity.dilation = (function() {
|
||||
function rebuyableCost(initialCost, increment, id) {
|
||||
return Decimal.multiply(initialCost, Decimal.pow(increment, player.dilation.rebuyables[id]));
|
||||
}
|
||||
function rebuyable(config) {
|
||||
return {
|
||||
id: config.id,
|
||||
cost: () => rebuyableCost(config.initialCost, config.increment, config.id),
|
||||
initialCost: config.initialCost,
|
||||
increment: config.increment,
|
||||
description: config.description,
|
||||
effect: () => config.effect(player.dilation.rebuyables[config.id]),
|
||||
formatEffect: config.formatEffect,
|
||||
formatCost: config.formatCost,
|
||||
purchaseCap: config.purchaseCap,
|
||||
reachedCap: () => player.dilation.rebuyables[config.id] >= config.purchaseCap,
|
||||
pelleOnly: Boolean(config.pelleOnly),
|
||||
rebuyable: true
|
||||
};
|
||||
}
|
||||
function rebuyableCost(initialCost, increment, id) {
|
||||
return Decimal.multiply(initialCost, Decimal.pow(increment, player.dilation.rebuyables[id]));
|
||||
}
|
||||
function rebuyable(config) {
|
||||
return {
|
||||
dtGain: rebuyable({
|
||||
id: 1,
|
||||
initialCost: 1e5,
|
||||
increment: 10,
|
||||
description: () =>
|
||||
(SingularityMilestone.dilatedTimeFromSingularities.isUnlocked
|
||||
? `${formatX(2 * SingularityMilestone.dilatedTimeFromSingularities.effectValue, 2, 2)} Dilated Time gain`
|
||||
: "Double Dilated Time gain"),
|
||||
effect: bought => {
|
||||
const base = SingularityMilestone.dilatedTimeFromSingularities.isUnlocked
|
||||
? 2 * SingularityMilestone.dilatedTimeFromSingularities.effectValue
|
||||
: 2;
|
||||
return Decimal.pow(base, bought);
|
||||
},
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
galaxyThreshold: rebuyable({
|
||||
id: 2,
|
||||
initialCost: 1e6,
|
||||
increment: 100,
|
||||
description: () =>
|
||||
(Perk.bypassTGReset.isBought
|
||||
? "Reset Tachyon Galaxies, but lower their threshold"
|
||||
: "Reset Dilated Time and Tachyon Galaxies, but lower their threshold"),
|
||||
// The 38th purchase is at 1e80, and is the last purchase.
|
||||
effect: bought => (bought < 38 ? Math.pow(0.8, bought) : 0),
|
||||
formatEffect: effect => {
|
||||
if (effect === 0) return `${formatX(getTachyonGalaxyMult(effect), 4, 4)}`;
|
||||
const nextEffect = effect === Math.pow(0.8, 37) ? 0 : 0.8 * effect;
|
||||
return `${formatX(getTachyonGalaxyMult(effect), 4, 4)} ➜
|
||||
Next: ${formatX(getTachyonGalaxyMult(nextEffect), 4, 4)}`;
|
||||
},
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: 38
|
||||
}),
|
||||
tachyonGain: rebuyable({
|
||||
id: 3,
|
||||
initialCost: 1e7,
|
||||
increment: 20,
|
||||
description: () => {
|
||||
if (Pelle.isDoomed) return `Multiply the amount of Tachyon Particles gained by ${formatInt(1)}`;
|
||||
if (Enslaved.isRunning) return `Multiply the amount of Tachyon Particles gained
|
||||
by ${Math.pow(3, Enslaved.tachyonNerf).toFixed(2)}`;
|
||||
return "Triple the amount of Tachyon Particles gained";
|
||||
},
|
||||
effect: bought => {
|
||||
if (Pelle.isDoomed) return DC.D1.pow(bought);
|
||||
return DC.D3.pow(bought);
|
||||
},
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
doubleGalaxies: {
|
||||
id: 4,
|
||||
cost: 5e6,
|
||||
description: () => `Gain twice as many Tachyon Galaxies, up to ${formatInt(1000)}`,
|
||||
effect: 2
|
||||
},
|
||||
tdMultReplicanti: {
|
||||
id: 5,
|
||||
cost: 1e9,
|
||||
description: () => {
|
||||
const rep10 = replicantiMult().pLog10();
|
||||
let multiplier = "0.1";
|
||||
if (rep10 > 9000) {
|
||||
const ratio = DilationUpgrade.tdMultReplicanti.effectValue.pLog10() / rep10;
|
||||
if (ratio < 0.095) {
|
||||
multiplier = ratio.toFixed(2);
|
||||
}
|
||||
}
|
||||
return `Time Dimensions are affected by Replicanti multiplier ${formatPow(multiplier, 1, 3)}, reduced
|
||||
effect above ${formatX(DC.E9000)}`;
|
||||
},
|
||||
effect: () => {
|
||||
let rep10 = replicantiMult().pLog10() * 0.1;
|
||||
rep10 = rep10 > 9000 ? 9000 + 0.5 * (rep10 - 9000) : rep10;
|
||||
return Decimal.pow10(rep10);
|
||||
},
|
||||
formatEffect: value => formatX(value, 2, 1)
|
||||
},
|
||||
ndMultDT: {
|
||||
id: 6,
|
||||
cost: 5e7,
|
||||
description: "Antimatter Dimension multiplier based on Dilated Time, unaffected by Time Dilation",
|
||||
effect: () => Currency.dilatedTime.value.pow(308).clampMin(1),
|
||||
formatEffect: value => formatX(value, 2, 1)
|
||||
},
|
||||
ipMultDT: {
|
||||
id: 7,
|
||||
cost: 2e12,
|
||||
description: "Gain a multiplier to Infinity Points based on Dilated Time",
|
||||
effect: () => Currency.dilatedTime.value.pow(1000).clampMin(1),
|
||||
formatEffect: value => formatX(value, 2, 1),
|
||||
cap: () => Effarig.eternityCap
|
||||
},
|
||||
timeStudySplit: {
|
||||
id: 8,
|
||||
cost: 1e10,
|
||||
description: "You can buy all three Time Study paths from the Dimension Split"
|
||||
},
|
||||
dilationPenalty: {
|
||||
id: 9,
|
||||
cost: 1e11,
|
||||
description: () => `Reduce the Dilation penalty (${formatPow(1.05, 2, 2)} after reduction)`,
|
||||
effect: 1.05,
|
||||
},
|
||||
ttGenerator: {
|
||||
id: 10,
|
||||
cost: 1e15,
|
||||
description: "Generate Time Theorems based on Tachyon Particles",
|
||||
effect: () => Currency.tachyonParticles.value.div(20000),
|
||||
formatEffect: value => `${format(value, 2, 1)}/sec`
|
||||
},
|
||||
dtGainPelle: rebuyable({
|
||||
id: 11,
|
||||
initialCost: 1e14,
|
||||
increment: 100,
|
||||
pelleOnly: true,
|
||||
description: () => `${formatX(5)} Dilated Time gain`,
|
||||
effect: bought => Decimal.pow(5, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
galaxyMultiplier: rebuyable({
|
||||
id: 12,
|
||||
initialCost: 1e15,
|
||||
increment: 1000,
|
||||
pelleOnly: true,
|
||||
description: () => "Multiply Tachyon Galaxies gained",
|
||||
effect: bought => bought + 1,
|
||||
formatEffect: value => `${formatX(value, 2)} ➜ ${formatX(value + 1, 2)}`,
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
tickspeedPower: rebuyable({
|
||||
id: 13,
|
||||
initialCost: 1e16,
|
||||
increment: 1e4,
|
||||
pelleOnly: true,
|
||||
description: () => `Gain a power to tickspeed effect`,
|
||||
effect: bought => 1 + bought * 0.03,
|
||||
formatEffect: value => `${formatPow(value, 2, 2)} ➜ ${formatPow(value + 0.03, 2, 2)}`,
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
galaxyThresholdPelle: {
|
||||
id: 14,
|
||||
cost: 1e45,
|
||||
pelleOnly: true,
|
||||
description: "Cubic root Tachyon Galaxy threshold",
|
||||
effect: 1 / 3
|
||||
},
|
||||
flatDilationMult: {
|
||||
id: 15,
|
||||
cost: 1e55,
|
||||
pelleOnly: true,
|
||||
description: () => `Gain more Dilated Time based on EP`,
|
||||
effect: () => 1e9 ** Math.min((Math.max(player.eternityPoints.log10() - 1500, 0) / 2500) ** 1.2, 1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
id: config.id,
|
||||
cost: () => rebuyableCost(config.initialCost, config.increment, config.id),
|
||||
initialCost: config.initialCost,
|
||||
increment: config.increment,
|
||||
description: config.description,
|
||||
effect: () => config.effect(player.dilation.rebuyables[config.id]),
|
||||
formatEffect: config.formatEffect,
|
||||
formatCost: config.formatCost,
|
||||
purchaseCap: config.purchaseCap,
|
||||
reachedCap: () => player.dilation.rebuyables[config.id] >= config.purchaseCap,
|
||||
pelleOnly: Boolean(config.pelleOnly),
|
||||
rebuyable: true
|
||||
};
|
||||
}());
|
||||
}
|
||||
|
||||
GameDatabase.eternity.dilation = {
|
||||
dtGain: rebuyable({
|
||||
id: 1,
|
||||
initialCost: 1e5,
|
||||
increment: 10,
|
||||
description: () =>
|
||||
(SingularityMilestone.dilatedTimeFromSingularities.isUnlocked
|
||||
? `${formatX(2 * SingularityMilestone.dilatedTimeFromSingularities.effectValue, 2, 2)} Dilated Time gain`
|
||||
: "Double Dilated Time gain"),
|
||||
effect: bought => {
|
||||
const base = SingularityMilestone.dilatedTimeFromSingularities.isUnlocked
|
||||
? 2 * SingularityMilestone.dilatedTimeFromSingularities.effectValue
|
||||
: 2;
|
||||
return Decimal.pow(base, bought);
|
||||
},
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
galaxyThreshold: rebuyable({
|
||||
id: 2,
|
||||
initialCost: 1e6,
|
||||
increment: 100,
|
||||
description: () =>
|
||||
(Perk.bypassTGReset.isBought
|
||||
? "Reset Tachyon Galaxies, but lower their threshold"
|
||||
: "Reset Dilated Time and Tachyon Galaxies, but lower their threshold"),
|
||||
// The 38th purchase is at 1e80, and is the last purchase.
|
||||
effect: bought => (bought < 38 ? Math.pow(0.8, bought) : 0),
|
||||
formatEffect: effect => {
|
||||
if (effect === 0) return `${formatX(getTachyonGalaxyMult(effect), 4, 4)}`;
|
||||
const nextEffect = effect === Math.pow(0.8, 37) ? 0 : 0.8 * effect;
|
||||
return `${formatX(getTachyonGalaxyMult(effect), 4, 4)} ➜
|
||||
Next: ${formatX(getTachyonGalaxyMult(nextEffect), 4, 4)}`;
|
||||
},
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: 38
|
||||
}),
|
||||
tachyonGain: rebuyable({
|
||||
id: 3,
|
||||
initialCost: 1e7,
|
||||
increment: 20,
|
||||
description: () => {
|
||||
if (Pelle.isDoomed) return `Multiply the amount of Tachyon Particles gained by ${formatInt(1)}`;
|
||||
if (Enslaved.isRunning) return `Multiply the amount of Tachyon Particles gained
|
||||
by ${Math.pow(3, Enslaved.tachyonNerf).toFixed(2)}`;
|
||||
return "Triple the amount of Tachyon Particles gained";
|
||||
},
|
||||
effect: bought => {
|
||||
if (Pelle.isDoomed) return DC.D1.pow(bought);
|
||||
return DC.D3.pow(bought);
|
||||
},
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
doubleGalaxies: {
|
||||
id: 4,
|
||||
cost: 5e6,
|
||||
description: () => `Gain twice as many Tachyon Galaxies, up to ${formatInt(1000)}`,
|
||||
effect: 2
|
||||
},
|
||||
tdMultReplicanti: {
|
||||
id: 5,
|
||||
cost: 1e9,
|
||||
description: () => {
|
||||
const rep10 = replicantiMult().pLog10();
|
||||
let multiplier = "0.1";
|
||||
if (rep10 > 9000) {
|
||||
const ratio = DilationUpgrade.tdMultReplicanti.effectValue.pLog10() / rep10;
|
||||
if (ratio < 0.095) {
|
||||
multiplier = ratio.toFixed(2);
|
||||
}
|
||||
}
|
||||
return `Time Dimensions are affected by Replicanti multiplier ${formatPow(multiplier, 1, 3)}, reduced
|
||||
effect above ${formatX(DC.E9000)}`;
|
||||
},
|
||||
effect: () => {
|
||||
let rep10 = replicantiMult().pLog10() * 0.1;
|
||||
rep10 = rep10 > 9000 ? 9000 + 0.5 * (rep10 - 9000) : rep10;
|
||||
return Decimal.pow10(rep10);
|
||||
},
|
||||
formatEffect: value => formatX(value, 2, 1)
|
||||
},
|
||||
ndMultDT: {
|
||||
id: 6,
|
||||
cost: 5e7,
|
||||
description: "Antimatter Dimension multiplier based on Dilated Time, unaffected by Time Dilation",
|
||||
effect: () => Currency.dilatedTime.value.pow(308).clampMin(1),
|
||||
formatEffect: value => formatX(value, 2, 1)
|
||||
},
|
||||
ipMultDT: {
|
||||
id: 7,
|
||||
cost: 2e12,
|
||||
description: "Gain a multiplier to Infinity Points based on Dilated Time",
|
||||
effect: () => Currency.dilatedTime.value.pow(1000).clampMin(1),
|
||||
formatEffect: value => formatX(value, 2, 1),
|
||||
cap: () => Effarig.eternityCap
|
||||
},
|
||||
timeStudySplit: {
|
||||
id: 8,
|
||||
cost: 1e10,
|
||||
description: "You can buy all three Time Study paths from the Dimension Split"
|
||||
},
|
||||
dilationPenalty: {
|
||||
id: 9,
|
||||
cost: 1e11,
|
||||
description: () => `Reduce the Dilation penalty (${formatPow(1.05, 2, 2)} after reduction)`,
|
||||
effect: 1.05,
|
||||
},
|
||||
ttGenerator: {
|
||||
id: 10,
|
||||
cost: 1e15,
|
||||
description: "Generate Time Theorems based on Tachyon Particles",
|
||||
effect: () => Currency.tachyonParticles.value.div(20000),
|
||||
formatEffect: value => `${format(value, 2, 1)}/sec`
|
||||
},
|
||||
dtGainPelle: rebuyable({
|
||||
id: 11,
|
||||
initialCost: 1e14,
|
||||
increment: 100,
|
||||
pelleOnly: true,
|
||||
description: () => `${formatX(5)} Dilated Time gain`,
|
||||
effect: bought => Decimal.pow(5, bought),
|
||||
formatEffect: value => formatX(value, 2),
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
galaxyMultiplier: rebuyable({
|
||||
id: 12,
|
||||
initialCost: 1e15,
|
||||
increment: 1000,
|
||||
pelleOnly: true,
|
||||
description: () => "Multiply Tachyon Galaxies gained",
|
||||
effect: bought => bought + 1,
|
||||
formatEffect: value => `${formatX(value, 2)} ➜ ${formatX(value + 1, 2)}`,
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
tickspeedPower: rebuyable({
|
||||
id: 13,
|
||||
initialCost: 1e16,
|
||||
increment: 1e4,
|
||||
pelleOnly: true,
|
||||
description: () => `Gain a power to tickspeed effect`,
|
||||
effect: bought => 1 + bought * 0.03,
|
||||
formatEffect: value => `${formatPow(value, 2, 2)} ➜ ${formatPow(value + 0.03, 2, 2)}`,
|
||||
formatCost: value => format(value, 2),
|
||||
purchaseCap: Number.MAX_VALUE
|
||||
}),
|
||||
galaxyThresholdPelle: {
|
||||
id: 14,
|
||||
cost: 1e45,
|
||||
pelleOnly: true,
|
||||
description: "Cubic root Tachyon Galaxy threshold",
|
||||
effect: 1 / 3
|
||||
},
|
||||
flatDilationMult: {
|
||||
id: 15,
|
||||
cost: 1e55,
|
||||
pelleOnly: true,
|
||||
description: () => `Gain more Dilated Time based on EP`,
|
||||
effect: () => 1e9 ** Math.min((Math.max(player.eternityPoints.log10() - 1500, 0) / 2500) ** 1.2, 1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,8 @@ export const GameDatabase = {
|
|||
glyphSacrifice: {},
|
||||
},
|
||||
celestials: {
|
||||
effarig: {},
|
||||
alchemy: {},
|
||||
pelle: {},
|
||||
descriptions: {},
|
||||
}
|
||||
|
|
|
@ -1,145 +1,148 @@
|
|||
import { DC } from "../../constants";
|
||||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.infinity.breakUpgrades = (function() {
|
||||
function rebuyable(config) {
|
||||
const effectFunction = config.effect || (x => x);
|
||||
return {
|
||||
id: config.id,
|
||||
cost: () => config.initialCost * Math.pow(config.costIncrease, player.infinityRebuyables[config.id]),
|
||||
maxUpgrades: config.maxUpgrades,
|
||||
description: config.description,
|
||||
effect: () => effectFunction(player.infinityRebuyables[config.id]),
|
||||
isDisabled: config.isDisabled,
|
||||
// There isn't enough room in the button to fit the EC reduction and "Next:" at the same time while still
|
||||
// presenting all the information in an understandable way, so we only show it if the upgrade is maxed
|
||||
formatEffect: config.formatEffect ||
|
||||
(value => {
|
||||
const afterECText = config.afterEC ? config.afterEC() : "";
|
||||
return value === config.maxUpgrades
|
||||
? `Default: ${formatX(10)} | Currently: ${formatX(10 - value)} ${afterECText}`
|
||||
: `Default: ${formatX(10)} | Currently: ${formatX(10 - value)} Next: ${formatX(10 - value - 1)}`;
|
||||
}),
|
||||
formatCost: value => format(value, 2, 0),
|
||||
noLabel: !config.label
|
||||
};
|
||||
}
|
||||
|
||||
function rebuyable(config) {
|
||||
const effectFunction = config.effect || (x => x);
|
||||
const { id, maxUpgrades, description, isDisabled, noLabel, onPurchased } = config;
|
||||
return {
|
||||
totalAMMult: {
|
||||
id: "totalMult",
|
||||
cost: 1e4,
|
||||
description: "Antimatter Dimensions gain a multiplier based on total antimatter produced",
|
||||
effect: () => Math.pow(player.records.totalAntimatter.exponent + 1, 0.5),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
currentAMMult: {
|
||||
id: "currentMult",
|
||||
cost: 5e4,
|
||||
description: "Antimatter Dimensions gain a multiplier based on current antimatter",
|
||||
effect: () => Math.pow(Currency.antimatter.exponent + 1, 0.5),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
galaxyBoost: {
|
||||
id: "postGalaxy",
|
||||
cost: 5e11,
|
||||
description: () => `All Galaxies are ${formatPercents(0.5)} stronger`,
|
||||
effect: 1.5
|
||||
},
|
||||
infinitiedMult: {
|
||||
id: "infinitiedMult",
|
||||
cost: 1e5,
|
||||
description: "Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => 1 + Currency.infinitiesTotal.value.pLog10() * 10,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
achievementMult: {
|
||||
id: "achievementMult",
|
||||
cost: 1e6,
|
||||
description: "Additional multiplier to Antimatter Dimensions based on Achievements completed",
|
||||
effect: () => Math.max(Math.pow((Achievements.effectiveCount - 30), 3) / 40, 1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
slowestChallengeMult: {
|
||||
id: "challengeMult",
|
||||
cost: 1e7,
|
||||
description: "Antimatter Dimensions gain a multiplier based on slowest challenge run",
|
||||
effect: () => Decimal.clampMin(50 / Time.worstChallenge.totalMinutes, 1),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
hasCap: true,
|
||||
cap: DC.D3E4
|
||||
},
|
||||
infinitiedGen: {
|
||||
id: "infinitiedGeneration",
|
||||
cost: 2e7,
|
||||
description: () => (Pelle.isDoomed
|
||||
? "This upgrade has no effect while in Doomed"
|
||||
: "Passively generate Infinities based on your fastest Infinity"),
|
||||
effect: () => player.records.bestInfinity.time,
|
||||
formatEffect: value => {
|
||||
if (Pelle.isDoomed) return "Disabled";
|
||||
if (value === Number.MAX_VALUE && !Pelle.isDoomed) return "No Infinity generation";
|
||||
let infinities = DC.D1;
|
||||
infinities = infinities.timesEffectsOf(
|
||||
RealityUpgrade(5),
|
||||
RealityUpgrade(7),
|
||||
Ra.unlocks.continuousTTBoost.effects.infinity
|
||||
);
|
||||
infinities = infinities.times(getAdjustedGlyphEffect("infinityinfmult"));
|
||||
return `${quantify("Infinity", infinities)} every ${Time.bestInfinity.times(5).toStringShort()}`;
|
||||
}
|
||||
},
|
||||
autobuyMaxDimboosts: {
|
||||
id: "autobuyMaxDimboosts",
|
||||
cost: 5e9,
|
||||
description: "Unlock the buy max Dimension Boost Autobuyer mode"
|
||||
},
|
||||
autobuyerSpeed: {
|
||||
id: "autoBuyerUpgrade",
|
||||
cost: 1e15,
|
||||
description: "Autobuyers unlocked or improved by Normal Challenges work twice as fast"
|
||||
},
|
||||
tickspeedCostMult: rebuyable({
|
||||
id: 0,
|
||||
initialCost: 1e6,
|
||||
costIncrease: 5,
|
||||
maxUpgrades: 8,
|
||||
description: "Reduce post-infinity Tickspeed Upgrade cost multiplier scaling",
|
||||
afterEC: () => (EternityChallenge(11).completions > 0
|
||||
? `After EC11: ${formatX(Player.tickSpeedMultDecrease, 2, 2)}`
|
||||
: ""
|
||||
),
|
||||
label: false,
|
||||
}),
|
||||
dimCostMult: rebuyable({
|
||||
id: 1,
|
||||
initialCost: 1e7,
|
||||
costIncrease: 5e3,
|
||||
maxUpgrades: 7,
|
||||
description: "Reduce post-infinity Antimatter Dimension cost multiplier scaling",
|
||||
afterEC: () => (EternityChallenge(6).completions > 0
|
||||
? `After EC6: ${formatX(Player.dimensionMultDecrease, 2, 2)}`
|
||||
: ""
|
||||
),
|
||||
label: false,
|
||||
}),
|
||||
ipGen: rebuyable({
|
||||
id: 2,
|
||||
initialCost: 1e7,
|
||||
costIncrease: 10,
|
||||
maxUpgrades: 10,
|
||||
effect: value => Player.bestRunIPPM.times(value / 20),
|
||||
description: () => {
|
||||
let generation = `Generate ${formatInt(5 * player.infinityRebuyables[2])}%`;
|
||||
if (!BreakInfinityUpgrade.ipGen.isCapped) {
|
||||
generation += ` ➜ ${formatInt(5 * (1 + player.infinityRebuyables[2]))}%`;
|
||||
}
|
||||
const offlineString = player.options.offlineProgress ? ", works offline" : "";
|
||||
return `${generation} of your best IP/min from your last 10 Infinities${offlineString}`;
|
||||
},
|
||||
isDisabled: effect => effect.eq(0),
|
||||
formatEffect: value => `${format(value, 2, 1)} IP/min`,
|
||||
label: true
|
||||
})
|
||||
rebuyable: true,
|
||||
id,
|
||||
cost: () => config.initialCost * Math.pow(config.costIncrease, player.infinityRebuyables[config.id]),
|
||||
maxUpgrades,
|
||||
description,
|
||||
effect: () => effectFunction(player.infinityRebuyables[config.id]),
|
||||
isDisabled,
|
||||
// There isn't enough room in the button to fit the EC reduction and "Next:" at the same time while still
|
||||
// presenting all the information in an understandable way, so we only show it if the upgrade is maxed
|
||||
formatEffect: config.formatEffect ||
|
||||
(value => {
|
||||
const afterECText = config.afterEC ? config.afterEC() : "";
|
||||
return value === config.maxUpgrades
|
||||
? `Default: ${formatX(10)} | Currently: ${formatX(10 - value)} ${afterECText}`
|
||||
: `Default: ${formatX(10)} | Currently: ${formatX(10 - value)} Next: ${formatX(10 - value - 1)}`;
|
||||
}),
|
||||
formatCost: value => format(value, 2, 0),
|
||||
noLabel,
|
||||
onPurchased
|
||||
};
|
||||
}());
|
||||
}
|
||||
|
||||
GameDatabase.infinity.breakUpgrades = {
|
||||
totalAMMult: {
|
||||
id: "totalMult",
|
||||
cost: 1e4,
|
||||
description: "Antimatter Dimensions gain a multiplier based on total antimatter produced",
|
||||
effect: () => Math.pow(player.records.totalAntimatter.exponent + 1, 0.5),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
currentAMMult: {
|
||||
id: "currentMult",
|
||||
cost: 5e4,
|
||||
description: "Antimatter Dimensions gain a multiplier based on current antimatter",
|
||||
effect: () => Math.pow(Currency.antimatter.exponent + 1, 0.5),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
galaxyBoost: {
|
||||
id: "postGalaxy",
|
||||
cost: 5e11,
|
||||
description: () => `All Galaxies are ${formatPercents(0.5)} stronger`,
|
||||
effect: 1.5
|
||||
},
|
||||
infinitiedMult: {
|
||||
id: "infinitiedMult",
|
||||
cost: 1e5,
|
||||
description: "Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => 1 + Currency.infinitiesTotal.value.pLog10() * 10,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
achievementMult: {
|
||||
id: "achievementMult",
|
||||
cost: 1e6,
|
||||
description: "Additional multiplier to Antimatter Dimensions based on Achievements completed",
|
||||
effect: () => Math.max(Math.pow((Achievements.effectiveCount - 30), 3) / 40, 1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
slowestChallengeMult: {
|
||||
id: "challengeMult",
|
||||
cost: 1e7,
|
||||
description: "Antimatter Dimensions gain a multiplier based on slowest challenge run",
|
||||
effect: () => Decimal.clampMin(50 / Time.worstChallenge.totalMinutes, 1),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
hasCap: true,
|
||||
cap: DC.D3E4
|
||||
},
|
||||
infinitiedGen: {
|
||||
id: "infinitiedGeneration",
|
||||
cost: 2e7,
|
||||
description: () => (Pelle.isDoomed
|
||||
? "This upgrade has no effect while in Doomed"
|
||||
: "Passively generate Infinities based on your fastest Infinity"),
|
||||
effect: () => player.records.bestInfinity.time,
|
||||
formatEffect: value => {
|
||||
if (Pelle.isDoomed) return "Disabled";
|
||||
if (value === Number.MAX_VALUE && !Pelle.isDoomed) return "No Infinity generation";
|
||||
let infinities = DC.D1;
|
||||
infinities = infinities.timesEffectsOf(
|
||||
RealityUpgrade(5),
|
||||
RealityUpgrade(7),
|
||||
Ra.unlocks.continuousTTBoost.effects.infinity
|
||||
);
|
||||
infinities = infinities.times(getAdjustedGlyphEffect("infinityinfmult"));
|
||||
return `${quantify("Infinity", infinities)} every ${Time.bestInfinity.times(5).toStringShort()}`;
|
||||
}
|
||||
},
|
||||
autobuyMaxDimboosts: {
|
||||
id: "autobuyMaxDimboosts",
|
||||
cost: 5e9,
|
||||
description: "Unlock the buy max Dimension Boost Autobuyer mode"
|
||||
},
|
||||
autobuyerSpeed: {
|
||||
id: "autoBuyerUpgrade",
|
||||
cost: 1e15,
|
||||
description: "Autobuyers unlocked or improved by Normal Challenges work twice as fast"
|
||||
},
|
||||
tickspeedCostMult: rebuyable({
|
||||
id: 0,
|
||||
initialCost: 1e6,
|
||||
costIncrease: 5,
|
||||
maxUpgrades: 8,
|
||||
description: "Reduce post-infinity Tickspeed Upgrade cost multiplier scaling",
|
||||
afterEC: () => (EternityChallenge(11).completions > 0
|
||||
? `After EC11: ${formatX(Player.tickSpeedMultDecrease, 2, 2)}`
|
||||
: ""
|
||||
),
|
||||
noLabel: true,
|
||||
onPurchased: () => GameCache.tickSpeedMultDecrease.invalidate()
|
||||
}),
|
||||
dimCostMult: rebuyable({
|
||||
id: 1,
|
||||
initialCost: 1e7,
|
||||
costIncrease: 5e3,
|
||||
maxUpgrades: 7,
|
||||
description: "Reduce post-infinity Antimatter Dimension cost multiplier scaling",
|
||||
afterEC: () => (EternityChallenge(6).completions > 0
|
||||
? `After EC6: ${formatX(Player.dimensionMultDecrease, 2, 2)}`
|
||||
: ""
|
||||
),
|
||||
noLabel: true,
|
||||
onPurchased: () => GameCache.dimensionMultDecrease.invalidate()
|
||||
}),
|
||||
ipGen: rebuyable({
|
||||
id: 2,
|
||||
initialCost: 1e7,
|
||||
costIncrease: 10,
|
||||
maxUpgrades: 10,
|
||||
effect: value => Player.bestRunIPPM.times(value / 20),
|
||||
description: () => {
|
||||
let generation = `Generate ${formatInt(5 * player.infinityRebuyables[2])}%`;
|
||||
if (!BreakInfinityUpgrade.ipGen.isCapped) {
|
||||
generation += ` ➜ ${formatInt(5 * (1 + player.infinityRebuyables[2]))}%`;
|
||||
}
|
||||
const offlineString = player.options.offlineProgress ? ", works offline" : "";
|
||||
return `${generation} of your best IP/min from your last 10 Infinities${offlineString}`;
|
||||
},
|
||||
isDisabled: effect => effect.eq(0),
|
||||
formatEffect: value => `${format(value, 2, 1)} IP/min`,
|
||||
noLabel: false
|
||||
})
|
||||
};
|
||||
|
|
|
@ -1,227 +1,241 @@
|
|||
import { DC } from "../../constants";
|
||||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.infinity.upgrades = (function() {
|
||||
function dimInfinityMult() {
|
||||
return Currency.infinitiesTotal.value.times(0.2).plus(1);
|
||||
}
|
||||
function chargedDimInfinityMult() {
|
||||
return 1 + Math.log10(Math.max(1, Currency.infinitiesTotal.value.pLog10())) * Math.sqrt(Ra.pets.teresa.level) / 150;
|
||||
}
|
||||
return {
|
||||
totalTimeMult: {
|
||||
id: "timeMult",
|
||||
cost: 1,
|
||||
description: "Antimatter Dimensions gain a multiplier based on time played",
|
||||
effect: () => Math.pow(Time.totalTimePlayed.totalMinutes / 2, 0.15),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
charged: {
|
||||
description: "Antimatter Dimensions gain a power effect based on time played and Teresa level",
|
||||
effect: () => 1 +
|
||||
Math.log10(Math.log10(Time.totalTimePlayed.totalMilliseconds)) *
|
||||
Math.pow(Ra.pets.teresa.level, 0.5) / 150,
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
dim18mult: {
|
||||
id: "18Mult",
|
||||
cost: 1,
|
||||
description: "1st and 8th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "1st and 8th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
dim27mult: {
|
||||
id: "27Mult",
|
||||
cost: 1,
|
||||
description: "2nd and 7th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "2nd and 7th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
dim36mult: {
|
||||
id: "36Mult",
|
||||
cost: 1,
|
||||
description: "3rd and 6th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "3rd and 6th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
dim45mult: {
|
||||
id: "45Mult",
|
||||
cost: 1,
|
||||
description: "4th and 5th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "4th and 5th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
resetBoost: {
|
||||
id: "resetBoost",
|
||||
cost: 1,
|
||||
description: () =>
|
||||
`Decrease the number of Dimensions needed for Dimension Boosts and Antimatter Galaxies by ${formatInt(9)}`,
|
||||
effect: 9,
|
||||
charged: {
|
||||
description: () => "Decrease Dimension Boost requirement based on Teresa level",
|
||||
effect: () => 1 / (1 + Math.sqrt(Ra.pets.teresa.level) / 10),
|
||||
formatEffect: value => `${formatX(value, 4, 4)}`
|
||||
}
|
||||
},
|
||||
buy10Mult: {
|
||||
id: "dimMult",
|
||||
cost: 1,
|
||||
description: () => `Increase the multiplier for buying ${formatInt(10)} Antimatter Dimensions`,
|
||||
effect: () => 1.1,
|
||||
formatEffect: () => `${formatX(2, 0, 1)} ➜ ${formatX(2.2, 0, 1)}`,
|
||||
charged: {
|
||||
description: () => `The multiplier for buying ${formatInt(10)} Antimatter Dimensions gains ` +
|
||||
"a power effect based on Teresa level",
|
||||
effect: () => 1 + Ra.pets.teresa.level / 200,
|
||||
formatEffect: value => formatPow(value, 3, 3)
|
||||
}
|
||||
},
|
||||
galaxyBoost: {
|
||||
id: "galaxyBoost",
|
||||
cost: 2,
|
||||
description: "All Galaxies are twice as strong",
|
||||
effect: 2,
|
||||
charged: {
|
||||
description: "All Galaxies are stronger based on Teresa level",
|
||||
effect: () => 2 + Math.sqrt(Ra.pets.teresa.level) / 100,
|
||||
formatEffect: value => `+${formatPercents(value - 1)}`
|
||||
}
|
||||
},
|
||||
thisInfinityTimeMult: {
|
||||
id: "timeMult2",
|
||||
cost: 3,
|
||||
description: "Antimatter Dimensions gain a multiplier based on time spent in current Infinity",
|
||||
effect: () => Decimal.max(Math.pow(Time.thisInfinity.totalMinutes / 4, 0.25), 1),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
charged: {
|
||||
description:
|
||||
"Antimatter Dimensions gain a power effect based on time spent in current Infinity and Teresa level",
|
||||
effect: () => 1 +
|
||||
Math.log10(Math.log10(Time.thisInfinity.totalMilliseconds + 100)) *
|
||||
Math.sqrt(Ra.pets.teresa.level) / 150,
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
unspentIPMult: {
|
||||
id: "unspentBonus",
|
||||
cost: 5,
|
||||
description: "Multiplier to 1st Antimatter Dimension based on unspent Infinity Points",
|
||||
effect: () => Currency.infinityPoints.value.dividedBy(2).pow(1.5).plus(1),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
charged: {
|
||||
description: "Multiplier to 1st Antimatter Dimension based on unspent Infinity Points, powered by Teresa level",
|
||||
effect: () => Currency.infinityPoints.value.dividedBy(2).pow(Math.sqrt(Ra.pets.teresa.level) * 1.5).plus(1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
}
|
||||
},
|
||||
dimboostMult: {
|
||||
id: "resetMult",
|
||||
cost: 7,
|
||||
description: "Increase Dimension Boost multiplier",
|
||||
effect: () => 2.5,
|
||||
formatEffect: () => `${formatX(2, 0, 1)} ➜ ${formatX(2.5, 0, 1)}`,
|
||||
charged: {
|
||||
description: "Dimension Boost multiplier gains a power effect based on Teresa level",
|
||||
effect: () => 1 + Ra.pets.teresa.level / 200,
|
||||
formatEffect: value => formatPow(value, 3, 3)
|
||||
}
|
||||
},
|
||||
ipGen: {
|
||||
id: "passiveGen",
|
||||
cost: 10,
|
||||
description: () => (Pelle.isDoomed
|
||||
? "This upgrade has no effect while in Doomed"
|
||||
: `Passively generate Infinity Points ${formatInt(10)} times slower than your fastest Infinity`),
|
||||
// Cutting corners: this is not actual effect, but it is totalIPMult that is displyed on upgrade
|
||||
effect: () => (Teresa.isRunning || V.isRunning || Pelle.isDoomed ? DC.D0 : GameCache.totalIPMult.value),
|
||||
formatEffect: value => {
|
||||
if (Teresa.isRunning || V.isRunning) return "Disabled in this reality";
|
||||
if (Pelle.isDoomed) return "Disabled";
|
||||
const income = format(value, 2, 0);
|
||||
const period = player.records.bestInfinity.time >= 999999999999
|
||||
? "∞"
|
||||
: Time.bestInfinity.times(10).toStringShort();
|
||||
return `${income} every ${period}`;
|
||||
},
|
||||
charged: {
|
||||
description: () =>
|
||||
`Gain a percentage of your Reality Machines gained on Reality each real-time second,
|
||||
percent increases with Teresa level`,
|
||||
effect: () => Math.sqrt(Ra.pets.teresa.level) / 1000 *
|
||||
Ra.unlocks.continuousTTBoost.effects.autoPrestige.effectOrDefault(1),
|
||||
formatEffect: value => `${formatPercents(value, 2)}`
|
||||
}
|
||||
},
|
||||
skipReset1: {
|
||||
id: "skipReset1",
|
||||
cost: 20,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(1)} Dimension Boost, automatically unlocking the 5th Antimatter Dimension`,
|
||||
},
|
||||
skipReset2: {
|
||||
id: "skipReset2",
|
||||
cost: 40,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(2)} Dimension Boosts, automatically unlocking the 6th Antimatter Dimension`,
|
||||
},
|
||||
skipReset3: {
|
||||
id: "skipReset3",
|
||||
cost: 80,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(3)} Dimension Boosts, automatically unlocking the 7th Antimatter Dimension`,
|
||||
},
|
||||
skipResetGalaxy: {
|
||||
id: "skipResetGalaxy",
|
||||
cost: 300,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(4)} Dimension Boosts, automatically unlocking the 8th Antimatter Dimension;
|
||||
and an Antimatter Galaxy`,
|
||||
},
|
||||
ipOffline: {
|
||||
id: "ipOffline",
|
||||
cost: 1000,
|
||||
description: () => (player.options.offlineProgress
|
||||
? `Only while offline, gain ${formatPercents(0.5)} of your best IP/min without using Max All`
|
||||
: "This upgrade would give offline Infinity Point generation, but offline progress is currently disabled"),
|
||||
effect: () => (player.options.offlineProgress
|
||||
? player.records.thisEternity.bestIPMsWithoutMaxAll.times(TimeSpan.fromMinutes(1).totalMilliseconds / 2)
|
||||
: DC.D0),
|
||||
isDisabled: () => !player.options.offlineProgress,
|
||||
formatEffect: value => `${format(value, 2, 2)} IP/min`,
|
||||
},
|
||||
ipMult: {
|
||||
id: "ipMult",
|
||||
cost: () => InfinityUpgrade.ipMult.cost,
|
||||
costCap: DC.E6E6,
|
||||
costIncreaseThreshold: DC.E3E6,
|
||||
description: () => (Pelle.isDoomed
|
||||
? "This upgrade has no effect while in Doomed"
|
||||
: `Multiply Infinity Points from all sources by ${formatX(2)}`),
|
||||
// Normally the multiplier caps at e993k or so with 3300000 purchases, but if the cost is capped then we just give
|
||||
// an extra e7k to make the multiplier look nice
|
||||
effect: () => (player.IPMultPurchases >= 3300000 ? DC.E1E6 : DC.D2.pow(player.IPMultPurchases)),
|
||||
cap: () => Effarig.eternityCap ?? DC.E1E6,
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
|
||||
function dimInfinityMult() {
|
||||
return Currency.infinitiesTotal.value.times(0.2).plus(1);
|
||||
}
|
||||
function chargedDimInfinityMult() {
|
||||
return 1 + Math.log10(Math.max(1, Currency.infinitiesTotal.value.pLog10())) * Math.sqrt(Ra.pets.teresa.level) / 150;
|
||||
}
|
||||
|
||||
GameDatabase.infinity.upgrades = {
|
||||
totalTimeMult: {
|
||||
id: "timeMult",
|
||||
cost: 1,
|
||||
description: "Antimatter Dimensions gain a multiplier based on time played",
|
||||
effect: () => Math.pow(Time.totalTimePlayed.totalMinutes / 2, 0.15),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
charged: {
|
||||
description: "Antimatter Dimensions gain a power effect based on time played and Teresa level",
|
||||
effect: () => 1 +
|
||||
Math.log10(Math.log10(Time.totalTimePlayed.totalMilliseconds)) *
|
||||
Math.pow(Ra.pets.teresa.level, 0.5) / 150,
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
};
|
||||
}());
|
||||
},
|
||||
dim18mult: {
|
||||
id: "18Mult",
|
||||
cost: 1,
|
||||
checkRequirement: () => InfinityUpgrade.totalTimeMult.isBought,
|
||||
description: "1st and 8th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "1st and 8th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
dim27mult: {
|
||||
id: "27Mult",
|
||||
cost: 1,
|
||||
checkRequirement: () => InfinityUpgrade.buy10Mult.isBought,
|
||||
description: "2nd and 7th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "2nd and 7th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
dim36mult: {
|
||||
id: "36Mult",
|
||||
cost: 1,
|
||||
checkRequirement: () => InfinityUpgrade.dim18mult.isBought,
|
||||
description: "3rd and 6th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "3rd and 6th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
dim45mult: {
|
||||
id: "45Mult",
|
||||
cost: 1,
|
||||
checkRequirement: () => InfinityUpgrade.dim27mult.isBought,
|
||||
description: "4th and 5th Antimatter Dimensions gain a multiplier based on Infinities",
|
||||
effect: () => dimInfinityMult(),
|
||||
formatEffect: value => formatX(value, 1, 1),
|
||||
charged: {
|
||||
description: "4th and 5th Antimatter Dimensions gain a power effect based on Infinities and Teresa level",
|
||||
effect: () => chargedDimInfinityMult(),
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
resetBoost: {
|
||||
id: "resetBoost",
|
||||
cost: 1,
|
||||
checkRequirement: () => InfinityUpgrade.dim36mult.isBought,
|
||||
description: () =>
|
||||
`Decrease the number of Dimensions needed for Dimension Boosts and Antimatter Galaxies by ${formatInt(9)}`,
|
||||
effect: 9,
|
||||
charged: {
|
||||
description: () => "Decrease Dimension Boost requirement based on Teresa level",
|
||||
effect: () => 1 / (1 + Math.sqrt(Ra.pets.teresa.level) / 10),
|
||||
formatEffect: value => `${formatX(value, 4, 4)}`
|
||||
}
|
||||
},
|
||||
buy10Mult: {
|
||||
id: "dimMult",
|
||||
cost: 1,
|
||||
description: () => `Increase the multiplier for buying ${formatInt(10)} Antimatter Dimensions`,
|
||||
effect: () => 1.1,
|
||||
formatEffect: () => `${formatX(2, 0, 1)} ➜ ${formatX(2.2, 0, 1)}`,
|
||||
charged: {
|
||||
description: () => `The multiplier for buying ${formatInt(10)} Antimatter Dimensions gains ` +
|
||||
"a power effect based on Teresa level",
|
||||
effect: () => 1 + Ra.pets.teresa.level / 200,
|
||||
formatEffect: value => formatPow(value, 3, 3)
|
||||
}
|
||||
},
|
||||
galaxyBoost: {
|
||||
id: "galaxyBoost",
|
||||
cost: 2,
|
||||
checkRequirement: () => InfinityUpgrade.dim45mult.isBought,
|
||||
description: "All Galaxies are twice as strong",
|
||||
effect: 2,
|
||||
charged: {
|
||||
description: "All Galaxies are stronger based on Teresa level",
|
||||
effect: () => 2 + Math.sqrt(Ra.pets.teresa.level) / 100,
|
||||
formatEffect: value => `+${formatPercents(value - 1)}`
|
||||
}
|
||||
},
|
||||
thisInfinityTimeMult: {
|
||||
id: "timeMult2",
|
||||
cost: 3,
|
||||
description: "Antimatter Dimensions gain a multiplier based on time spent in current Infinity",
|
||||
effect: () => Decimal.max(Math.pow(Time.thisInfinity.totalMinutes / 4, 0.25), 1),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
charged: {
|
||||
description:
|
||||
"Antimatter Dimensions gain a power effect based on time spent in current Infinity and Teresa level",
|
||||
effect: () => 1 +
|
||||
Math.log10(Math.log10(Time.thisInfinity.totalMilliseconds + 100)) *
|
||||
Math.sqrt(Ra.pets.teresa.level) / 150,
|
||||
formatEffect: value => formatPow(value, 4, 4)
|
||||
}
|
||||
},
|
||||
unspentIPMult: {
|
||||
id: "unspentBonus",
|
||||
cost: 5,
|
||||
checkRequirement: () => InfinityUpgrade.thisInfinityTimeMult.isBought,
|
||||
description: "Multiplier to 1st Antimatter Dimension based on unspent Infinity Points",
|
||||
effect: () => Currency.infinityPoints.value.dividedBy(2).pow(1.5).plus(1),
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
charged: {
|
||||
description: "Multiplier to 1st Antimatter Dimension based on unspent Infinity Points, powered by Teresa level",
|
||||
effect: () => Currency.infinityPoints.value.dividedBy(2).pow(Math.sqrt(Ra.pets.teresa.level) * 1.5).plus(1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
}
|
||||
},
|
||||
dimboostMult: {
|
||||
id: "resetMult",
|
||||
cost: 7,
|
||||
checkRequirement: () => InfinityUpgrade.unspentIPMult.isBought,
|
||||
description: "Increase Dimension Boost multiplier",
|
||||
effect: () => 2.5,
|
||||
formatEffect: () => `${formatX(2, 0, 1)} ➜ ${formatX(2.5, 0, 1)}`,
|
||||
charged: {
|
||||
description: "Dimension Boost multiplier gains a power effect based on Teresa level",
|
||||
effect: () => 1 + Ra.pets.teresa.level / 200,
|
||||
formatEffect: value => formatPow(value, 3, 3)
|
||||
}
|
||||
},
|
||||
ipGen: {
|
||||
id: "passiveGen",
|
||||
cost: 10,
|
||||
checkRequirement: () => InfinityUpgrade.dimboostMult.isBought,
|
||||
description: () => (Pelle.isDoomed
|
||||
? "This upgrade has no effect while in Doomed"
|
||||
: `Passively generate Infinity Points ${formatInt(10)} times slower than your fastest Infinity`),
|
||||
// Cutting corners: this is not actual effect, but it is totalIPMult that is displyed on upgrade
|
||||
effect: () => (Teresa.isRunning || V.isRunning || Pelle.isDoomed ? DC.D0 : GameCache.totalIPMult.value),
|
||||
formatEffect: value => {
|
||||
if (Teresa.isRunning || V.isRunning) return "Disabled in this reality";
|
||||
if (Pelle.isDoomed) return "Disabled";
|
||||
const income = format(value, 2, 0);
|
||||
const period = player.records.bestInfinity.time >= 999999999999
|
||||
? "∞"
|
||||
: Time.bestInfinity.times(10).toStringShort();
|
||||
return `${income} every ${period}`;
|
||||
},
|
||||
charged: {
|
||||
description: () =>
|
||||
`Gain a percentage of your Reality Machines gained on Reality each real-time second,
|
||||
percent increases with Teresa level`,
|
||||
effect: () => Math.sqrt(Ra.pets.teresa.level) / 1000 *
|
||||
Ra.unlocks.continuousTTBoost.effects.autoPrestige.effectOrDefault(1),
|
||||
formatEffect: value => `${formatPercents(value, 2)}`
|
||||
}
|
||||
},
|
||||
skipReset1: {
|
||||
id: "skipReset1",
|
||||
cost: 20,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(1)} Dimension Boost, automatically unlocking the 5th Antimatter Dimension`,
|
||||
},
|
||||
skipReset2: {
|
||||
id: "skipReset2",
|
||||
cost: 40,
|
||||
checkRequirement: () => InfinityUpgrade.skipReset1.isBought,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(2)} Dimension Boosts, automatically unlocking the 6th Antimatter Dimension`,
|
||||
},
|
||||
skipReset3: {
|
||||
id: "skipReset3",
|
||||
cost: 80,
|
||||
checkRequirement: () => InfinityUpgrade.skipReset2.isBought,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(3)} Dimension Boosts, automatically unlocking the 7th Antimatter Dimension`,
|
||||
},
|
||||
skipResetGalaxy: {
|
||||
id: "skipResetGalaxy",
|
||||
cost: 300,
|
||||
checkRequirement: () => InfinityUpgrade.skipReset3.isBought,
|
||||
description: () =>
|
||||
`Start every reset with ${formatInt(4)} Dimension Boosts, automatically unlocking the 8th Antimatter Dimension;
|
||||
and an Antimatter Galaxy`,
|
||||
},
|
||||
ipOffline: {
|
||||
id: "ipOffline",
|
||||
cost: 1000,
|
||||
checkRequirement: () => Achievement(41).isUnlocked,
|
||||
description: () => (player.options.offlineProgress
|
||||
? `Only while offline, gain ${formatPercents(0.5)} of your best IP/min without using Max All`
|
||||
: "This upgrade would give offline Infinity Point generation, but offline progress is currently disabled"),
|
||||
effect: () => (player.options.offlineProgress
|
||||
? player.records.thisEternity.bestIPMsWithoutMaxAll.times(TimeSpan.fromMinutes(1).totalMilliseconds / 2)
|
||||
: DC.D0),
|
||||
isDisabled: () => !player.options.offlineProgress,
|
||||
formatEffect: value => `${format(value, 2, 2)} IP/min`,
|
||||
},
|
||||
ipMult: {
|
||||
id: "ipMult",
|
||||
cost: () => InfinityUpgrade.ipMult.cost,
|
||||
checkRequirement: () => Achievement(41).isUnlocked,
|
||||
costCap: DC.E6E6,
|
||||
costIncreaseThreshold: DC.E3E6,
|
||||
description: () => (Pelle.isDoomed
|
||||
? "This upgrade has no effect while in Doomed"
|
||||
: `Multiply Infinity Points from all sources by ${formatX(2)}`),
|
||||
// Normally the multiplier caps at e993k or so with 3300000 purchases, but if the cost is capped then we just give
|
||||
// an extra e7k to make the multiplier look nice
|
||||
effect: () => (player.IPMultPurchases >= 3300000 ? DC.E1E6 : DC.D2.pow(player.IPMultPurchases)),
|
||||
cap: () => Effarig.eternityCap ?? DC.E1E6,
|
||||
formatEffect: value => formatX(value, 2, 2),
|
||||
}
|
||||
};
|
||||
|
|
|
@ -915,7 +915,7 @@ GameDatabase.news = [
|
|||
id: "a174",
|
||||
text:
|
||||
`<span style='font-family: runescape; color: yellow; text-shadow: 0.1rem 0.1rem black; letter-spacing: 0.1rem;
|
||||
font-size: 2rem; line-height: 0; animation: text-flash 1s steps(1, end) infinite;'
|
||||
font-size: 2rem; line-height: 0; animation: a-text-flash 1s steps(1, end) infinite;'
|
||||
>FREE RUNE ARMOR TRIMMING</span>`,
|
||||
},
|
||||
{
|
||||
|
@ -992,12 +992,12 @@ GameDatabase.news = [
|
|||
{
|
||||
id: "a184",
|
||||
text:
|
||||
`<span style='animation: text-grow 1s infinite'>R̵̬̙͋͂̀̋͑̈́̇͠Ê̵͇͎͂̂̍̓̌̐̋̋̀̀̔M̶̨̲̯̘͙̬̥̮̣͚̱̫͛̽̃͌̚͝
|
||||
"Ą̴͍̝͐Į̷̛̲̯̫̘͌́̄̏͌̀̈́͝͝Ṅ̶̛̻̠̠̤̦̞̞͗̎̊̌̊͝͠</span><span style='animation: text-shrink 1s infinite'>
|
||||
`<span style='animation: a-text-grow 1s infinite'>R̵̬̙͋͂̀̋͑̈́̇͠Ê̵͇͎͂̂̍̓̌̐̋̋̀̀̔M̶̨̲̯̘͙̬̥̮̣͚̱̫͛̽̃͌̚͝
|
||||
"Ą̴͍̝͐Į̷̛̲̯̫̘͌́̄̏͌̀̈́͝͝Ṅ̶̛̻̠̠̤̦̞̞͗̎̊̌̊͝͠</span><span style='animation: a-text-shrink 1s infinite'>
|
||||
Ḁ̷̛͂̈́͗̎̃̓͛́͘ͅW̶̡̖͓̗̦̃̇̌̀͝A̵͇̭͉̓̎̈̿̊́̄̚͜R̶̝͚̲̭͎͇͎͓͖͚͇̀̈́͗̃̏̂̌͝͝Ę̴̡̤͙͈̝̬̰͒͘</span><span style
|
||||
='animation: text-grow 1s infinite'> ̶̺̈́́̆̓͘͘Ồ̸̢̢̮͓̯̗͙͚̬̉͊̿F̶̠̤̱̱̱͊̂̍̔̃͆̆̑̿͘</span><span style='animation:
|
||||
text-shrink 1s infinite'> ̴̨̞̠̮͚̱͉͋̔͗̽̈́́́̅ͅỴ̶̣̙̹͚̲͔̲̼̬̥̀͌̒̾͘͘O̵̪̠̗̝̗̘̜͚̮̊͒͆̃̀̌̒͝ͅU̸͎͗̍̑̎̅̅͝R̵̗͑̽̏̓͆͒̈́͌͘̕
|
||||
</span><span style='animation: text-grow 1s infinite'> ̸̑̽̇̆͊̔̍̊̈́̈́͘ͅS̸̘͐͝U̴̥̭̚͘R̸̖̜͍͒́̋͆̈́̓
|
||||
='animation: a-text-grow 1s infinite'> ̶̺̈́́̆̓͘͘Ồ̸̢̢̮͓̯̗͙͚̬̉͊̿F̶̠̤̱̱̱͊̂̍̔̃͆̆̑̿͘</span><span style='animation:
|
||||
a-text-shrink 1s infinite'> ̴̨̞̠̮͚̱͉͋̔͗̽̈́́́̅ͅỴ̶̣̙̹͚̲͔̲̼̬̥̀͌̒̾͘͘O̵̪̠̗̝̗̘̜͚̮̊͒͆̃̀̌̒͝ͅU̸͎͗̍̑̎̅̅͝R̵̗͑̽̏̓͆͒̈́͌͘̕
|
||||
</span><span style='animation: a-text-grow 1s infinite'> ̸̑̽̇̆͊̔̍̊̈́̈́͘ͅS̸̘͐͝U̴̥̭̚͘R̸̖̜͍͒́̋͆̈́̓
|
||||
R̸̡̛̛̪̝̟̱̣̹̭̟̣̀̈̀̏̉̌͝͠Õ̶͙͈͖̠͇̬͍̟̰U̵̩̫͉̝͔̼͎̦̔̓̽͌͊̏̇̓̀̓̀Ņ̸͍͇̘̙̥̰͉̲͕͈̥̍͛̃̑͝Ḑ̵̤̻̖̱̘̯̝̖̈̌̄̕͝
|
||||
Ī̶̜̱̈́̑̃̉̄̋̔͐͋͠Ṅ̴͎̞͍̽͊͛̈́̅͛̈̅̚͠Ģ̸̢̾͊S̷̫̼̜̼͇̋͛̎͑͆̅̓̇</span>`,
|
||||
},
|
||||
|
@ -1014,10 +1014,10 @@ GameDatabase.news = [
|
|||
{
|
||||
id: "a186",
|
||||
text:
|
||||
`<span style='animation: text-shrink 1s infinite'>/(^_^)/</span> <span style='animation: text-grow 1s infinite
|
||||
'>\\(^_^)\\</span> <span style='animation: text-shrink 1s infinite'>/(^_^)/</span> <span style='animation:
|
||||
text-grow 1s infinite'>\\(^_^)\\</span> <span style='animation: text-shrink 1s infinite'>/(^_^)/</span> <span
|
||||
style='animation: text-grow 1s infinite'>\\(^_^)\\</span>`,
|
||||
`<span style='animation: a-text-shrink 1s infinite'>/(^_^)/</span> <span style='animation: a-text-grow 1s infinite
|
||||
'>\\(^_^)\\</span> <span style='animation: a-text-shrink 1s infinite'>/(^_^)/</span> <span style='animation:
|
||||
a-text-grow 1s infinite'>\\(^_^)\\</span> <span style='animation: a-text-shrink 1s infinite'>/(^_^)/</span> <span
|
||||
style='animation: a-text-grow 1s infinite'>\\(^_^)\\</span>`,
|
||||
},
|
||||
{
|
||||
id: "a187",
|
||||
|
@ -1083,7 +1083,7 @@ GameDatabase.news = [
|
|||
random *= 255;
|
||||
const color = `hsl(${random}, 90%, 60%)`;
|
||||
return `<span style='color: ${color}; text-shadow: 0 0 0.5rem ${color};
|
||||
animation: text-grow 0.4s infinite;'>Disco Time!</span>`;
|
||||
animation: a-text-grow 0.4s infinite;'>Disco Time!</span>`;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1352,8 +1352,8 @@ GameDatabase.news = [
|
|||
id: "a238",
|
||||
get text() {
|
||||
return `AD Player: "How many orders of magnitude are you on?" Normal person: "Like, maybe 5 or 6 right now, my
|
||||
dude." AD Player: "You are like a little baby. Watch this: <span style='animation: text-crunch ${newsAnimSpd(22)}s
|
||||
1; font-size: 0;'>C R O N C H</span>"`;
|
||||
dude." AD Player: "You are like a little baby. Watch this: <span style='animation: a-text-crunch
|
||||
${newsAnimSpd(22)}s 1; font-size: 0;'>C R O N C H</span>"`;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1441,7 +1441,7 @@ GameDatabase.news = [
|
|||
},
|
||||
{
|
||||
id: "a246",
|
||||
text: "<span style='animation: fade-out 3s infinite'>OoooOOOOooOOO, it's me, the infamous news ghost!</span>",
|
||||
text: "<span style='animation: a-fade-out 3s infinite'>OoooOOOOooOOO, it's me, the infamous news ghost!</span>",
|
||||
},
|
||||
(function() {
|
||||
let isFlipped = false;
|
||||
|
@ -1505,7 +1505,7 @@ GameDatabase.news = [
|
|||
{
|
||||
id: "a252",
|
||||
get text() {
|
||||
return `<span style='animation: text-stretch ${newsAnimSpd(30)}s 1'>This message is dilated.</span>`;
|
||||
return `<span style='animation: a-text-stretch ${newsAnimSpd(30)}s 1'>This message is dilated.</span>`;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2256,7 +2256,7 @@ GameDatabase.news = [
|
|||
{
|
||||
id: "a352",
|
||||
get text() {
|
||||
return `<span style='opacity: 0; animation: disappear ${newsAnimSpd(20)}s 1'>
|
||||
return `<span style='opacity: 0; animation: a-disappear ${newsAnimSpd(20)}s 1'>
|
||||
This news message is antimemetic. You will forget that it exists shortly.</span>`;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.reality.glyphSacrifice = [
|
||||
{
|
||||
GameDatabase.reality.glyphSacrifice = {
|
||||
"power": {
|
||||
id: "power",
|
||||
effect: added => {
|
||||
if (Pelle.isDisabled("glyphsac")) return 0;
|
||||
|
@ -19,7 +19,8 @@ GameDatabase.reality.glyphSacrifice = [
|
|||
: "";
|
||||
return `Distant Galaxy scaling starts ${formatInt(amount)} later${nextGalaxyText}`;
|
||||
}
|
||||
}, {
|
||||
},
|
||||
"infinity": {
|
||||
id: "infinity",
|
||||
effect: added => {
|
||||
if (Pelle.isDisabled("glyphsac")) return 1;
|
||||
|
@ -31,7 +32,8 @@ GameDatabase.reality.glyphSacrifice = [
|
|||
if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`;
|
||||
return `${formatX(amount, 2, 2)} bigger multiplier when buying 8th Infinity Dimension.`;
|
||||
}
|
||||
}, {
|
||||
},
|
||||
"time": {
|
||||
id: "time",
|
||||
effect: added => {
|
||||
if (Pelle.isDisabled("glyphsac")) return 1;
|
||||
|
@ -43,7 +45,8 @@ GameDatabase.reality.glyphSacrifice = [
|
|||
if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`;
|
||||
return `${formatX(amount, 2, 2)} bigger multiplier when buying 8th Time Dimension.`;
|
||||
}
|
||||
}, {
|
||||
},
|
||||
"replication": {
|
||||
id: "replication",
|
||||
effect: added => {
|
||||
if (Pelle.isDisabled("glyphsac")) return 0;
|
||||
|
@ -61,7 +64,8 @@ GameDatabase.reality.glyphSacrifice = [
|
|||
: "";
|
||||
return `Replicanti Galaxy scaling starts ${formatInt(amount)} later${nextGalaxyText}`;
|
||||
}
|
||||
}, {
|
||||
},
|
||||
"dilation": {
|
||||
id: "dilation",
|
||||
effect: added => {
|
||||
if (Pelle.isDisabled("glyphsac")) return 1;
|
||||
|
@ -75,7 +79,8 @@ GameDatabase.reality.glyphSacrifice = [
|
|||
if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`;
|
||||
return `Multiply Tachyon Particle gain by ${formatX(amount, 2, 2)}`;
|
||||
}
|
||||
}, {
|
||||
},
|
||||
"effarig": {
|
||||
id: "effarig",
|
||||
effect: added => {
|
||||
if (Pelle.isDisabled("glyphsac")) return 0;
|
||||
|
@ -87,7 +92,8 @@ GameDatabase.reality.glyphSacrifice = [
|
|||
if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`;
|
||||
return `+${formatPercents(amount / 100, 2)} additional Glyph rarity`;
|
||||
}
|
||||
}, {
|
||||
},
|
||||
"reality": {
|
||||
id: "reality",
|
||||
effect: added => {
|
||||
if (Pelle.isDisabled("glyphsac")) return 0;
|
||||
|
@ -99,4 +105,4 @@ GameDatabase.reality.glyphSacrifice = [
|
|||
return `${formatPercents(amount - 1, 2)} increased Alchemy yield`;
|
||||
}
|
||||
}
|
||||
].mapToObject(g => g.id, g => g);
|
||||
};
|
||||
|
|
|
@ -1,293 +1,292 @@
|
|||
import { DC } from "../../constants";
|
||||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.reality.imaginaryUpgrades = (function() {
|
||||
const rebuyable = props => {
|
||||
props.cost = () => props.initialCost * Math.pow(props.costMult, player.reality.imaginaryRebuyables[props.id]);
|
||||
const { effect } = props;
|
||||
if (props.isDecimal) props.effect = () => Decimal.pow(effect, player.reality.imaginaryRebuyables[props.id]);
|
||||
else props.effect = () => effect * player.reality.imaginaryRebuyables[props.id];
|
||||
if (!props.formatEffect) props.formatEffect = value => `+${format(value, 2, 2)}`;
|
||||
props.formatCost = value => format(value, 2, 0);
|
||||
return props;
|
||||
};
|
||||
return [
|
||||
rebuyable({
|
||||
name: "Temporal Intensifier",
|
||||
id: 1,
|
||||
initialCost: 3,
|
||||
costMult: 60,
|
||||
description: () => `Increase Temporal Amplifier multiplier by +${format(0.15, 2, 2)}`,
|
||||
effect: 0.15
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Replicative Intensifier",
|
||||
id: 2,
|
||||
initialCost: 4,
|
||||
costMult: 60,
|
||||
description: () => `Increase Replicative Amplifier multiplier by +${format(0.15, 2, 2)}`,
|
||||
effect: 0.15
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Eternal Intensifier",
|
||||
id: 3,
|
||||
initialCost: 1,
|
||||
costMult: 40,
|
||||
description: () => `Increase Eternal Amplifier multiplier by +${format(0.4, 2, 2)}`,
|
||||
effect: 0.4
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Superluminal Intensifier",
|
||||
id: 4,
|
||||
initialCost: 5,
|
||||
costMult: 80,
|
||||
description: () => `Increase Superluminal Amplifier multiplier by +${format(0.15, 2, 2)}`,
|
||||
effect: 0.15
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Boundless Intensifier",
|
||||
id: 5,
|
||||
initialCost: 1,
|
||||
costMult: 30,
|
||||
description: () => `Increase Boundless Amplifier multiplier by +${format(0.6, 2, 2)}`,
|
||||
effect: 0.6
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Elliptic Materiality",
|
||||
id: 6,
|
||||
initialCost: 1e4,
|
||||
costMult: 500,
|
||||
description: () => `Increase the Reality Machine cap by ${formatX(1e100)}`,
|
||||
effect: 1e100,
|
||||
formatEffect: value => `${formatX(value)}`,
|
||||
isDecimal: true
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Runic Assurance",
|
||||
id: 7,
|
||||
initialCost: 2e5,
|
||||
costMult: 500,
|
||||
description: () => `Delay Glyph Instability starting level by ${formatInt(200)}`,
|
||||
effect: 200,
|
||||
formatEffect: value => `+${formatInt(value)} levels`
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Hyperbolic Apeirogon",
|
||||
id: 8,
|
||||
initialCost: 1e7,
|
||||
costMult: 800,
|
||||
description: () => `Multiply Infinity Dimensions by ${format("1e100000")}`,
|
||||
effect: DC.E100000,
|
||||
formatEffect: value => `${formatX(value)}`,
|
||||
isDecimal: true
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Cosmic Filament",
|
||||
id: 9,
|
||||
initialCost: 1e9,
|
||||
costMult: 1000,
|
||||
description: () => `Increase Galaxy strength`,
|
||||
effect: 0.03,
|
||||
formatEffect: value => `+${formatPercents(value)}`
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Entropic Condensing",
|
||||
id: 10,
|
||||
initialCost: 8e9,
|
||||
costMult: 2000,
|
||||
description: () => `Increase Singularity gain`,
|
||||
effect: 1,
|
||||
formatEffect: value => `${formatX(1 + value, 2)}`,
|
||||
}),
|
||||
{
|
||||
name: "Suspicion of Interference",
|
||||
id: 11,
|
||||
cost: 5e7,
|
||||
requirement: () => `${format(1e90)} total Relic Shards
|
||||
(You have ${format(player.celestials.effarig.relicShards, 2)})`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => player.celestials.effarig.relicShards >= 1e90,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_AFTER,
|
||||
description: "Time Dimension power based on total antimatter",
|
||||
effect: () => 1 + Math.log10(player.records.totalAntimatter.log10()) / 100,
|
||||
formatEffect: value => `${formatPow(value, 0, 4)}`,
|
||||
},
|
||||
{
|
||||
name: "Consequences of Illusions",
|
||||
id: 12,
|
||||
cost: 5e7,
|
||||
requirement: () => `Make a level ${formatInt(9000)} Glyph with a single Glyph level factor weight at
|
||||
${formatInt(100)}`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Object.values(player.celestials.effarig.glyphWeights).some(w => w === 100) &&
|
||||
gainedGlyphLevel().actualLevel >= 9000,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Gain free Dimboosts based on Imaginary rebuyable count",
|
||||
effect: () => 2e4 * ImaginaryUpgrades.totalRebuyables,
|
||||
formatEffect: value => `${format(value, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Transience of Information",
|
||||
id: 13,
|
||||
cost: 5e7,
|
||||
requirement: () => `Reach ${format(Number.MAX_VALUE, 2)} projected Reality Machines within
|
||||
The Enslaved Ones' Reality`,
|
||||
hasFailed: () => !Enslaved.isRunning,
|
||||
checkRequirement: () => Enslaved.isRunning && MachineHandler.uncappedRM.gte(Number.MAX_VALUE),
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Increase Imaginary Machine Cap based on Imaginary Upgrades purchased",
|
||||
effect: () => 1 + ImaginaryUpgrades.totalRebuyables / 20 + ImaginaryUpgrades.totalSinglePurchase / 2,
|
||||
formatEffect: value => `${formatX(value, 2, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Recollection of Intrusion",
|
||||
id: 14,
|
||||
cost: 3.5e8,
|
||||
requirement: () => `Reach a tickspeed of ${format("1e75000000000")} / sec within Eternity Challenge 5`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => EternityChallenge(5).isRunning && Tickspeed.perSecond.exponent >= 7.5e10,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Raise all Dimension per-purchase multipliers to ${formatPow(1.5, 0, 1)}`,
|
||||
effect: 1.5
|
||||
},
|
||||
{
|
||||
name: "Fabrication of Ideals",
|
||||
id: 15,
|
||||
cost: 1e9,
|
||||
requirement: () => `Reach ${format("1e1500000000000")} antimatter without
|
||||
ever having any 1st Infinity Dimensions`,
|
||||
hasFailed: () => player.requirementChecks.reality.maxID1.gt(0),
|
||||
checkRequirement: () => player.requirementChecks.reality.maxID1.eq(0) && player.antimatter.exponent >= 1.5e12,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Convert Antimatter Dimensions to Continuum and unlock Lai'tela, Celestial of Dimensions",
|
||||
},
|
||||
{
|
||||
name: "Massless Momentum",
|
||||
id: 16,
|
||||
cost: 3.5e9,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Destabilize Lai'tela's Reality in under ${formatInt(30)} seconds twice`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Laitela.maxAllowedDimension <= 6,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock the 2nd Dark Matter Dimension",
|
||||
},
|
||||
{
|
||||
name: "Chiral Oscillation",
|
||||
id: 17,
|
||||
cost: 6e9,
|
||||
requirement: () => `Automatically condense at least ${formatInt(20)} Singularities at once`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Singularity.singularitiesGained >= 20 &&
|
||||
Currency.darkEnergy.gte(Singularity.cap * SingularityMilestone.autoCondense.effectValue),
|
||||
checkEvent: GAME_EVENT.SINGULARITY_RESET_BEFORE,
|
||||
description: "Unlock the 3rd Dark Matter Dimension",
|
||||
},
|
||||
{
|
||||
name: "Dimensional Symmetry",
|
||||
id: 18,
|
||||
cost: 1.5e10,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Have ${formatInt(80000)} total Galaxies`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Replicanti.galaxies.total + player.galaxies +
|
||||
player.dilation.totalTachyonGalaxies >= 80000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock the 4th Dark Matter Dimension",
|
||||
},
|
||||
{
|
||||
name: "Deterministic Radiation",
|
||||
id: 19,
|
||||
cost: 2.8e10,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Reach ${formatInt(3.85e6)} Tickspeed Continuum without ever having more than
|
||||
${formatInt(8)} Time Studies in this Reality`,
|
||||
hasFailed: () => player.requirementChecks.reality.maxStudies > 8,
|
||||
checkRequirement: () => player.requirementChecks.reality.maxStudies <= 8 &&
|
||||
Tickspeed.continuumValue >= 3.85e6,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock Dark Matter Annihilation",
|
||||
},
|
||||
{
|
||||
name: "Vacuum Acceleration",
|
||||
id: 20,
|
||||
cost: 3e12,
|
||||
requirement: () => `Have a Continuum increase of at least ${formatPercents(1)}`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Laitela.matterExtraPurchaseFactor >= 2,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Unlock Autobuyers for repeatable Imaginary Upgrades and generate Imaginary Machines
|
||||
${formatInt(10)} times faster`,
|
||||
effect: 10,
|
||||
},
|
||||
{
|
||||
name: "Existential Elimination",
|
||||
id: 21,
|
||||
cost: 1e13,
|
||||
requirement: () => `Reach ${format("1e7400000000000")} antimatter with Continuum disabled`,
|
||||
hasFailed: () => !player.requirementChecks.reality.noContinuum,
|
||||
checkRequirement: () => player.requirementChecks.reality.noContinuum &&
|
||||
Currency.antimatter.value.log10() >= 7.4e12,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Annihilation multiplier gain is improved based on Imaginary Machines",
|
||||
effect: () => Math.clampMin(Math.pow(Math.log10(Currency.imaginaryMachines.value) - 10, 3), 1),
|
||||
formatEffect: value => `${formatX(value, 2, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Total Termination",
|
||||
id: 22,
|
||||
cost: 1.5e14,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Reach ${format("1e150000000000")} antimatter in Effarig's Reality with
|
||||
at least ${formatInt(4)} Cursed Glyphs equipped`,
|
||||
// Note: 4 cursed glyphs is -12 glyph count, but equipping a positive glyph in the last slot is allowed
|
||||
hasFailed: () => !Effarig.isRunning || player.requirementChecks.reality.maxGlyphs > -10,
|
||||
checkRequirement: () => Effarig.isRunning && player.requirementChecks.reality.maxGlyphs < -10 &&
|
||||
Currency.antimatter.value.exponent >= 1.5e11,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Glyph Sacrifice totals for basic Glyphs are increased to ${format(1e100)}`,
|
||||
effect: 1e100,
|
||||
},
|
||||
{
|
||||
name: "Planar Purification",
|
||||
id: 23,
|
||||
cost: 6e14,
|
||||
requirement: () => `Reach Glyph level ${formatInt(20000)} in Ra's Reality with
|
||||
at most ${formatInt(0)} Glyphs equipped`,
|
||||
hasFailed: () => !Ra.isRunning || player.requirementChecks.reality.maxGlyphs > 0,
|
||||
checkRequirement: () => Ra.isRunning && player.requirementChecks.reality.maxGlyphs <= 0 &&
|
||||
gainedGlyphLevel().actualLevel >= 20000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Increase free Dimboost count based on Tesseract count",
|
||||
effect: () => Math.floor(0.25 * Math.pow(Tesseracts.effectiveCount, 2)),
|
||||
formatEffect: value => `${formatX(value)}`,
|
||||
},
|
||||
{
|
||||
name: "Absolute Annulment",
|
||||
id: 24,
|
||||
cost: 6e14,
|
||||
requirement: () => `Have ${formatInt(13000)} Antimatter Galaxies in Ra's Reality
|
||||
with a fully inverted Black Hole`,
|
||||
hasFailed: () => !Ra.isRunning || player.requirementChecks.reality.slowestBH > 1e-300,
|
||||
checkRequirement: () => Ra.isRunning && player.requirementChecks.reality.slowestBH <= 1e-300 &&
|
||||
player.galaxies >= 13000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Increase free Dimboost strength based on Singularity count",
|
||||
effect: () => Decimal.pow(player.celestials.laitela.singularities, 300),
|
||||
formatEffect: value => `${formatX(value, 2, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Omnipresent Obliteration",
|
||||
id: 25,
|
||||
cost: 1.6e15,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Reach Reality in Lai'tela's Reality with all Dimensions disabled and
|
||||
at least ${formatInt(4)} empty Glyph slots`,
|
||||
hasFailed: () => !Laitela.isRunning || Laitela.maxAllowedDimension !== 0 || Glyphs.activeList.length > 1,
|
||||
checkRequirement: () => Laitela.isRunning && Laitela.maxAllowedDimension === 0 &&
|
||||
Glyphs.activeList.length <= 1,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Unlock Pelle, Celestial of Antimatter",
|
||||
},
|
||||
];
|
||||
}());
|
||||
const rebuyable = props => {
|
||||
props.cost = () => props.initialCost * Math.pow(props.costMult, player.reality.imaginaryRebuyables[props.id]);
|
||||
const { effect } = props;
|
||||
if (props.isDecimal) props.effect = () => Decimal.pow(effect, player.reality.imaginaryRebuyables[props.id]);
|
||||
else props.effect = () => effect * player.reality.imaginaryRebuyables[props.id];
|
||||
if (!props.formatEffect) props.formatEffect = value => `+${format(value, 2, 2)}`;
|
||||
props.formatCost = value => format(value, 2, 0);
|
||||
return props;
|
||||
};
|
||||
|
||||
GameDatabase.reality.imaginaryUpgrades = [
|
||||
rebuyable({
|
||||
name: "Temporal Intensifier",
|
||||
id: 1,
|
||||
initialCost: 3,
|
||||
costMult: 60,
|
||||
description: () => `Increase Temporal Amplifier multiplier by +${format(0.15, 2, 2)}`,
|
||||
effect: 0.15
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Replicative Intensifier",
|
||||
id: 2,
|
||||
initialCost: 4,
|
||||
costMult: 60,
|
||||
description: () => `Increase Replicative Amplifier multiplier by +${format(0.15, 2, 2)}`,
|
||||
effect: 0.15
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Eternal Intensifier",
|
||||
id: 3,
|
||||
initialCost: 1,
|
||||
costMult: 40,
|
||||
description: () => `Increase Eternal Amplifier multiplier by +${format(0.4, 2, 2)}`,
|
||||
effect: 0.4
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Superluminal Intensifier",
|
||||
id: 4,
|
||||
initialCost: 5,
|
||||
costMult: 80,
|
||||
description: () => `Increase Superluminal Amplifier multiplier by +${format(0.15, 2, 2)}`,
|
||||
effect: 0.15
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Boundless Intensifier",
|
||||
id: 5,
|
||||
initialCost: 1,
|
||||
costMult: 30,
|
||||
description: () => `Increase Boundless Amplifier multiplier by +${format(0.6, 2, 2)}`,
|
||||
effect: 0.6
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Elliptic Materiality",
|
||||
id: 6,
|
||||
initialCost: 1e4,
|
||||
costMult: 500,
|
||||
description: () => `Increase the Reality Machine cap by ${formatX(1e100)}`,
|
||||
effect: 1e100,
|
||||
formatEffect: value => `${formatX(value)}`,
|
||||
isDecimal: true
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Runic Assurance",
|
||||
id: 7,
|
||||
initialCost: 2e5,
|
||||
costMult: 500,
|
||||
description: () => `Delay Glyph Instability starting level by ${formatInt(200)}`,
|
||||
effect: 200,
|
||||
formatEffect: value => `+${formatInt(value)} levels`
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Hyperbolic Apeirogon",
|
||||
id: 8,
|
||||
initialCost: 1e7,
|
||||
costMult: 800,
|
||||
description: () => `Multiply Infinity Dimensions by ${format("1e100000")}`,
|
||||
effect: DC.E100000,
|
||||
formatEffect: value => `${formatX(value)}`,
|
||||
isDecimal: true
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Cosmic Filament",
|
||||
id: 9,
|
||||
initialCost: 1e9,
|
||||
costMult: 1000,
|
||||
description: () => `Increase Galaxy strength`,
|
||||
effect: 0.03,
|
||||
formatEffect: value => `+${formatPercents(value)}`
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Entropic Condensing",
|
||||
id: 10,
|
||||
initialCost: 8e9,
|
||||
costMult: 2000,
|
||||
description: () => `Increase Singularity gain`,
|
||||
effect: 1,
|
||||
formatEffect: value => `${formatX(1 + value, 2)}`,
|
||||
}),
|
||||
{
|
||||
name: "Suspicion of Interference",
|
||||
id: 11,
|
||||
cost: 5e7,
|
||||
requirement: () => `${format(1e90)} total Relic Shards
|
||||
(You have ${format(player.celestials.effarig.relicShards, 2)})`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => player.celestials.effarig.relicShards >= 1e90,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_AFTER,
|
||||
description: "Time Dimension power based on total antimatter",
|
||||
effect: () => 1 + Math.log10(player.records.totalAntimatter.log10()) / 100,
|
||||
formatEffect: value => `${formatPow(value, 0, 4)}`,
|
||||
},
|
||||
{
|
||||
name: "Consequences of Illusions",
|
||||
id: 12,
|
||||
cost: 5e7,
|
||||
requirement: () => `Make a level ${formatInt(9000)} Glyph with a single Glyph level factor weight at
|
||||
${formatInt(100)}`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Object.values(player.celestials.effarig.glyphWeights).some(w => w === 100) &&
|
||||
gainedGlyphLevel().actualLevel >= 9000,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Gain free Dimboosts based on Imaginary rebuyable count",
|
||||
effect: () => 2e4 * ImaginaryUpgrades.totalRebuyables,
|
||||
formatEffect: value => `${format(value, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Transience of Information",
|
||||
id: 13,
|
||||
cost: 5e7,
|
||||
requirement: () => `Reach ${format(Number.MAX_VALUE, 2)} projected Reality Machines within
|
||||
The Enslaved Ones' Reality`,
|
||||
hasFailed: () => !Enslaved.isRunning,
|
||||
checkRequirement: () => Enslaved.isRunning && MachineHandler.uncappedRM.gte(Number.MAX_VALUE),
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Increase Imaginary Machine Cap based on Imaginary Upgrades purchased",
|
||||
effect: () => 1 + ImaginaryUpgrades.totalRebuyables / 20 + ImaginaryUpgrades.totalSinglePurchase / 2,
|
||||
formatEffect: value => `${formatX(value, 2, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Recollection of Intrusion",
|
||||
id: 14,
|
||||
cost: 3.5e8,
|
||||
requirement: () => `Reach a tickspeed of ${format("1e75000000000")} / sec within Eternity Challenge 5`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => EternityChallenge(5).isRunning && Tickspeed.perSecond.exponent >= 7.5e10,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Raise all Dimension per-purchase multipliers to ${formatPow(1.5, 0, 1)}`,
|
||||
effect: 1.5
|
||||
},
|
||||
{
|
||||
name: "Fabrication of Ideals",
|
||||
id: 15,
|
||||
cost: 1e9,
|
||||
requirement: () => `Reach ${format("1e1500000000000")} antimatter without
|
||||
ever having any 1st Infinity Dimensions`,
|
||||
hasFailed: () => player.requirementChecks.reality.maxID1.gt(0),
|
||||
checkRequirement: () => player.requirementChecks.reality.maxID1.eq(0) && player.antimatter.exponent >= 1.5e12,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Convert Antimatter Dimensions to Continuum and unlock Lai'tela, Celestial of Dimensions",
|
||||
},
|
||||
{
|
||||
name: "Massless Momentum",
|
||||
id: 16,
|
||||
cost: 3.5e9,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Destabilize Lai'tela's Reality in under ${formatInt(30)} seconds twice`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Laitela.maxAllowedDimension <= 6,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock the 2nd Dark Matter Dimension",
|
||||
},
|
||||
{
|
||||
name: "Chiral Oscillation",
|
||||
id: 17,
|
||||
cost: 6e9,
|
||||
requirement: () => `Automatically condense at least ${formatInt(20)} Singularities at once`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Singularity.singularitiesGained >= 20 &&
|
||||
Currency.darkEnergy.gte(Singularity.cap * SingularityMilestone.autoCondense.effectValue),
|
||||
checkEvent: GAME_EVENT.SINGULARITY_RESET_BEFORE,
|
||||
description: "Unlock the 3rd Dark Matter Dimension",
|
||||
},
|
||||
{
|
||||
name: "Dimensional Symmetry",
|
||||
id: 18,
|
||||
cost: 1.5e10,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Have ${formatInt(80000)} total Galaxies`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Replicanti.galaxies.total + player.galaxies +
|
||||
player.dilation.totalTachyonGalaxies >= 80000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock the 4th Dark Matter Dimension",
|
||||
},
|
||||
{
|
||||
name: "Deterministic Radiation",
|
||||
id: 19,
|
||||
cost: 2.8e10,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Reach ${formatInt(3.85e6)} Tickspeed Continuum without ever having more than
|
||||
${formatInt(8)} Time Studies in this Reality`,
|
||||
hasFailed: () => player.requirementChecks.reality.maxStudies > 8,
|
||||
checkRequirement: () => player.requirementChecks.reality.maxStudies <= 8 &&
|
||||
Tickspeed.continuumValue >= 3.85e6,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock Dark Matter Annihilation",
|
||||
},
|
||||
{
|
||||
name: "Vacuum Acceleration",
|
||||
id: 20,
|
||||
cost: 3e12,
|
||||
requirement: () => `Have a Continuum increase of at least ${formatPercents(1)}`,
|
||||
hasFailed: () => false,
|
||||
checkRequirement: () => Laitela.matterExtraPurchaseFactor >= 2,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Unlock Autobuyers for repeatable Imaginary Upgrades and generate Imaginary Machines
|
||||
${formatInt(10)} times faster`,
|
||||
effect: 10,
|
||||
},
|
||||
{
|
||||
name: "Existential Elimination",
|
||||
id: 21,
|
||||
cost: 1e13,
|
||||
requirement: () => `Reach ${format("1e7400000000000")} antimatter with Continuum disabled`,
|
||||
hasFailed: () => !player.requirementChecks.reality.noContinuum,
|
||||
checkRequirement: () => player.requirementChecks.reality.noContinuum &&
|
||||
Currency.antimatter.value.log10() >= 7.4e12,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Annihilation multiplier gain is improved based on Imaginary Machines",
|
||||
effect: () => Math.clampMin(Math.pow(Math.log10(Currency.imaginaryMachines.value) - 10, 3), 1),
|
||||
formatEffect: value => `${formatX(value, 2, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Total Termination",
|
||||
id: 22,
|
||||
cost: 1.5e14,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Reach ${format("1e150000000000")} antimatter in Effarig's Reality with
|
||||
at least ${formatInt(4)} Cursed Glyphs equipped`,
|
||||
// Note: 4 cursed glyphs is -12 glyph count, but equipping a positive glyph in the last slot is allowed
|
||||
hasFailed: () => !Effarig.isRunning || player.requirementChecks.reality.maxGlyphs > -10,
|
||||
checkRequirement: () => Effarig.isRunning && player.requirementChecks.reality.maxGlyphs < -10 &&
|
||||
Currency.antimatter.value.exponent >= 1.5e11,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Glyph Sacrifice totals for basic Glyphs are increased to ${format(1e100)}`,
|
||||
effect: 1e100,
|
||||
},
|
||||
{
|
||||
name: "Planar Purification",
|
||||
id: 23,
|
||||
cost: 6e14,
|
||||
requirement: () => `Reach Glyph level ${formatInt(20000)} in Ra's Reality with
|
||||
at most ${formatInt(0)} Glyphs equipped`,
|
||||
hasFailed: () => !Ra.isRunning || player.requirementChecks.reality.maxGlyphs > 0,
|
||||
checkRequirement: () => Ra.isRunning && player.requirementChecks.reality.maxGlyphs <= 0 &&
|
||||
gainedGlyphLevel().actualLevel >= 20000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Increase free Dimboost count based on Tesseract count",
|
||||
effect: () => Math.floor(0.25 * Math.pow(Tesseracts.effectiveCount, 2)),
|
||||
formatEffect: value => `${formatX(value)}`,
|
||||
},
|
||||
{
|
||||
name: "Absolute Annulment",
|
||||
id: 24,
|
||||
cost: 6e14,
|
||||
requirement: () => `Have ${formatInt(13000)} Antimatter Galaxies in Ra's Reality
|
||||
with a fully inverted Black Hole`,
|
||||
hasFailed: () => !Ra.isRunning || player.requirementChecks.reality.slowestBH > 1e-300,
|
||||
checkRequirement: () => Ra.isRunning && player.requirementChecks.reality.slowestBH <= 1e-300 &&
|
||||
player.galaxies >= 13000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Increase free Dimboost strength based on Singularity count",
|
||||
effect: () => Decimal.pow(player.celestials.laitela.singularities, 300),
|
||||
formatEffect: value => `${formatX(value, 2, 1)}`,
|
||||
},
|
||||
{
|
||||
name: "Omnipresent Obliteration",
|
||||
id: 25,
|
||||
cost: 1.6e15,
|
||||
formatCost: x => format(x, 1),
|
||||
requirement: () => `Reach Reality in Lai'tela's Reality with all Dimensions disabled and
|
||||
at least ${formatInt(4)} empty Glyph slots`,
|
||||
hasFailed: () => !Laitela.isRunning || Laitela.maxAllowedDimension !== 0 || Glyphs.activeList.length > 1,
|
||||
checkRequirement: () => Laitela.isRunning && Laitela.maxAllowedDimension === 0 &&
|
||||
Glyphs.activeList.length <= 1,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Unlock Pelle, Celestial of Antimatter",
|
||||
},
|
||||
];
|
||||
|
|
|
@ -1,345 +1,345 @@
|
|||
import { DC } from "../../constants";
|
||||
import { GameDatabase } from "../game-database";
|
||||
|
||||
GameDatabase.reality.upgrades = (function() {
|
||||
const rebuyable = props => {
|
||||
props.cost = () => getHybridCostScaling(
|
||||
player.reality.rebuyables[props.id],
|
||||
1e30,
|
||||
props.initialCost,
|
||||
props.costMult,
|
||||
props.costMult / 10,
|
||||
DC.E309,
|
||||
1e3,
|
||||
props.initialCost * props.costMult
|
||||
);
|
||||
const { effect } = props;
|
||||
props.effect = () => Math.pow(
|
||||
effect + ImaginaryUpgrade(props.id).effectOrDefault(0),
|
||||
player.reality.rebuyables[props.id] * getAdjustedGlyphEffect("realityrow1pow"));
|
||||
props.description = () => props.textTemplate.replace("{value}",
|
||||
ImaginaryUpgrade(props.id).effectValue === 0
|
||||
? formatInt(effect)
|
||||
: format(effect + ImaginaryUpgrade(props.id).effectValue, 2, 2));
|
||||
props.formatEffect = value => formatX(value, 2, 0);
|
||||
props.formatCost = value => format(value, 2, 0);
|
||||
return props;
|
||||
};
|
||||
return [
|
||||
rebuyable({
|
||||
name: "Temporal Amplifier",
|
||||
id: 1,
|
||||
initialCost: 1,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain Dilated Time {value} times faster",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Replicative Amplifier",
|
||||
id: 2,
|
||||
initialCost: 1,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain Replicanti {value} times faster",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Eternal Amplifier",
|
||||
id: 3,
|
||||
initialCost: 2,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain {value} times more Eternities",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Superluminal Amplifier",
|
||||
id: 4,
|
||||
initialCost: 2,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain {value} times more Tachyon Particles",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Boundless Amplifier",
|
||||
id: 5,
|
||||
initialCost: 3,
|
||||
costMult: 50,
|
||||
textTemplate: "You gain {value} times more Infinities",
|
||||
effect: 5
|
||||
}),
|
||||
{
|
||||
name: "Cosmically Duplicate",
|
||||
id: 6,
|
||||
cost: 15,
|
||||
requirement: "Complete your first Eternity without using Replicanti Galaxies",
|
||||
// Note that while noRG resets on eternity, the reality-level check will be false after the first eternity.
|
||||
// The noRG variable is eternity-level as it's also used for an achievement check
|
||||
hasFailed: () => !(player.requirementChecks.eternity.noRG && player.requirementChecks.reality.noEternities),
|
||||
checkRequirement: () => player.requirementChecks.eternity.noRG && player.requirementChecks.reality.noEternities,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
|
||||
description: "Replicanti speed is multiplied based on Replicanti Galaxies",
|
||||
effect: () => 1 + Replicanti.galaxies.total / 50,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
const rebuyable = props => {
|
||||
props.cost = () => getHybridCostScaling(
|
||||
player.reality.rebuyables[props.id],
|
||||
1e30,
|
||||
props.initialCost,
|
||||
props.costMult,
|
||||
props.costMult / 10,
|
||||
DC.E309,
|
||||
1e3,
|
||||
props.initialCost * props.costMult
|
||||
);
|
||||
const { effect } = props;
|
||||
props.effect = () => Math.pow(
|
||||
effect + ImaginaryUpgrade(props.id).effectOrDefault(0),
|
||||
player.reality.rebuyables[props.id] * getAdjustedGlyphEffect("realityrow1pow"));
|
||||
props.description = () => props.textTemplate.replace("{value}",
|
||||
ImaginaryUpgrade(props.id).effectValue === 0
|
||||
? formatInt(effect)
|
||||
: format(effect + ImaginaryUpgrade(props.id).effectValue, 2, 2));
|
||||
props.formatEffect = value => formatX(value, 2, 0);
|
||||
props.formatCost = value => format(value, 2, 0);
|
||||
return props;
|
||||
};
|
||||
|
||||
|
||||
GameDatabase.reality.upgrades = [
|
||||
rebuyable({
|
||||
name: "Temporal Amplifier",
|
||||
id: 1,
|
||||
initialCost: 1,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain Dilated Time {value} times faster",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Replicative Amplifier",
|
||||
id: 2,
|
||||
initialCost: 1,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain Replicanti {value} times faster",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Eternal Amplifier",
|
||||
id: 3,
|
||||
initialCost: 2,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain {value} times more Eternities",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Superluminal Amplifier",
|
||||
id: 4,
|
||||
initialCost: 2,
|
||||
costMult: 30,
|
||||
textTemplate: "You gain {value} times more Tachyon Particles",
|
||||
effect: 3
|
||||
}),
|
||||
rebuyable({
|
||||
name: "Boundless Amplifier",
|
||||
id: 5,
|
||||
initialCost: 3,
|
||||
costMult: 50,
|
||||
textTemplate: "You gain {value} times more Infinities",
|
||||
effect: 5
|
||||
}),
|
||||
{
|
||||
name: "Cosmically Duplicate",
|
||||
id: 6,
|
||||
cost: 15,
|
||||
requirement: "Complete your first Eternity without using Replicanti Galaxies",
|
||||
// Note that while noRG resets on eternity, the reality-level check will be false after the first eternity.
|
||||
// The noRG variable is eternity-level as it's also used for an achievement check
|
||||
hasFailed: () => !(player.requirementChecks.eternity.noRG && player.requirementChecks.reality.noEternities),
|
||||
checkRequirement: () => player.requirementChecks.eternity.noRG && player.requirementChecks.reality.noEternities,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
|
||||
description: "Replicanti speed is multiplied based on Replicanti Galaxies",
|
||||
effect: () => 1 + Replicanti.galaxies.total / 50,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Innumerably Construct",
|
||||
id: 7,
|
||||
cost: 15,
|
||||
requirement: "Complete your first Infinity with at most 1 Antimatter Galaxy",
|
||||
hasFailed: () => !(player.galaxies <= 1 && player.requirementChecks.reality.noInfinities),
|
||||
checkRequirement: () => player.galaxies <= 1 && player.requirementChecks.reality.noInfinities,
|
||||
checkEvent: GAME_EVENT.BIG_CRUNCH_BEFORE,
|
||||
description: "Infinity gain is boosted from Antimatter Galaxy count",
|
||||
effect: () => 1 + player.galaxies / 30,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Paradoxically Attain",
|
||||
id: 8,
|
||||
cost: 15,
|
||||
requirement: "Get to Eternity without any automatic Achievements",
|
||||
hasFailed: () => player.reality.gainedAutoAchievements,
|
||||
checkRequirement: () => !player.reality.gainedAutoAchievements,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
|
||||
description: "Tachyon Particle gain is boosted based on Achievement multiplier",
|
||||
effect: () => Math.sqrt(Achievements.power),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Linguistically Expand",
|
||||
id: 9,
|
||||
cost: 15,
|
||||
requirement: () => `Eternity for ${format("1e4000")} Eternity Points using
|
||||
only a single level ${formatInt(3)}+ Glyph.`,
|
||||
hasFailed: () => {
|
||||
const invalidEquippedGlyphs = Glyphs.activeList.length > 1 ||
|
||||
(Glyphs.activeList.length === 1 && Glyphs.activeList[0].level < 3);
|
||||
const hasValidGlyphInInventory = Glyphs.inventory.countWhere(g => g && g.level >= 3) > 0;
|
||||
return invalidEquippedGlyphs || (Glyphs.activeList.length === 0 && !hasValidGlyphInInventory);
|
||||
},
|
||||
{
|
||||
name: "Innumerably Construct",
|
||||
id: 7,
|
||||
cost: 15,
|
||||
requirement: "Complete your first Infinity with at most 1 Antimatter Galaxy",
|
||||
hasFailed: () => !(player.galaxies <= 1 && player.requirementChecks.reality.noInfinities),
|
||||
checkRequirement: () => player.galaxies <= 1 && player.requirementChecks.reality.noInfinities,
|
||||
checkEvent: GAME_EVENT.BIG_CRUNCH_BEFORE,
|
||||
description: "Infinity gain is boosted from Antimatter Galaxy count",
|
||||
effect: () => 1 + player.galaxies / 30,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 4000 &&
|
||||
Glyphs.activeList.length === 1 && Glyphs.activeList[0].level >= 3,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: "Gain another Glyph slot",
|
||||
effect: () => 1
|
||||
},
|
||||
{
|
||||
name: "Existentially Prolong",
|
||||
id: 10,
|
||||
cost: 15,
|
||||
requirement: () => `Complete your first Eternity with at least ${formatPostBreak(DC.E450)} Infinity Points`,
|
||||
hasFailed: () => !player.requirementChecks.reality.noEternities,
|
||||
checkRequirement: () => Currency.infinityPoints.exponent >= 450 &&
|
||||
player.requirementChecks.reality.noEternities,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
|
||||
description: () => `Start every Reality with ${formatInt(100)} Eternities (also applies to current Reality)`,
|
||||
automatorPoints: 15,
|
||||
shortDescription: () => `Start with ${formatInt(100)} Eternities`,
|
||||
effect: () => 100
|
||||
},
|
||||
{
|
||||
name: "The Boundless Flow",
|
||||
id: 11,
|
||||
cost: 50,
|
||||
requirement: () => `${format(Currency.infinitiesBanked.value, 2)}/${format(DC.E12)} Banked Infinities`,
|
||||
checkRequirement: () => Currency.infinitiesBanked.exponent >= 12,
|
||||
checkEvent: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.REALITY_FIRST_UNLOCKED],
|
||||
description: "Every second, gain 10% of the Infinities you would normally gain by Infinitying",
|
||||
automatorPoints: 5,
|
||||
shortDescription: () => `Continuous Infinity generation`,
|
||||
effect: () => gainedInfinities().times(0.1),
|
||||
formatEffect: value => `${format(value)} per second`
|
||||
},
|
||||
{
|
||||
name: "The Knowing Existence",
|
||||
id: 12,
|
||||
cost: 50,
|
||||
requirement: () => `Eternity for ${format(DC.E70)} Eternity Points without Eternity Challenge 1`,
|
||||
hasFailed: () => EternityChallenge(1).completions !== 0,
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 70 && EternityChallenge(1).completions === 0,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: "Eternity Point multiplier based on Reality and Time Theorem count",
|
||||
effect: () => Currency.timeTheorems.value
|
||||
.minus(DC.E3).clampMin(2)
|
||||
.pow(Math.log2(Math.min(Currency.realities.value, 1e4))).clampMin(1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "The Telemechanical Process",
|
||||
id: 13,
|
||||
cost: 50,
|
||||
requirement: () => `Eternity for ${format(DC.E4000)} Eternity Points without Time Dimensions 5-8`,
|
||||
hasFailed: () => !Array.range(5, 4).every(i => TimeDimension(i).amount.equals(0)),
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 4000 &&
|
||||
Array.range(5, 4).every(i => TimeDimension(i).amount.equals(0)),
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: () => `Unlock Time Dimension, ${formatX(5)} Eternity Point multiplier,
|
||||
and improved Eternity autobuyers`,
|
||||
automatorPoints: 10,
|
||||
shortDescription: () => `TD and ${formatX(5)} EP Autobuyers, improved Eternity Autobuyer`,
|
||||
},
|
||||
{
|
||||
name: "The Eternal Flow",
|
||||
id: 14,
|
||||
cost: 50,
|
||||
requirement: () => `${format(Currency.eternities.value, 2)}/${format(1e7)} Eternities`,
|
||||
checkRequirement: () => Currency.eternities.gte(1e7),
|
||||
checkEvent: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.REALITY_FIRST_UNLOCKED],
|
||||
description: "Gain Eternities per second equal to your Reality count",
|
||||
automatorPoints: 5,
|
||||
shortDescription: () => `Continuous Eternity generation`,
|
||||
effect: () => Currency.realities.value * Ra.unlocks.continuousTTBoost.effects.eternity.effectOrDefault(1),
|
||||
formatEffect: value => `${format(value)} per second`
|
||||
},
|
||||
{
|
||||
name: "The Paradoxical Forever",
|
||||
id: 15,
|
||||
cost: 50,
|
||||
requirement: () => `Have ${format(DC.E10)} Eternity Points without purchasing
|
||||
the ${formatX(5)} Eternity Point upgrade`,
|
||||
hasFailed: () => player.epmultUpgrades !== 0,
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 10 && player.epmultUpgrades === 0,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: () => `Boost Tachyon Particle gain based on ${formatX(5)} Eternity Point multiplier`,
|
||||
effect: () => Math.max(Math.sqrt(Decimal.log10(EternityUpgrade.epMult.effectValue)) / 3, 1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Disparity of Rarity",
|
||||
id: 16,
|
||||
cost: 1500,
|
||||
requirement: () => `Reality with ${formatInt(4)} Glyphs equipped of uncommon or better rarity
|
||||
(${formatInt(Glyphs.activeList.countWhere(g => g && g.strength >= 1.5))} equipped)`,
|
||||
hasFailed: () => {
|
||||
const availableGlyphs = Glyphs.inventory.countWhere(g => g && g.strength >= 1.5);
|
||||
const equipped = Glyphs.activeList.countWhere(g => g.strength >= 1.5);
|
||||
const availableSlots = Glyphs.activeSlotCount - Glyphs.activeList.length;
|
||||
return equipped + Math.min(availableGlyphs, availableSlots) < 4;
|
||||
},
|
||||
{
|
||||
name: "Paradoxically Attain",
|
||||
id: 8,
|
||||
cost: 15,
|
||||
requirement: "Get to Eternity without any automatic Achievements",
|
||||
hasFailed: () => player.reality.gainedAutoAchievements,
|
||||
checkRequirement: () => !player.reality.gainedAutoAchievements,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
|
||||
description: "Tachyon Particle gain is boosted based on Achievement multiplier",
|
||||
effect: () => Math.sqrt(Achievements.power),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
checkRequirement: () => Glyphs.activeList.countWhere(g => g.strength >= 1.5) === 4,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Improve the Glyph rarity formula",
|
||||
effect: 1.3,
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Duplicity of Potency",
|
||||
id: 17,
|
||||
cost: 1500,
|
||||
requirement: () => `Reality with ${formatInt(4)} Glyphs equipped, each having at least ${formatInt(2)} effects
|
||||
(${formatInt(Glyphs.activeList.countWhere(g => g && countValuesFromBitmask(g.effects) >= 2))} equipped)`,
|
||||
hasFailed: () => {
|
||||
const availableGlyphs = Glyphs.inventory.countWhere(g => g && countValuesFromBitmask(g.effects) >= 2);
|
||||
const equipped = Glyphs.activeList.countWhere(g => countValuesFromBitmask(g.effects) >= 2);
|
||||
const availableSlots = Glyphs.activeSlotCount - Glyphs.activeList.length;
|
||||
return equipped + Math.min(availableGlyphs, availableSlots) < 4;
|
||||
},
|
||||
{
|
||||
name: "Linguistically Expand",
|
||||
id: 9,
|
||||
cost: 15,
|
||||
requirement: () => `Eternity for ${format("1e4000")} Eternity Points using
|
||||
only a single level ${formatInt(3)}+ Glyph.`,
|
||||
hasFailed: () => {
|
||||
const invalidEquippedGlyphs = Glyphs.activeList.length > 1 ||
|
||||
(Glyphs.activeList.length === 1 && Glyphs.activeList[0].level < 3);
|
||||
const hasValidGlyphInInventory = Glyphs.inventory.countWhere(g => g && g.level >= 3) > 0;
|
||||
return invalidEquippedGlyphs || (Glyphs.activeList.length === 0 && !hasValidGlyphInInventory);
|
||||
},
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 4000 &&
|
||||
Glyphs.activeList.length === 1 && Glyphs.activeList[0].level >= 3,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: "Gain another Glyph slot",
|
||||
effect: () => 1
|
||||
checkRequirement: () => Glyphs.activeList.countWhere(g => countValuesFromBitmask(g.effects) >= 2) === 4,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: () => `${formatPercents(0.5)} chance to get an additional effect on Glyphs`,
|
||||
effect: 0.5,
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Measure of Forever",
|
||||
id: 18,
|
||||
cost: 1500,
|
||||
requirement: () => `Reality with ${formatInt(4)} Glyphs equipped, each at level ${formatInt(10)} or higher
|
||||
(${formatInt(Glyphs.activeList.countWhere(g => g && g.level >= 10))} equipped)`,
|
||||
hasFailed: () => {
|
||||
const availableGlyphs = Glyphs.inventory.countWhere(g => g && g.level >= 10);
|
||||
const equipped = Glyphs.activeList.countWhere(g => g.level >= 10);
|
||||
const availableSlots = Glyphs.activeSlotCount - Glyphs.activeList.length;
|
||||
return equipped + Math.min(availableGlyphs, availableSlots) < 4;
|
||||
},
|
||||
{
|
||||
name: "Existentially Prolong",
|
||||
id: 10,
|
||||
cost: 15,
|
||||
requirement: () => `Complete your first Eternity with at least ${formatPostBreak(DC.E450)} Infinity Points`,
|
||||
hasFailed: () => !player.requirementChecks.reality.noEternities,
|
||||
checkRequirement: () => Currency.infinityPoints.exponent >= 450 &&
|
||||
player.requirementChecks.reality.noEternities,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
|
||||
description: () => `Start every Reality with ${formatInt(100)} Eternities (also applies to current Reality)`,
|
||||
automatorPoints: 15,
|
||||
shortDescription: () => `Start with ${formatInt(100)} Eternities`,
|
||||
effect: () => 100
|
||||
},
|
||||
{
|
||||
name: "The Boundless Flow",
|
||||
id: 11,
|
||||
cost: 50,
|
||||
requirement: () => `${format(Currency.infinitiesBanked.value, 2)}/${format(DC.E12)} Banked Infinities`,
|
||||
checkRequirement: () => Currency.infinitiesBanked.exponent >= 12,
|
||||
checkEvent: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.REALITY_FIRST_UNLOCKED],
|
||||
description: "Every second, gain 10% of the Infinities you would normally gain by Infinitying",
|
||||
automatorPoints: 5,
|
||||
shortDescription: () => `Continuous Infinity generation`,
|
||||
effect: () => gainedInfinities().times(0.1),
|
||||
formatEffect: value => `${format(value)} per second`
|
||||
},
|
||||
{
|
||||
name: "The Knowing Existence",
|
||||
id: 12,
|
||||
cost: 50,
|
||||
requirement: () => `Eternity for ${format(DC.E70)} Eternity Points without Eternity Challenge 1`,
|
||||
hasFailed: () => EternityChallenge(1).completions !== 0,
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 70 && EternityChallenge(1).completions === 0,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: "Eternity Point multiplier based on Reality and Time Theorem count",
|
||||
effect: () => Currency.timeTheorems.value
|
||||
.minus(DC.E3).clampMin(2)
|
||||
.pow(Math.log2(Math.min(Currency.realities.value, 1e4))).clampMin(1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "The Telemechanical Process",
|
||||
id: 13,
|
||||
cost: 50,
|
||||
requirement: () => `Eternity for ${format(DC.E4000)} Eternity Points without Time Dimensions 5-8`,
|
||||
hasFailed: () => !Array.range(5, 4).every(i => TimeDimension(i).amount.equals(0)),
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 4000 &&
|
||||
Array.range(5, 4).every(i => TimeDimension(i).amount.equals(0)),
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: () => `Unlock Time Dimension, ${formatX(5)} Eternity Point multiplier,
|
||||
and improved Eternity autobuyers`,
|
||||
automatorPoints: 10,
|
||||
shortDescription: () => `TD and ${formatX(5)} EP Autobuyers, improved Eternity Autobuyer`,
|
||||
},
|
||||
{
|
||||
name: "The Eternal Flow",
|
||||
id: 14,
|
||||
cost: 50,
|
||||
requirement: () => `${format(Currency.eternities.value, 2)}/${format(1e7)} Eternities`,
|
||||
checkRequirement: () => Currency.eternities.gte(1e7),
|
||||
checkEvent: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.REALITY_FIRST_UNLOCKED],
|
||||
description: "Gain Eternities per second equal to your Reality count",
|
||||
automatorPoints: 5,
|
||||
shortDescription: () => `Continuous Eternity generation`,
|
||||
effect: () => Currency.realities.value * Ra.unlocks.continuousTTBoost.effects.eternity.effectOrDefault(1),
|
||||
formatEffect: value => `${format(value)} per second`
|
||||
},
|
||||
{
|
||||
name: "The Paradoxical Forever",
|
||||
id: 15,
|
||||
cost: 50,
|
||||
requirement: () => `Have ${format(DC.E10)} Eternity Points without purchasing
|
||||
the ${formatX(5)} Eternity Point upgrade`,
|
||||
hasFailed: () => player.epmultUpgrades !== 0,
|
||||
checkRequirement: () => Currency.eternityPoints.exponent >= 10 && player.epmultUpgrades === 0,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: () => `Boost Tachyon Particle gain based on ${formatX(5)} Eternity Point multiplier`,
|
||||
effect: () => Math.max(Math.sqrt(Decimal.log10(EternityUpgrade.epMult.effectValue)) / 3, 1),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Disparity of Rarity",
|
||||
id: 16,
|
||||
cost: 1500,
|
||||
requirement: () => `Reality with ${formatInt(4)} Glyphs equipped of uncommon or better rarity
|
||||
(${formatInt(Glyphs.activeList.countWhere(g => g && g.strength >= 1.5))} equipped)`,
|
||||
hasFailed: () => {
|
||||
const availableGlyphs = Glyphs.inventory.countWhere(g => g && g.strength >= 1.5);
|
||||
const equipped = Glyphs.activeList.countWhere(g => g.strength >= 1.5);
|
||||
const availableSlots = Glyphs.activeSlotCount - Glyphs.activeList.length;
|
||||
return equipped + Math.min(availableGlyphs, availableSlots) < 4;
|
||||
},
|
||||
checkRequirement: () => Glyphs.activeList.countWhere(g => g.strength >= 1.5) === 4,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Improve the Glyph rarity formula",
|
||||
effect: 1.3,
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Duplicity of Potency",
|
||||
id: 17,
|
||||
cost: 1500,
|
||||
requirement: () => `Reality with ${formatInt(4)} Glyphs equipped, each having at least ${formatInt(2)} effects
|
||||
(${formatInt(Glyphs.activeList.countWhere(g => g && countValuesFromBitmask(g.effects) >= 2))} equipped)`,
|
||||
hasFailed: () => {
|
||||
const availableGlyphs = Glyphs.inventory.countWhere(g => g && countValuesFromBitmask(g.effects) >= 2);
|
||||
const equipped = Glyphs.activeList.countWhere(g => countValuesFromBitmask(g.effects) >= 2);
|
||||
const availableSlots = Glyphs.activeSlotCount - Glyphs.activeList.length;
|
||||
return equipped + Math.min(availableGlyphs, availableSlots) < 4;
|
||||
},
|
||||
checkRequirement: () => Glyphs.activeList.countWhere(g => countValuesFromBitmask(g.effects) >= 2) === 4,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: () => `${formatPercents(0.5)} chance to get an additional effect on Glyphs`,
|
||||
effect: 0.5,
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Measure of Forever",
|
||||
id: 18,
|
||||
cost: 1500,
|
||||
requirement: () => `Reality with ${formatInt(4)} Glyphs equipped, each at level ${formatInt(10)} or higher
|
||||
(${formatInt(Glyphs.activeList.countWhere(g => g && g.level >= 10))} equipped)`,
|
||||
hasFailed: () => {
|
||||
const availableGlyphs = Glyphs.inventory.countWhere(g => g && g.level >= 10);
|
||||
const equipped = Glyphs.activeList.countWhere(g => g.level >= 10);
|
||||
const availableSlots = Glyphs.activeSlotCount - Glyphs.activeList.length;
|
||||
return equipped + Math.min(availableGlyphs, availableSlots) < 4;
|
||||
},
|
||||
checkRequirement: () => Glyphs.activeList.countWhere(g => g.level >= 10) === 4,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Eternity count boosts Glyph level",
|
||||
effect: () => Math.max(Math.sqrt(Currency.eternities.value.plus(1).log10()) * 0.45, 1),
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Scour to Empower",
|
||||
id: 19,
|
||||
cost: 1500,
|
||||
requirement: () => `Have a total of ${formatInt(30)} or more Glyphs at once
|
||||
(You have ${formatInt(Glyphs.allGlyphs.countWhere(g => g))})`,
|
||||
hasFailed: () => Glyphs.allGlyphs.countWhere(g => g) < 30,
|
||||
checkRequirement: () => Glyphs.allGlyphs.countWhere(g => g) >= 30,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "You can sacrifice Glyphs for permanent bonuses (Shift + click)",
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Parity of Singularity",
|
||||
id: 20,
|
||||
cost: 1500,
|
||||
requirement: () => `${formatInt(1)} year total play time and the Black Hole unlocked
|
||||
(Currently: ${Time.totalTimePlayed.toStringShort(false)})`,
|
||||
hasFailed: () => !BlackHole(1).isUnlocked && Currency.realityMachines.lt(100),
|
||||
checkRequirement: () => Time.totalTimePlayed.totalYears >= 1 && BlackHole(1).isUnlocked,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock Black Hole 2",
|
||||
automatorPoints: 10,
|
||||
shortDescription: () => `Second Black Hole`,
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Cosmic Conglomerate",
|
||||
id: 21,
|
||||
cost: 100000,
|
||||
requirement: () => `${formatInt(Replicanti.galaxies.total + player.galaxies +
|
||||
player.dilation.totalTachyonGalaxies)}/${formatInt(2800)} total Galaxies from all types`,
|
||||
checkRequirement: () =>
|
||||
Replicanti.galaxies.total + player.galaxies + player.dilation.totalTachyonGalaxies >= 2800,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Remote Antimatter Galaxy scaling is moved to ${formatInt(1e5)} galaxies`,
|
||||
effect: 1e5
|
||||
},
|
||||
{
|
||||
name: "Temporal Transcendence",
|
||||
id: 22,
|
||||
cost: 100000,
|
||||
requirement: () => `${format(Currency.timeShards.value, 1)}/${format(DC.E28000)} Time Shards`,
|
||||
checkRequirement: () => Currency.timeShards.exponent >= 28000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Time Dimension multiplier based on days spent in this Reality",
|
||||
effect: () => Decimal.pow10(Math.pow(1 + 2 * Math.log10(Time.thisReality.totalDays + 1), 1.6)),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Replicative Rapidity",
|
||||
id: 23,
|
||||
cost: 100000,
|
||||
requirement: () => `Reality in under ${formatInt(15)} minutes (Best: ${Time.bestReality.toStringShort()})`,
|
||||
hasFailed: () => Time.thisReality.totalMinutes >= 15,
|
||||
checkRequirement: () => Time.thisReality.totalMinutes < 15,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Replicanti speed is boosted based on your fastest Reality",
|
||||
effect: () => 15 / Math.clamp(Time.bestReality.totalMinutes, 1 / 12, 15),
|
||||
cap: 180,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Synthetic Symbolism",
|
||||
id: 24,
|
||||
cost: 100000,
|
||||
requirement: () => `Reality for ${formatInt(5000)} Reality Machines without Glyphs`,
|
||||
hasFailed: () => Glyphs.activeList.length > 0,
|
||||
checkRequirement: () => MachineHandler.gainedRealityMachines.gte(5000) && Glyphs.activeList.length === 0,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Gain another Glyph slot",
|
||||
effect: () => 1
|
||||
},
|
||||
{
|
||||
name: "Effortless Existence",
|
||||
id: 25,
|
||||
cost: 100000,
|
||||
requirement: () => `Reach ${format(DC.E11111)} EP (Best: ${format(player.records.bestReality.bestEP, 2)} EP)`,
|
||||
checkRequirement: () => player.records.bestReality.bestEP.exponent >= 11111,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: "Unlock the Reality autobuyer and Automator command",
|
||||
automatorPoints: 100,
|
||||
shortDescription: () => `Reality Autobuyer`,
|
||||
},
|
||||
];
|
||||
}());
|
||||
checkRequirement: () => Glyphs.activeList.countWhere(g => g.level >= 10) === 4,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Eternity count boosts Glyph level",
|
||||
effect: () => Math.max(Math.sqrt(Currency.eternities.value.plus(1).log10()) * 0.45, 1),
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Scour to Empower",
|
||||
id: 19,
|
||||
cost: 1500,
|
||||
requirement: () => `Have a total of ${formatInt(30)} or more Glyphs at once
|
||||
(You have ${formatInt(Glyphs.allGlyphs.countWhere(g => g))})`,
|
||||
hasFailed: () => Glyphs.allGlyphs.countWhere(g => g) < 30,
|
||||
checkRequirement: () => Glyphs.allGlyphs.countWhere(g => g) >= 30,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "You can sacrifice Glyphs for permanent bonuses (Shift + click)",
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Parity of Singularity",
|
||||
id: 20,
|
||||
cost: 1500,
|
||||
requirement: () => `${formatInt(1)} year total play time and the Black Hole unlocked
|
||||
(Currently: ${Time.totalTimePlayed.toStringShort(false)})`,
|
||||
hasFailed: () => !BlackHole(1).isUnlocked && Currency.realityMachines.lt(100),
|
||||
checkRequirement: () => Time.totalTimePlayed.totalYears >= 1 && BlackHole(1).isUnlocked,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Unlock Black Hole 2",
|
||||
automatorPoints: 10,
|
||||
shortDescription: () => `Second Black Hole`,
|
||||
formatCost: value => format(value, 1, 0)
|
||||
},
|
||||
{
|
||||
name: "Cosmic Conglomerate",
|
||||
id: 21,
|
||||
cost: 100000,
|
||||
requirement: () => `${formatInt(Replicanti.galaxies.total + player.galaxies +
|
||||
player.dilation.totalTachyonGalaxies)}/${formatInt(2800)} total Galaxies from all types`,
|
||||
checkRequirement: () =>
|
||||
Replicanti.galaxies.total + player.galaxies + player.dilation.totalTachyonGalaxies >= 2800,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: () => `Remote Antimatter Galaxy scaling is moved to ${formatInt(1e5)} galaxies`,
|
||||
effect: 1e5
|
||||
},
|
||||
{
|
||||
name: "Temporal Transcendence",
|
||||
id: 22,
|
||||
cost: 100000,
|
||||
requirement: () => `${format(Currency.timeShards.value, 1)}/${format(DC.E28000)} Time Shards`,
|
||||
checkRequirement: () => Currency.timeShards.exponent >= 28000,
|
||||
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
|
||||
description: "Time Dimension multiplier based on days spent in this Reality",
|
||||
effect: () => Decimal.pow10(Math.pow(1 + 2 * Math.log10(Time.thisReality.totalDays + 1), 1.6)),
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Replicative Rapidity",
|
||||
id: 23,
|
||||
cost: 100000,
|
||||
requirement: () => `Reality in under ${formatInt(15)} minutes (Best: ${Time.bestReality.toStringShort()})`,
|
||||
hasFailed: () => Time.thisReality.totalMinutes >= 15,
|
||||
checkRequirement: () => Time.thisReality.totalMinutes < 15,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Replicanti speed is boosted based on your fastest Reality",
|
||||
effect: () => 15 / Math.clamp(Time.bestReality.totalMinutes, 1 / 12, 15),
|
||||
cap: 180,
|
||||
formatEffect: value => formatX(value, 2, 2)
|
||||
},
|
||||
{
|
||||
name: "Synthetic Symbolism",
|
||||
id: 24,
|
||||
cost: 100000,
|
||||
requirement: () => `Reality for ${formatInt(5000)} Reality Machines without Glyphs`,
|
||||
hasFailed: () => Glyphs.activeList.length > 0,
|
||||
checkRequirement: () => MachineHandler.gainedRealityMachines.gte(5000) && Glyphs.activeList.length === 0,
|
||||
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
|
||||
description: "Gain another Glyph slot",
|
||||
effect: () => 1
|
||||
},
|
||||
{
|
||||
name: "Effortless Existence",
|
||||
id: 25,
|
||||
cost: 100000,
|
||||
requirement: () => `Reach ${format(DC.E11111)} EP (Best: ${format(player.records.bestReality.bestEP, 2)} EP)`,
|
||||
checkRequirement: () => player.records.bestReality.bestEP.exponent >= 11111,
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
description: "Unlock the Reality autobuyer and Automator command",
|
||||
automatorPoints: 100,
|
||||
shortDescription: () => `Reality Autobuyer`,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -86,7 +86,7 @@ GameDatabase.speedrunMilestones = [
|
|||
key: "allEternityMilestones",
|
||||
name: "All Eternity Milestones",
|
||||
description: "Unlock all Eternity Milestones",
|
||||
checkRequirement: () => EternityMilestones.all.every(m => m.isReached),
|
||||
checkRequirement: () => EternityMilestone.all.every(m => m.isReached),
|
||||
checkEvent: GAME_EVENT.ETERNITY_RESET_AFTER,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1318,6 +1318,11 @@ GameStorage.devMigrations = {
|
|||
delete player.celestials.effarig.unlocksBits;
|
||||
delete player.celestials.ra.unlocksBits;
|
||||
},
|
||||
player => {
|
||||
for (const script of Object.values(player.reality.automator.scripts)) {
|
||||
script.id = parseInt(script.id, 10);
|
||||
}
|
||||
},
|
||||
],
|
||||
|
||||
patch(player) {
|
||||
|
|
|
@ -30,19 +30,7 @@ class TabNotificationState {
|
|||
}
|
||||
}
|
||||
|
||||
export const TabNotification = (function() {
|
||||
const db = GameDatabase.tabNotifications;
|
||||
return {
|
||||
firstInfinity: new TabNotificationState(db.firstInfinity),
|
||||
IDUnlock: new TabNotificationState(db.ICUnlock),
|
||||
ICUnlock: new TabNotificationState(db.ICUnlock),
|
||||
breakInfinity: new TabNotificationState(db.breakInfinity),
|
||||
firstEternity: new TabNotificationState(db.firstEternity),
|
||||
dilationAfterUnlock: new TabNotificationState(db.dilationAfterUnlock),
|
||||
realityUnlock: new TabNotificationState(db.realityUnlock),
|
||||
blackHoleUnlock: new TabNotificationState(db.blackHoleUnlock),
|
||||
automatorUnlock: new TabNotificationState(db.automatorUnlock),
|
||||
teresaUnlock: new TabNotificationState(db.teresaUnlock),
|
||||
alchemyUnlock: new TabNotificationState(db.alchemyUnlock),
|
||||
};
|
||||
}());
|
||||
export const TabNotification = mapGameDataToObject(
|
||||
GameDatabase.tabNotifications,
|
||||
config => new TabNotificationState(config)
|
||||
);
|
||||
|
|
|
@ -683,7 +683,7 @@ function applyAutoUnlockPerks() {
|
|||
if (Perk.autounlockDilation3.isBought) buyDilationUpgrade(DilationUpgrade.ttGenerator.id);
|
||||
if (Perk.autounlockReality.isBought) TimeStudy.reality.purchase(true);
|
||||
if (player.eternityUpgrades.size < 6 && Perk.autounlockEU2.isBought) {
|
||||
const secondRow = Object.values(EternityUpgrade).filter(u => u.id > 3);
|
||||
const secondRow = EternityUpgrade.all.filter(u => u.id > 3);
|
||||
for (const upgrade of secondRow) {
|
||||
if (player.eternityPoints.gte(upgrade.cost / 1e10)) player.eternityUpgrades.add(upgrade.id);
|
||||
}
|
||||
|
|
|
@ -132,21 +132,20 @@
|
|||
border-radius: 0;
|
||||
}
|
||||
|
||||
.l-automator-pane__controls {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.c-automator__controls {
|
||||
background-color: #262626;
|
||||
}
|
||||
|
||||
.l-automator__controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: none;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* for corner buttons */
|
||||
position: relative;
|
||||
justify-content: flex-start;
|
||||
.l-automator-button-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 3rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
@ -163,23 +162,6 @@
|
|||
right: 0;
|
||||
}
|
||||
|
||||
.l-automator__script-names {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.l-automator__scripts-dropdown {
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
border-width: 0.1rem;
|
||||
border-radius: 0;
|
||||
margin: 0.4rem;
|
||||
padding: 0.2rem 0 0.3rem;
|
||||
}
|
||||
|
||||
.l-automator__rename-input {
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
|
|
|
@ -67,7 +67,7 @@ body.t-s9 {
|
|||
height: 7rem;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--color-base);
|
||||
background-color: var(--color-prestige--accent);
|
||||
border-right: 0.1rem solid var(--color-accent);
|
||||
border-bottom: 0.1rem solid var(--color-accent);
|
||||
padding: 1rem;
|
||||
|
@ -312,7 +312,7 @@ body.t-s9 {
|
|||
line-height: 2.8rem;
|
||||
opacity: 0;
|
||||
color: var(--color-text);
|
||||
background: var(--color-base);
|
||||
background: var(--color-prestige--accent);
|
||||
border: 0.1rem solid var(--color-accent);
|
||||
margin-left: -7.7rem;
|
||||
transition-duration: 0.2s;
|
||||
|
@ -346,7 +346,6 @@ body.t-s9 {
|
|||
|
||||
.o-tab-btn--infinity .o-subtab__tooltip {
|
||||
color: var(--color-infinity);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-infinity);
|
||||
}
|
||||
|
||||
|
@ -356,7 +355,6 @@ body.t-s9 {
|
|||
|
||||
.o-tab-btn--eternity .o-subtab__tooltip {
|
||||
color: var(--color-eternity);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-eternity);
|
||||
}
|
||||
|
||||
|
@ -366,7 +364,6 @@ body.t-s9 {
|
|||
|
||||
.o-tab-btn--reality .o-subtab__tooltip {
|
||||
color: var(--color-reality);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-reality);
|
||||
}
|
||||
|
||||
|
@ -376,7 +373,6 @@ body.t-s9 {
|
|||
|
||||
.o-tab-btn--celestial .o-subtab__tooltip {
|
||||
color: var(--color-celestials);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-celestials);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@ html {
|
|||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.s-base--metro::-webkit-scrollbar-thumb {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
@ -154,7 +159,7 @@ html {
|
|||
--color-reality: #afa3a5;
|
||||
--color-reality-light: #e8e3e4;
|
||||
--color-celestials: #f2d6c1;
|
||||
--color-prestige--accent: black;
|
||||
--color-prestige--accent: #dbd242;
|
||||
|
||||
--color-pelle--base: #7cb727;
|
||||
}
|
||||
|
@ -510,7 +515,6 @@ button:focus {
|
|||
position: absolute;
|
||||
right: 0.5rem;
|
||||
bottom: 0.5rem;
|
||||
animation: weee 4s infinite;
|
||||
}
|
||||
|
||||
.o-time-study-selection-btn {
|
||||
|
@ -535,7 +539,7 @@ button:focus {
|
|||
font-size: 1.8rem;
|
||||
font-weight: bold;
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-base);
|
||||
background-color: var(--color-prestige--accent);
|
||||
border: var(--var-border-width, 0.2rem) solid var(--color-accent);
|
||||
border-radius: var(--var-border-radius, 0.4rem);
|
||||
transition-duration: 0.2s;
|
||||
|
@ -550,51 +554,43 @@ button:focus {
|
|||
}
|
||||
|
||||
.o-tab-btn:hover {
|
||||
color: var(--color-text-inverted);
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-accent);
|
||||
}
|
||||
|
||||
.o-tab-btn--infinity {
|
||||
color: var(--color-infinity);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-infinity);
|
||||
}
|
||||
|
||||
.o-tab-btn--infinity:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-infinity);
|
||||
}
|
||||
|
||||
.o-tab-btn--eternity {
|
||||
color: var(--color-eternity);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-eternity);
|
||||
}
|
||||
|
||||
.o-tab-btn--eternity:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-eternity);
|
||||
}
|
||||
|
||||
.o-tab-btn--reality {
|
||||
color: var(--color-reality);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-reality);
|
||||
}
|
||||
|
||||
.o-tab-btn--reality:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-reality);
|
||||
}
|
||||
|
||||
.o-tab-btn--celestial {
|
||||
color: var(--color-celestials);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-celestials);
|
||||
}
|
||||
|
||||
.o-tab-btn--celestial:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-celestials);
|
||||
}
|
||||
|
||||
|
@ -1131,26 +1127,25 @@ br {
|
|||
}
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line keyframes-name-pattern */
|
||||
@keyframes barrelRoll {
|
||||
@keyframes a-barrel-roll {
|
||||
0% { transform: rotateZ(0deg); }
|
||||
|
||||
50%,
|
||||
100% { transform: rotateZ(360deg); }
|
||||
}
|
||||
|
||||
@keyframes spin3d {
|
||||
@keyframes a-spin3d {
|
||||
0% { transform: rotate3d(5.2, -2.8, 1.4, 0deg); }
|
||||
100% { transform: rotate3d(5.2, -2.8, 1.4, 360deg); }
|
||||
}
|
||||
|
||||
@keyframes spin4d {
|
||||
@keyframes a-spin4d {
|
||||
0%,
|
||||
100% { transform: scale(1) rotate3d(5.2, -2.8, 1.4, 0deg); }
|
||||
50% { transform: scale(0) rotate3d(5.2, -2.8, 1.4, 360deg); }
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
@keyframes a-float {
|
||||
0% {
|
||||
bottom: 0;
|
||||
opacity: 0;
|
||||
|
@ -1166,7 +1161,7 @@ br {
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes implode {
|
||||
@keyframes a-implode {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
|
@ -1179,7 +1174,7 @@ br {
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes eternify {
|
||||
@keyframes a-eternify {
|
||||
0% {
|
||||
opacity: 1;
|
||||
filter: blur(0);
|
||||
|
@ -1221,7 +1216,7 @@ br {
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes dilate {
|
||||
@keyframes a-dilate {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scaleX(1);
|
||||
|
@ -1243,7 +1238,7 @@ br {
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes undilate {
|
||||
@keyframes a-undilate {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scaleX(1);
|
||||
|
@ -1265,14 +1260,14 @@ br {
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes realize {
|
||||
@keyframes a-realize {
|
||||
0% { opacity: 1; }
|
||||
20% { opacity: 0; }
|
||||
80% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes realizebg {
|
||||
@keyframes a-realizebg {
|
||||
0% { opacity: 0; }
|
||||
20% { opacity: 0; }
|
||||
30% { opacity: 1; }
|
||||
|
@ -1281,41 +1276,41 @@ br {
|
|||
100% { opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes text-grow {
|
||||
@keyframes a-text-grow {
|
||||
0% { font-size: 1.3rem; }
|
||||
50% { font-size: 1.8rem; }
|
||||
100% { font-size: 1.3rem; }
|
||||
}
|
||||
|
||||
@keyframes text-shrink {
|
||||
@keyframes a-text-shrink {
|
||||
0% { font-size: 1.8rem; }
|
||||
50% { font-size: 1.3rem; }
|
||||
100% { font-size: 1.8rem; }
|
||||
}
|
||||
|
||||
@keyframes text-crunch {
|
||||
@keyframes a-text-crunch {
|
||||
0% { font-size: 1.5rem; }
|
||||
90% { font-size: 1.5rem; }
|
||||
100% { font-size: 0; }
|
||||
}
|
||||
|
||||
@keyframes text-flash {
|
||||
@keyframes a-text-flash {
|
||||
0% { color: yellow; }
|
||||
50% { color: red; }
|
||||
}
|
||||
|
||||
@keyframes fade-out {
|
||||
@keyframes a-fade-out {
|
||||
0% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes disappear {
|
||||
@keyframes a-disappear {
|
||||
0% { opacity: 1; }
|
||||
100% { opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes text-stretch {
|
||||
@keyframes a-text-stretch {
|
||||
0% { letter-spacing: 0; }
|
||||
100% { letter-spacing: 30rem; }
|
||||
}
|
||||
|
@ -7776,8 +7771,6 @@ kbd {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 60rem;
|
||||
text-align: left;
|
||||
font-size: 1.2rem;
|
||||
padding: 0.25rem 1rem;
|
||||
}
|
||||
|
||||
|
@ -9269,7 +9262,7 @@ input.o-automator-block-input {
|
|||
font: 1rem Typewriter, serif;
|
||||
font-weight: bold;
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-base);
|
||||
background-color: var(--color-text-inverted);
|
||||
border: 0.1rem solid black;
|
||||
border-radius: var(--var-border-radius, 0.4rem);
|
||||
box-shadow: none;
|
||||
|
@ -9305,45 +9298,37 @@ input.o-automator-block-input {
|
|||
|
||||
.c-hide-modal-tab-button--infinity {
|
||||
color: var(--color-infinity);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-infinity);
|
||||
}
|
||||
|
||||
.c-hide-modal-tab-button--infinity:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-infinity);
|
||||
}
|
||||
|
||||
.c-hide-modal-tab-button--eternity {
|
||||
color: var(--color-eternity);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-eternity);
|
||||
}
|
||||
|
||||
.c-hide-modal-tab-button--eternity:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-eternity);
|
||||
}
|
||||
|
||||
.c-hide-modal-tab-button--reality {
|
||||
color: var(--color-reality);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-reality);
|
||||
}
|
||||
|
||||
.c-hide-modal-tab-button--reality:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-reality);
|
||||
}
|
||||
|
||||
.c-hide-modal-tab-button--celestials {
|
||||
color: var(--color-celestials);
|
||||
background: var(--color-prestige--accent);
|
||||
border-color: var(--color-celestials);
|
||||
}
|
||||
|
||||
.c-hide-modal-tab-button--celestials:hover {
|
||||
color: var(--color-prestige--accent);
|
||||
background: var(--color-celestials);
|
||||
}
|
||||
|
||||
|
@ -9354,7 +9339,7 @@ input.o-automator-block-input {
|
|||
font-family: "Font Awesome 6 Free" !important;
|
||||
}
|
||||
|
||||
@keyframes opacity {
|
||||
@keyframes a-opacity {
|
||||
0% { opacity: 0; }
|
||||
50% { opacity: 0.4; }
|
||||
100% { opacity: 0; }
|
||||
|
@ -9373,7 +9358,7 @@ input.o-automator-block-input {
|
|||
left: 0;
|
||||
background: gold;
|
||||
border-radius: var(--var-border-radius, inherit);
|
||||
animation: opacity 3s infinite;
|
||||
animation: a-opacity 3s infinite;
|
||||
}
|
||||
|
||||
.o-celestial-nav__hoverable .tooltiptext {
|
||||
|
|
|
@ -45,18 +45,17 @@ body.t-s1 {
|
|||
z-index: 0;
|
||||
opacity: 1;
|
||||
background-image: url("../images/snow1.png"), url("../images/snow2.png"), url("../images/snow3.png");
|
||||
animation: snow 10s linear infinite, snowFade 10s cubic-bezier(0, 0.3, 1, 0.7) infinite;
|
||||
animation: a-snow 10s linear infinite, a-snow-fade 10s cubic-bezier(0, 0.3, 1, 0.7) infinite;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@keyframes snow {
|
||||
@keyframes a-snow {
|
||||
0% { background-position: 0 0, 0 0, 0 0; }
|
||||
50% { background-position: 500px 500px, 100px 200px, -100px 150px; }
|
||||
100% { background-position: 1000px 1000px, 200px 400px, -200px 300px; }
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line keyframes-name-pattern */
|
||||
@keyframes snowFade {
|
||||
@keyframes a-snow-fade {
|
||||
0% { opacity: 0; }
|
||||
50% { opacity: 1; }
|
||||
100% { opacity: 0; }
|
||||
|
|
|
@ -5,10 +5,10 @@ body {
|
|||
.t-s3 #ui,
|
||||
.t-s3 #ui-fixed,
|
||||
.t-s3 .c-glyph-tooltip {
|
||||
animation: glasses 7s infinite;
|
||||
animation: a-glasses 7s infinite;
|
||||
}
|
||||
|
||||
@keyframes glasses {
|
||||
@keyframes a-glasses {
|
||||
0% { filter: blur(0); }
|
||||
10% { filter: blur(3px); }
|
||||
20% { filter: blur(0); }
|
||||
|
|
|
@ -78,8 +78,6 @@ export default {
|
|||
name: this.text,
|
||||
glyphSet: this.glyphs,
|
||||
closeOn: GAME_EVENT.GLYPH_SET_SAVE_CHANGE,
|
||||
isGlyphSelection: false,
|
||||
showSetName: true,
|
||||
displaySacrifice: this.showSacrifice,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -59,6 +59,6 @@ export default {
|
|||
}
|
||||
|
||||
.t-s3 .o-save-timer {
|
||||
animation: glasses 7s infinite;
|
||||
animation: a-glasses 7s infinite;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,9 +7,21 @@ export default {
|
|||
ModalWrapper,
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
required: true
|
||||
warnings: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
inputs: {
|
||||
type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -24,14 +36,14 @@ export default {
|
|||
computed: {
|
||||
presets: () => player.timestudy.presets,
|
||||
params: () => GameDatabase.reality.automator.templates.paramTypes,
|
||||
warnings() {
|
||||
validWarnings() {
|
||||
return this.invalidInputCount === 0
|
||||
? this.modalConfig.warnings().concat(this.templateScript?.warnings)
|
||||
: this.modalConfig.warnings();
|
||||
? this.warnings().concat(this.templateScript?.warnings)
|
||||
: this.warnings();
|
||||
},
|
||||
templateScript() {
|
||||
if (this.invalidInputCount !== 0) return null;
|
||||
return new ScriptTemplate(this.templateProps, this.modalConfig.name);
|
||||
return new ScriptTemplate(this.templateProps, this.name);
|
||||
}
|
||||
},
|
||||
// Many props in this component are generated dynamically from a GameDB entry, but Vue can only give reactive
|
||||
|
@ -39,7 +51,7 @@ export default {
|
|||
// specifically $set them here on initialization; additionally we give them a default value so that later function
|
||||
// calls don't error out from undefined inputs.
|
||||
created() {
|
||||
for (const input of this.modalConfig.inputs) {
|
||||
for (const input of this.inputs) {
|
||||
const boolProp = this.paramTypeObject(input.type).boolDisplay;
|
||||
if (boolProp) {
|
||||
this.$set(this.templateInputs, input.name, false);
|
||||
|
@ -77,7 +89,7 @@ export default {
|
|||
updateTemplateProps() {
|
||||
this.templateProps = {};
|
||||
this.invalidInputCount = 0;
|
||||
for (const input of this.modalConfig.inputs) {
|
||||
for (const input of this.inputs) {
|
||||
const typeObj = this.paramTypeObject(input.type);
|
||||
const mapFn = x => (typeObj.map ? typeObj.map(x) : x);
|
||||
this.templateProps[input.name] = mapFn(this.templateInputs[input.name]);
|
||||
|
@ -108,10 +120,10 @@ export default {
|
|||
<template>
|
||||
<ModalWrapper class="c-automator-template-container">
|
||||
<template #header>
|
||||
{{ modalConfig.name }} Template
|
||||
{{ name }} Template
|
||||
</template>
|
||||
<div class="c-automator-template-description">
|
||||
{{ modalConfig.description }}
|
||||
{{ description }}
|
||||
</div>
|
||||
<div class="c-automator-template-inputs">
|
||||
<b>Required Information:</b>
|
||||
|
@ -132,7 +144,7 @@ export default {
|
|||
<i>Current Tree</i>
|
||||
</button>
|
||||
<div
|
||||
v-for="input in modalConfig.inputs"
|
||||
v-for="input in inputs"
|
||||
:key="input.name"
|
||||
class="c-automator-template-entry"
|
||||
>
|
||||
|
@ -159,9 +171,9 @@ export default {
|
|||
</div>
|
||||
<div class="c-automator-template-warnings">
|
||||
<b>Possible things to consider:</b>
|
||||
<div v-if="warnings.length !== 0">
|
||||
<div v-if="validWarnings.length !== 0">
|
||||
<div
|
||||
v-for="warning in warnings"
|
||||
v-for="warning in validWarnings"
|
||||
:key="warning"
|
||||
class="c-automator-template-entry"
|
||||
>
|
||||
|
|
|
@ -9,10 +9,18 @@ export default {
|
|||
ModalWrapper,
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
playerBefore: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
playerAfter: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
seconds: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -23,17 +31,11 @@ export default {
|
|||
nothingHappened() {
|
||||
return Theme.current().name === "S9";
|
||||
},
|
||||
before() {
|
||||
return this.modalConfig.playerBefore;
|
||||
},
|
||||
after() {
|
||||
return this.modalConfig.playerAfter;
|
||||
},
|
||||
offlineStats() {
|
||||
return AwayProgressTypes.appearsInAwayModal;
|
||||
},
|
||||
headerText() {
|
||||
const timeDisplay = TimeSpan.fromSeconds(this.modalConfig.seconds).toString();
|
||||
const timeDisplay = TimeSpan.fromSeconds(this.seconds).toString();
|
||||
if (this.nothingHappened || !this.somethingHappened) {
|
||||
return `While you were away for ${timeDisplay}... Nothing happened.`;
|
||||
}
|
||||
|
@ -62,8 +64,8 @@ export default {
|
|||
v-for="name of offlineStats"
|
||||
:key="name"
|
||||
:name="name"
|
||||
:player-before="before"
|
||||
:player-after="after"
|
||||
:player-before="playerBefore"
|
||||
:player-after="playerAfter"
|
||||
@something-happened="somethingHappened = true"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -7,19 +7,14 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
scriptID: {
|
||||
type: [String, Number],
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
modal() {
|
||||
return this.$viewModel.modal.current;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleYesClick() {
|
||||
const script = this.modalConfig.scriptID;
|
||||
const script = this.scriptID;
|
||||
const runningScriptID = AutomatorBackend.state.topLevelScript;
|
||||
|
||||
AutomatorBackend.deleteScript(script);
|
||||
|
@ -34,17 +29,6 @@ export default {
|
|||
// AutomatorBackend.deleteScript will create an empty script if necessary
|
||||
player.reality.automator.state.editorScript = scriptList[0].id;
|
||||
}
|
||||
|
||||
// Deleting a script leaves a gap in ids, shift all of them down to fill it
|
||||
let newID = 0;
|
||||
const shiftedScripts = {};
|
||||
for (const id of Object.keys(player.reality.automator.scripts)) {
|
||||
shiftedScripts[newID] = player.reality.automator.scripts[id];
|
||||
shiftedScripts[newID].id = newID;
|
||||
newID++;
|
||||
}
|
||||
player.reality.automator.scripts = shiftedScripts;
|
||||
|
||||
EventHub.dispatch(GAME_EVENT.AUTOMATOR_SAVE_CHANGED);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -62,8 +62,8 @@ export default {
|
|||
this.canGetHint = this.currentStored >= this.nextHintCost;
|
||||
this.shownEntries = [];
|
||||
|
||||
this.realityHintsLeft = Object.values(EnslavedProgress).length;
|
||||
for (const prog of Object.values(EnslavedProgress)) {
|
||||
this.realityHintsLeft = EnslavedProgress.all.length;
|
||||
for (const prog of EnslavedProgress.all) {
|
||||
if (prog.hasHint) {
|
||||
this.shownEntries.push([prog.hasProgress
|
||||
? prog.config.progress
|
||||
|
@ -82,7 +82,7 @@ export default {
|
|||
},
|
||||
giveRealityHint(available) {
|
||||
if (available <= 0 || !Enslaved.spendTimeForHint()) return;
|
||||
Object.values(EnslavedProgress).filter(prog => !prog.hasHint).randomElement().unlock();
|
||||
EnslavedProgress.all.filter(prog => !prog.hasHint).randomElement().unlock();
|
||||
},
|
||||
giveGlyphHint(available) {
|
||||
if (available <= 0 || !Enslaved.spendTimeForHint()) return;
|
||||
|
|
|
@ -9,8 +9,8 @@ export default {
|
|||
GlyphSetPreview
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
glyphSetId: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
@ -21,10 +21,10 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.glyphSet = Glyphs.copyForRecords(player.reality.glyphs.sets[this.modalConfig.glyphSetId].glyphs);
|
||||
this.glyphSet = Glyphs.copyForRecords(player.reality.glyphs.sets[this.glyphSetId].glyphs);
|
||||
},
|
||||
handleYesClick() {
|
||||
player.reality.glyphs.sets[this.modalConfig.glyphSetId].glyphs = [];
|
||||
player.reality.glyphs.sets[this.glyphSetId].glyphs = [];
|
||||
EventHub.dispatch(GAME_EVENT.GLYPH_SET_SAVE_CHANGE);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -11,16 +11,30 @@ export default {
|
|||
GlyphShowcasePanelEntry,
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
required: true,
|
||||
name: String,
|
||||
glyphSet: Array,
|
||||
closeOn: String,
|
||||
isGlyphSelection: Boolean,
|
||||
showSetName: Boolean,
|
||||
displaySacrifice: Boolean,
|
||||
}
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
glyphSet: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
closeOn: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isGlyphSelection: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showSetName: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
displaySacrifice: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -31,9 +45,6 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
isGlyphSelection() {
|
||||
return this.modalConfig.isGlyphSelection;
|
||||
},
|
||||
maxGlyphEffects() {
|
||||
let maxEffects = 1;
|
||||
for (const glyph of this.glyphs) {
|
||||
|
@ -43,13 +54,13 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
this.on$(this.modalConfig.closeOn, this.emitClose);
|
||||
this.on$(this.closeOn, this.emitClose);
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.glyphs = this.isGlyphSelection
|
||||
? GlyphSelection.glyphList(GlyphSelection.choiceCount, gainedGlyphLevel(), { isChoosingGlyph: false })
|
||||
: this.modalConfig.glyphSet.filter(x => x);
|
||||
: this.glyphSet.filter(x => x);
|
||||
this.gainedLevel = gainedGlyphLevel().actualLevel;
|
||||
// There should only be one reality glyph; this picks one pseudo-randomly if multiple are cheated/glitched in
|
||||
const realityGlyph = this.glyphs.filter(g => g.type === "reality")[0];
|
||||
|
@ -64,13 +75,13 @@ export default {
|
|||
<template>
|
||||
<ModalWrapper>
|
||||
<template #header>
|
||||
{{ modalConfig.name }}
|
||||
{{ name }}
|
||||
</template>
|
||||
<div v-if="isGlyphSelection">
|
||||
Projected Glyph Level: {{ formatInt(gainedLevel) }}
|
||||
</div>
|
||||
<GlyphSetName
|
||||
v-if="modalConfig.showSetName"
|
||||
v-if="showSetName"
|
||||
:glyph-set="glyphs"
|
||||
:force-color="true"
|
||||
/>
|
||||
|
@ -84,7 +95,7 @@ export default {
|
|||
:show-level="!isGlyphSelection"
|
||||
:reality-glyph-boost="realityGlyphBoost"
|
||||
:max-glyph-effects="maxGlyphEffects"
|
||||
:show-sacrifice="modalConfig.displaySacrifice"
|
||||
:show-sacrifice="displaySacrifice"
|
||||
/>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
|
|
|
@ -6,12 +6,6 @@ export default {
|
|||
components: {
|
||||
ModalCloseButton,
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
required: true,
|
||||
type: Object,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabId: 0,
|
||||
|
@ -123,4 +117,4 @@ export default {
|
|||
.s-base--dark .o-h2p-tab-button--first-irrelevant {
|
||||
border-top-color: white;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -35,6 +35,7 @@ export default {
|
|||
<component
|
||||
:is="modal.component"
|
||||
v-if="modal.isBare && !forceDontShowModal"
|
||||
v-bind="modal.props"
|
||||
:modal-config="modal.props"
|
||||
/>
|
||||
<div
|
||||
|
@ -43,6 +44,7 @@ export default {
|
|||
>
|
||||
<component
|
||||
:is="modal.component"
|
||||
v-bind="modal.props"
|
||||
:modal-config="modal.props"
|
||||
@close="hide"
|
||||
/>
|
||||
|
|
|
@ -51,44 +51,58 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapper class="c-reality-glyph-creation">
|
||||
<ModalWrapper>
|
||||
<template #header>
|
||||
Reality Glyph Creation
|
||||
</template>
|
||||
<div>
|
||||
Create a level {{ formatInt(realityGlyphLevel) }} Reality Glyph.
|
||||
Rarity will always be {{ formatPercents(1) }}
|
||||
and level scales on your current reality resource amount (which is all consumed). All other alchemy resources will
|
||||
be unaffected. Reality Glyphs have unique effects, some of which are only available with higher level Glyphs.
|
||||
Reality Glyphs can also be sacrificed to increase the yield from alchemy reactions. Like Effarig Glyphs,
|
||||
you cannot equip more than one at the same time.
|
||||
<div class="c-reality-glyph-creation">
|
||||
<div>
|
||||
Create a level {{ formatInt(realityGlyphLevel) }} Reality Glyph.
|
||||
Rarity will always be {{ formatPercents(1) }} and
|
||||
level scales on your current reality resource amount (which is all consumed). All other alchemy resources will
|
||||
be unaffected. Reality Glyphs have unique effects, some of which are only available with higher level Glyphs.
|
||||
Reality Glyphs can also be sacrificed to increase the yield from alchemy reactions. Like Effarig Glyphs,
|
||||
you cannot equip more than one at the same time.
|
||||
</div>
|
||||
<div class="o-available-effects-container">
|
||||
<div class="o-available-effects">
|
||||
Available Effects:
|
||||
</div>
|
||||
<div
|
||||
v-for="(effect, index) in possibleEffects"
|
||||
:key="index"
|
||||
>
|
||||
{{ formatGlyphEffect(effect) }}
|
||||
</div>
|
||||
</div>
|
||||
<PrimaryButton
|
||||
v-if="isDoomed"
|
||||
:enabled="false"
|
||||
>
|
||||
You cannot create Reality Glyphs while in Doomed
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
v-else-if="realityGlyphLevel !== 0"
|
||||
@click="createRealityGlyph"
|
||||
>
|
||||
Create a Reality Glyph!
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
v-else
|
||||
:enabled="false"
|
||||
>
|
||||
Reality Glyph level must be higher than {{ formatInt(0) }}
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
<div>
|
||||
Available Effects:
|
||||
</div>
|
||||
<div
|
||||
v-for="(effect, index) in possibleEffects"
|
||||
:key="index"
|
||||
>
|
||||
{{ formatGlyphEffect(effect) }}
|
||||
</div><br>
|
||||
<PrimaryButton
|
||||
v-if="isDoomed"
|
||||
:enabled="false"
|
||||
>
|
||||
You cannot create Reality Glyphs while in Doomed
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
v-else-if="realityGlyphLevel !== 0"
|
||||
@click="createRealityGlyph"
|
||||
>
|
||||
Create a Reality Glyph!
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
v-else
|
||||
:enabled="false"
|
||||
>
|
||||
Reality Glyph level must be higher than {{ formatInt(0) }}
|
||||
</PrimaryButton>
|
||||
</ModalWrapper>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.o-available-effects-container {
|
||||
margin: 1.5rem 0 2rem;
|
||||
}
|
||||
|
||||
.o-available-effects {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
|
@ -7,21 +7,25 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
targetSlot: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
inventoryIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
targetSlot: 0,
|
||||
target: 0,
|
||||
idx: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.targetSlot = this.modalConfig.targetSlot;
|
||||
this.idx = this.modalConfig.inventoryIndex;
|
||||
this.target = this.targetSlot;
|
||||
this.idx = this.inventoryIndex;
|
||||
this.glyph = Glyphs.findByInventoryIndex(this.idx);
|
||||
},
|
||||
handleYesClick() {
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
import { sha512_256 } from "js-sha512";
|
||||
|
||||
import ModalWrapperChoice from "@/components/modals/ModalWrapperChoice";
|
||||
import PrimaryButton from "@/components/PrimaryButton";
|
||||
import StudyStringLine from "@/components/modals/StudyStringLine";
|
||||
|
||||
export default {
|
||||
name: "StudyStringModal",
|
||||
components: {
|
||||
ModalWrapperChoice,
|
||||
StudyStringLine
|
||||
StudyStringLine,
|
||||
PrimaryButton
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
|
@ -26,7 +28,7 @@ export default {
|
|||
// This modal is used by both study importing and preset editing but only has a prop actually passed in when
|
||||
// editing (which is the preset index). Needs to be an undefined check because index can be zero
|
||||
isImporting() {
|
||||
return this.modalConfig.id === undefined;
|
||||
return this.id === undefined;
|
||||
},
|
||||
// This represents the state reached from importing into an empty tree
|
||||
importedTree() {
|
||||
|
@ -119,7 +121,7 @@ export default {
|
|||
},
|
||||
// Needs to be assigned in created() or else they will end up being undefined when importing
|
||||
created() {
|
||||
const preset = player.timestudy.presets[this.modalConfig.id];
|
||||
const preset = player.timestudy.presets[this.id];
|
||||
this.input = preset ? preset.studies : "";
|
||||
this.name = preset ? preset.name : "";
|
||||
},
|
||||
|
@ -131,6 +133,9 @@ export default {
|
|||
if (this.isImporting) this.importTree();
|
||||
else this.savePreset();
|
||||
},
|
||||
convertInputShorthands() {
|
||||
this.input = TimeStudyTree.formatStudyList(this.input);
|
||||
},
|
||||
importTree() {
|
||||
if (!this.inputIsValid) return;
|
||||
if (this.inputIsSecret) SecretAchievement(37).unlock();
|
||||
|
@ -141,7 +146,7 @@ export default {
|
|||
},
|
||||
savePreset() {
|
||||
if (this.inputIsValid) {
|
||||
player.timestudy.presets[this.modalConfig.id].studies = TimeStudyTree.formatStudyList(this.input);
|
||||
player.timestudy.presets[this.id].studies = this.input;
|
||||
GameUI.notify.eternity(`Study Tree ${this.name} successfully edited.`);
|
||||
this.emitClose();
|
||||
}
|
||||
|
@ -216,6 +221,12 @@ export default {
|
|||
Not a valid tree
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!isImporting && inputIsValidTree">
|
||||
<br>
|
||||
<PrimaryButton @click="convertInputShorthands">
|
||||
Collapse Study ID list Shorthands
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
<template #confirm-text>
|
||||
{{ isImporting ? "Import" : "Save" }}
|
||||
</template>
|
||||
|
|
73
src/components/modals/SwitchAutomatorEditorModal.vue
Normal file
73
src/components/modals/SwitchAutomatorEditorModal.vue
Normal file
|
@ -0,0 +1,73 @@
|
|||
<script>
|
||||
import ModalWrapperChoice from "@/components/modals/ModalWrapperChoice";
|
||||
|
||||
export default {
|
||||
name: "SwitchAutomatorEditorModal",
|
||||
components: {
|
||||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isCurrentlyBlocks: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentScriptID: {
|
||||
get() {
|
||||
return this.$viewModel.tabs.reality.automator.editorScriptID;
|
||||
},
|
||||
set(value) {
|
||||
this.$viewModel.tabs.reality.automator.editorScriptID = value;
|
||||
}
|
||||
},
|
||||
currentScriptContent() {
|
||||
return player.reality.automator.scripts[this.currentScriptID].content;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.isCurrentlyBlocks = player.reality.automator.type === AUTOMATOR_TYPE.BLOCK;
|
||||
},
|
||||
toggleAutomatorMode() {
|
||||
const scriptID = this.currentScriptID;
|
||||
Tutorial.moveOn(TUTORIAL_STATE.AUTOMATOR);
|
||||
if (this.isCurrentlyBlocks) {
|
||||
// This saves the script after converting it.
|
||||
BlockAutomator.parseTextFromBlocks();
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.TEXT;
|
||||
} else if (BlockAutomator.fromText(this.currentScriptContent)) {
|
||||
AutomatorBackend.saveScript(scriptID, AutomatorTextUI.editor.getDoc().getValue());
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.BLOCK;
|
||||
} else {
|
||||
Modal.message.show("Automator script has errors, cannot convert to blocks.");
|
||||
}
|
||||
this.modalConfig.callback?.();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapperChoice
|
||||
option="switchAutomatorMode"
|
||||
@confirm="toggleAutomatorMode"
|
||||
>
|
||||
<template #header>
|
||||
Change Automator to {{ isCurrentlyBlocks ? "text" : "block" }} editor
|
||||
</template>
|
||||
<div class="c-modal-message__text">
|
||||
Are you sure you want to change to the {{ isCurrentlyBlocks ? "text" : "block" }} editor?
|
||||
This will stop your current script!
|
||||
</div>
|
||||
<template #confirm-text>
|
||||
Change Modes
|
||||
</template>
|
||||
</ModalWrapperChoice>
|
||||
</template>
|
|
@ -6,16 +6,19 @@ export default {
|
|||
components: {
|
||||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
challenge() {
|
||||
return EternityChallenge(this.modal.id);
|
||||
return EternityChallenge(this.id);
|
||||
},
|
||||
challengeIsCompleted() {
|
||||
return this.challenge.isFullyCompleted;
|
||||
},
|
||||
modal() {
|
||||
return this.$viewModel.modal.current;
|
||||
},
|
||||
message() {
|
||||
return `You will Eternity, if possible, and start a new Eternity within the Challenge, with all the
|
||||
Challenge-specific restrictions and modifiers active.
|
||||
|
@ -25,7 +28,7 @@ export default {
|
|||
${formatInt(5)} times, with increasing goals and bonuses.`;
|
||||
},
|
||||
entranceLabel() {
|
||||
return `You are about to enter Eternity Challenge ${this.modal.id}`;
|
||||
return `You are about to enter Eternity Challenge ${this.id}`;
|
||||
},
|
||||
reward() {
|
||||
let rewardDescription = this.challenge._config.reward.description;
|
||||
|
|
|
@ -6,26 +6,29 @@ export default {
|
|||
components: {
|
||||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
challenge() {
|
||||
return InfinityChallenge(this.modal.id);
|
||||
return InfinityChallenge(this.id);
|
||||
},
|
||||
challengeIsCompleted() {
|
||||
return this.challenge.isCompleted;
|
||||
},
|
||||
modal() {
|
||||
return this.$viewModel.modal.current;
|
||||
},
|
||||
message() {
|
||||
return `You will Big Crunch, if possible, and start a new Infinity within the Challenge, with all the
|
||||
Challenge-specific restrictions and modifiers active.
|
||||
To complete the Challenge${this.challengeIsCompleted ? "" : " and gain its reward"},
|
||||
you must reach the Challenge goal of
|
||||
${format(InfinityChallenge(this.modal.id).goal)} Antimatter.
|
||||
${format(InfinityChallenge(this.id).goal)} Antimatter.
|
||||
You do not start with any Dimension Boosts or Galaxies, regardless of upgrades.`;
|
||||
},
|
||||
entranceLabel() {
|
||||
return `You are about to enter Infinity Challenge ${this.modal.id}`;
|
||||
return `You are about to enter Infinity Challenge ${this.id}`;
|
||||
},
|
||||
reward() {
|
||||
let rewardDescription = this.challenge._config.reward.description;
|
||||
|
|
|
@ -6,16 +6,19 @@ export default {
|
|||
components: {
|
||||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
challenge() {
|
||||
return NormalChallenge(this.modal.id);
|
||||
return NormalChallenge(this.id);
|
||||
},
|
||||
challengeIsCompleted() {
|
||||
return this.challenge.isCompleted;
|
||||
},
|
||||
modal() {
|
||||
return this.$viewModel.modal.current;
|
||||
},
|
||||
message() {
|
||||
return `You will Big Crunch, if possible, and start a new Infinity within the Challenge, with all the
|
||||
Challenge-specific restrictions and modifiers active.
|
||||
|
@ -24,7 +27,7 @@ export default {
|
|||
You do not start with any Dimension Boosts or Galaxies, regardless of upgrades.`;
|
||||
},
|
||||
entranceLabel() {
|
||||
return `You are about to enter Challenge ${this.modal.id}`;
|
||||
return `You are about to enter Challenge ${this.id}`;
|
||||
},
|
||||
reward() {
|
||||
return `The reward for completing this challenge is: ${this.challenge._config.reward}`;
|
||||
|
|
|
@ -12,9 +12,6 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
modal() {
|
||||
return this.$viewModel.modal.current;
|
||||
},
|
||||
message() {
|
||||
switch (this.messageIndex) {
|
||||
case 0: return "Are you sure you want to get rid of your Companion Glyph?";
|
||||
|
|
|
@ -7,8 +7,8 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
idx: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
@ -19,12 +19,12 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
glyph() {
|
||||
return Glyphs.findByInventoryIndex(this.modalConfig.idx);
|
||||
return Glyphs.findByInventoryIndex(this.idx);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
const newGlyph = Glyphs.findByInventoryIndex(this.modalConfig.idx);
|
||||
const newGlyph = Glyphs.findByInventoryIndex(this.idx);
|
||||
if (this.glyph !== newGlyph && this.confirmedDelete) {
|
||||
|
||||
// Why is confirmedDelete here: refer to SacrificeGlyphModal.vue
|
||||
|
|
|
@ -7,8 +7,8 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
harsh: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
@ -19,9 +19,6 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
harsh() {
|
||||
return this.modalConfig.harsh;
|
||||
},
|
||||
threshold() {
|
||||
return this.harsh ? 1 : 5;
|
||||
},
|
||||
|
|
|
@ -7,8 +7,8 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
idx: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
@ -24,7 +24,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
glyph() {
|
||||
return Glyphs.findByInventoryIndex(this.modalConfig.idx);
|
||||
return Glyphs.findByInventoryIndex(this.idx);
|
||||
},
|
||||
resource() {
|
||||
return GlyphSacrificeHandler.glyphAlchemyResource(this.glyph);
|
||||
|
@ -43,7 +43,7 @@ export default {
|
|||
|
||||
this.after = this.resourceAmount + this.gain;
|
||||
|
||||
const newGlyph = Glyphs.findByInventoryIndex(this.modalConfig.idx);
|
||||
const newGlyph = Glyphs.findByInventoryIndex(this.idx);
|
||||
if (this.glyph !== newGlyph && !this.confirmedRefine) {
|
||||
|
||||
// Why is confirmedRefine here: refer to SacrificeGlyphModal.vue
|
||||
|
|
|
@ -7,8 +7,8 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
idx: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
@ -21,7 +21,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
glyph() {
|
||||
return Glyphs.findByInventoryIndex(this.modalConfig.idx);
|
||||
return Glyphs.findByInventoryIndex(this.idx);
|
||||
},
|
||||
message() {
|
||||
return `Do you really want to sacrifice this Glyph? Your total power of sacrificed ${this.glyph.type}
|
||||
|
@ -34,7 +34,7 @@ export default {
|
|||
this.currentGlyphSacrifice = player.reality.glyphs.sac[this.glyph.type];
|
||||
this.gain = GlyphSacrificeHandler.glyphSacrificeGain(this.glyph);
|
||||
|
||||
const newGlyph = Glyphs.findByInventoryIndex(this.modalConfig.idx);
|
||||
const newGlyph = Glyphs.findByInventoryIndex(this.idx);
|
||||
if (this.glyph !== newGlyph && !this.confirmedSacrifice) {
|
||||
|
||||
// ConfirmedSacrifice is here because when you sac a glyph with confirmation it
|
||||
|
|
|
@ -7,8 +7,8 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
bulk: {
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
|
@ -21,7 +21,6 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
bulk() { return this.modalConfig.bulk; },
|
||||
topLabel() {
|
||||
if (this.bulk) return `You are about to purchase ${quantifyInt("Antimatter Galaxy", this.newGalaxies)}`;
|
||||
return `You are about to purchase an Antimatter Galaxy`;
|
||||
|
|
|
@ -7,13 +7,12 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
bulk: {
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
bulk() { return this.modalConfig.bulk; },
|
||||
topLabel() {
|
||||
return `You are about to do a Dimension Boost Reset`;
|
||||
},
|
||||
|
|
|
@ -9,20 +9,24 @@ export default {
|
|||
EnterCelestialsRaPet,
|
||||
},
|
||||
props: {
|
||||
modalConfig: {
|
||||
type: Object,
|
||||
number: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
description() {
|
||||
return GameDatabase.celestials.descriptions[this.modalConfig.number].description().split("\n");
|
||||
return GameDatabase.celestials.descriptions[this.number].description().split("\n");
|
||||
},
|
||||
topLabel() {
|
||||
return `${this.modalConfig.name} Reality`;
|
||||
return `${this.name} Reality`;
|
||||
},
|
||||
message() {
|
||||
return `Perform a Reality reset, and enter ${this.modalConfig.name} Reality, in which`;
|
||||
return `Perform a Reality reset, and enter ${this.name} Reality, in which`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -37,7 +41,7 @@ export default {
|
|||
const laitelaFastest = player.celestials.laitela.fastestCompletion;
|
||||
const laitalaTime = TimeSpan.fromSeconds(laitelaFastest).toStringShort();
|
||||
|
||||
switch (this.modalConfig.number) {
|
||||
switch (this.number) {
|
||||
case 0: return `Your highest Teresa completetion was for ${format(teresaBestAM, 2, 2)}
|
||||
antimatter, gaining you a ${formatX(teresaRunMult, 2)} multiplier to Glyph Sacrifice power.`;
|
||||
case 1: return `${effarigDone
|
||||
|
@ -64,7 +68,7 @@ export default {
|
|||
},
|
||||
handleYesClick() {
|
||||
beginProcessReality(getRealityProps(true));
|
||||
switch (this.modalConfig.number) {
|
||||
switch (this.number) {
|
||||
case 0: return Teresa.initializeRun();
|
||||
case 1: return Effarig.initializeRun();
|
||||
case 2: return Enslaved.initializeRun();
|
||||
|
@ -95,7 +99,7 @@ export default {
|
|||
<div>
|
||||
{{ extraLine() }}
|
||||
</div>
|
||||
<span v-if="modalConfig.number === 4">
|
||||
<span v-if="number === 4">
|
||||
<EnterCelestialsRaPet
|
||||
v-for="id in 4"
|
||||
:key="id"
|
||||
|
|
|
@ -8,9 +8,6 @@ export default {
|
|||
ModalWrapperChoice
|
||||
},
|
||||
computed: {
|
||||
modal() {
|
||||
return this.$viewModel.modal.current;
|
||||
},
|
||||
message() {
|
||||
return `Dilating time will start a new Eternity, and all Dimension multiplier's exponents and
|
||||
tickspeed multiplier's exponent will be reduced to ${formatPow(0.75, 2, 2)}. If you can Eternity while Dilated,
|
||||
|
|
|
@ -21,6 +21,7 @@ export default {
|
|||
alchemyCap: 0,
|
||||
capFactor: 0,
|
||||
createdRealityGlyph: false,
|
||||
allReactionsDisabled: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -46,6 +47,9 @@ export default {
|
|||
"tutorial--glow": !this.createdRealityGlyph
|
||||
};
|
||||
},
|
||||
reactions() {
|
||||
return AlchemyReactions.all.compact().filter(r => r.product.isUnlocked);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
|
@ -55,6 +59,7 @@ export default {
|
|||
this.alchemyCap = Ra.alchemyResourceCap;
|
||||
this.capFactor = 1 / GlyphSacrificeHandler.glyphRefinementEfficiency;
|
||||
this.createdRealityGlyph = player.reality.glyphs.createdRealityGlyph;
|
||||
this.allReactionsDisabled = this.reactions.every(reaction => !reaction.isActive);
|
||||
},
|
||||
orbitSize(orbit) {
|
||||
const maxRadius = this.layout.orbits.map(o => o.radius).max();
|
||||
|
@ -151,18 +156,11 @@ export default {
|
|||
Modal.h2p.show();
|
||||
},
|
||||
toggleAllReactions() {
|
||||
const reactions = AlchemyReactions.all.compact().filter(r => r._product.isUnlocked);
|
||||
const allReactionsDisabled = reactions.every(reaction => !reaction.isActive);
|
||||
if (allReactionsDisabled) {
|
||||
for (const reaction of reactions) {
|
||||
reaction.isActive = true;
|
||||
}
|
||||
} else {
|
||||
for (const reaction of reactions) {
|
||||
reaction.isActive = false;
|
||||
}
|
||||
const setIsActive = this.allReactionsDisabled;
|
||||
for (const reaction of this.reactions) {
|
||||
reaction.isActive = setIsActive;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -180,7 +178,7 @@ export default {
|
|||
class="o-primary-btn--subtab-option"
|
||||
@click="toggleAllReactions"
|
||||
>
|
||||
Toggle all reactions
|
||||
{{ allReactionsDisabled ? "Enable" : "Disable" }} all reactions
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
v-if="realityCreationVisible"
|
||||
|
|
|
@ -13,6 +13,12 @@ export default {
|
|||
repeatOn: false,
|
||||
forceRestartOn: false,
|
||||
followExecution: false,
|
||||
hasErrors: false,
|
||||
currentLine: 0,
|
||||
statusName: "",
|
||||
editingName: "",
|
||||
duplicateStatus: false,
|
||||
duplicateEditing: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -32,6 +38,18 @@ export default {
|
|||
"fa-eject": this.isPaused
|
||||
};
|
||||
},
|
||||
statusText() {
|
||||
// Pad with leading zeroes based on script length to prevent text jitter on fast scripts. This technically fails
|
||||
// for scripts with more than 99999 lines, but scripts that long will be prevented elsewhere
|
||||
const digits = Math.clampMin(Math.ceil(Math.log10(AutomatorBackend.currentScriptLength + 1)), 1);
|
||||
let lineNum = `0000${this.currentLine}`;
|
||||
lineNum = lineNum.slice(lineNum.length - digits);
|
||||
|
||||
if (this.isPaused) return `Paused: "${this.statusName}" (Resumes on Line ${lineNum})`;
|
||||
if (this.isRunning) return `Running: "${this.statusName}" (Line ${lineNum})`;
|
||||
if (this.hasErrors) return `Stopped: "${this.statusName}" has errors (Cannot run)`;
|
||||
return `Stopped: Will start running "${this.statusName}"`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
|
@ -40,9 +58,21 @@ export default {
|
|||
this.repeatOn = AutomatorBackend.state.repeat;
|
||||
this.forceRestartOn = AutomatorBackend.state.forceRestart;
|
||||
this.followExecution = AutomatorBackend.state.followExecution;
|
||||
this.hasErrors = AutomatorData.currentErrors().length !== 0;
|
||||
this.currentLine = AutomatorBackend.currentLineNumber;
|
||||
|
||||
// When the automator isn't running, the script name contains the last run script instead of the
|
||||
// to-be-run script, which is the currently displayed one in the editor
|
||||
this.statusName = (this.isPaused || this.isRunning)
|
||||
? AutomatorBackend.scriptName
|
||||
: AutomatorBackend.currentEditingScript.name;
|
||||
this.editingName = AutomatorBackend.currentEditingScript.name;
|
||||
this.duplicateStatus = AutomatorBackend.hasDuplicateName(this.statusName);
|
||||
this.duplicateEditing = AutomatorBackend.hasDuplicateName(this.editingName);
|
||||
},
|
||||
rewind: () => AutomatorBackend.restart(),
|
||||
play() {
|
||||
if (this.hasErrors) return;
|
||||
if (this.isRunning) {
|
||||
AutomatorBackend.pause();
|
||||
return;
|
||||
|
@ -64,52 +94,99 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="c-automator__controls l-automator__controls l-automator-pane__controls">
|
||||
<AutomatorButton
|
||||
v-tooltip="'Rewind Automator to the first command'"
|
||||
class="fa-fast-backward"
|
||||
@click="rewind"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="{
|
||||
content: playTooltip,
|
||||
hideOnTargetClick: false
|
||||
}"
|
||||
:class="playButtonClass"
|
||||
@click="play"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Stop Automator and reset position'"
|
||||
class="fa-stop"
|
||||
@click="stop"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Step forward one line'"
|
||||
class="fa-step-forward"
|
||||
@click="step"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Restart script automatically when it completes'"
|
||||
class="fa-sync-alt"
|
||||
:class="{ 'c-automator__button--active' : repeatOn }"
|
||||
@click="repeat"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Restart script when finishing or restarting a Reality'"
|
||||
class="fa-reply"
|
||||
:class="{ 'c-automator__button--active' : forceRestartOn }"
|
||||
@click="restart"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Scroll Automator to follow current line'"
|
||||
class="fa-indent"
|
||||
:class="{ 'c-automator__button--active' : followExecution }"
|
||||
@click="follow"
|
||||
/>
|
||||
<div class="c-automator__controls l-automator__controls">
|
||||
<div class="l-automator-button-row">
|
||||
<AutomatorButton
|
||||
v-tooltip="'Rewind Automator to the first command'"
|
||||
class="fa-fast-backward"
|
||||
@click="rewind"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="{
|
||||
content: playTooltip,
|
||||
hideOnTargetClick: false
|
||||
}"
|
||||
:class="playButtonClass"
|
||||
@click="play"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Stop Automator and reset position'"
|
||||
class="fa-stop"
|
||||
@click="stop"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Step forward one line'"
|
||||
class="fa-step-forward"
|
||||
@click="step"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Restart script automatically when it completes'"
|
||||
class="fa-sync-alt"
|
||||
:class="{ 'c-automator__button--active' : repeatOn }"
|
||||
@click="repeat"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Restart script when finishing or restarting a Reality'"
|
||||
class="fa-reply"
|
||||
:class="{ 'c-automator__button--active' : forceRestartOn }"
|
||||
@click="restart"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Scroll Automator to follow current line'"
|
||||
class="fa-indent"
|
||||
:class="{ 'c-automator__button--active' : followExecution }"
|
||||
@click="follow"
|
||||
/>
|
||||
<div class="c-automator__status-text c-automator__status-text--edit">
|
||||
<span
|
||||
v-if="duplicateEditing"
|
||||
v-tooltip="'More than one script has this name!'"
|
||||
class="fas fa-exclamation-triangle c-automator__status-text--error"
|
||||
/>
|
||||
{{ editingName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="l-automator-button-row">
|
||||
<span
|
||||
v-if="duplicateStatus"
|
||||
v-tooltip="'More than one script has this name!'"
|
||||
class="fas fa-exclamation-triangle c-automator__status-text c-automator__status-text--error"
|
||||
/>
|
||||
<span
|
||||
v-if="statusName !== editingName"
|
||||
v-tooltip="'The automator is running a different script than the editor is showing'"
|
||||
class="fas fa-circle-exclamation c-automator__status-text c-automator__status-text--warning"
|
||||
/>
|
||||
<span
|
||||
class="c-automator__status-text"
|
||||
:class="{ 'c-automator__status-text--error' : hasErrors && !isRunning }"
|
||||
>
|
||||
{{ statusText }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.c-automator__status-text {
|
||||
font-size: 1.5rem;
|
||||
color: var(--color-reality);
|
||||
font-weight: bold;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.c-automator__status-text--edit {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.c-automator__status-text--warning {
|
||||
color: var(--color-good-paused);
|
||||
}
|
||||
|
||||
.c-automator__status-text--error {
|
||||
color: var(--color-bad);
|
||||
}
|
||||
|
||||
.c-automator__button--active {
|
||||
background-color: var(--color-reality);
|
||||
border-color: var(--color-reality-light);
|
||||
|
|
|
@ -5,6 +5,7 @@ import AutomatorDocsCommandList from "./AutomatorDocsCommandList";
|
|||
import AutomatorDocsTemplateList from "./AutomatorDocsTemplateList";
|
||||
import AutomatorErrorPage from "./AutomatorErrorPage";
|
||||
import AutomatorEventLog from "./AutomatorEventLog";
|
||||
import AutomatorModeSwitch from "./AutomatorModeSwitch";
|
||||
|
||||
export default {
|
||||
name: "AutomatorDocs",
|
||||
|
@ -14,7 +15,8 @@ export default {
|
|||
AutomatorErrorPage,
|
||||
AutomatorEventLog,
|
||||
AutomatorBlocks,
|
||||
AutomatorDocsTemplateList
|
||||
AutomatorDocsTemplateList,
|
||||
AutomatorModeSwitch,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -128,6 +130,10 @@ export default {
|
|||
this.currentScriptID = Object.keys(storedScripts)[0];
|
||||
player.reality.automator.state.editorScript = this.currentScriptID;
|
||||
}
|
||||
if (!AutomatorGrammar.blockifyTextAutomator(this.currentScript)) {
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.TEXT;
|
||||
Modal.message.show("Automator script has errors, cannot view in blocks.");
|
||||
}
|
||||
this.$nextTick(() => BlockAutomator.fromText(this.currentScript));
|
||||
},
|
||||
rename() {
|
||||
|
@ -178,87 +184,93 @@ export default {
|
|||
|
||||
<template>
|
||||
<div class="l-automator-pane">
|
||||
<div class="c-automator__controls l-automator__controls l-automator-pane__controls">
|
||||
<AutomatorButton
|
||||
v-tooltip="'Scripting Information'"
|
||||
class="fa-list"
|
||||
:class="{ 'c-automator__button--active': infoPaneID === 1 }"
|
||||
@click="infoPaneID = 1"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="blockTooltip"
|
||||
:class="{
|
||||
'fa-cubes': isBlock,
|
||||
'fa-file-code': !isBlock,
|
||||
'c-automator__button--active': infoPaneID === 2
|
||||
}"
|
||||
@click="infoPaneID = 2"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="errorTooltip"
|
||||
:style="errorStyle"
|
||||
class="fa-exclamation-triangle"
|
||||
:class="{ 'c-automator__button--active': infoPaneID === 3 }"
|
||||
@click="infoPaneID = 3"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'View recently executed commands'"
|
||||
class="fa-eye"
|
||||
:class="{ 'c-automator__button--active': infoPaneID === 4 }"
|
||||
@click="infoPaneID = 4"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Export automator script'"
|
||||
class="fa-file-export"
|
||||
@click="exportScript"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Import automator script'"
|
||||
class="fa-file-import"
|
||||
@click="importScript"
|
||||
/>
|
||||
<div class="l-automator__script-names">
|
||||
<template v-if="!editingName">
|
||||
<select
|
||||
class="l-automator__scripts-dropdown"
|
||||
@input="onScriptDropdown"
|
||||
>
|
||||
<option
|
||||
v-for="script in scripts"
|
||||
:key="script.id"
|
||||
v-bind="selectedScriptAttribute(script.id)"
|
||||
:value="script.id"
|
||||
>
|
||||
{{ dropdownLabel(script) }}
|
||||
</option>
|
||||
<option value="createNewScript">
|
||||
Create new...
|
||||
</option>
|
||||
</select>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Rename script'"
|
||||
class="far fa-edit"
|
||||
@click="rename"
|
||||
/>
|
||||
</template>
|
||||
<input
|
||||
v-else
|
||||
ref="renameInput"
|
||||
class="l-automator__rename-input"
|
||||
@blur="nameEdited"
|
||||
@keyup.enter="$refs.renameInput.blur()"
|
||||
>
|
||||
<div class="c-automator__controls l-automator__controls">
|
||||
<div class="l-automator-button-row">
|
||||
<AutomatorButton
|
||||
v-tooltip="'Scripting Information'"
|
||||
class="fa-list"
|
||||
:class="{ 'c-automator__button--active': infoPaneID === 1 }"
|
||||
@click="infoPaneID = 1"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="blockTooltip"
|
||||
:class="{
|
||||
'fa-cubes': isBlock,
|
||||
'fa-file-code': !isBlock,
|
||||
'c-automator__button--active': infoPaneID === 2
|
||||
}"
|
||||
@click="infoPaneID = 2"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="errorTooltip"
|
||||
:style="errorStyle"
|
||||
class="fa-exclamation-triangle"
|
||||
:class="{ 'c-automator__button--active': infoPaneID === 3 }"
|
||||
@click="infoPaneID = 3"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'View recently executed commands'"
|
||||
class="fa-eye"
|
||||
:class="{ 'c-automator__button--active': infoPaneID === 4 }"
|
||||
@click="infoPaneID = 4"
|
||||
/>
|
||||
<AutomatorModeSwitch />
|
||||
<AutomatorButton
|
||||
v-tooltip="fullScreenTooltip"
|
||||
:class="fullScreenIconClass"
|
||||
class="l-automator__expand-corner"
|
||||
@click="fullScreen = !fullScreen"
|
||||
/>
|
||||
</div>
|
||||
<div class="l-automator-button-row">
|
||||
<AutomatorButton
|
||||
v-tooltip="'Export automator script'"
|
||||
class="fa-file-export"
|
||||
@click="exportScript"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Import automator script'"
|
||||
class="fa-file-import"
|
||||
@click="importScript"
|
||||
/>
|
||||
<div class="l-automator__script-names">
|
||||
<template v-if="!editingName">
|
||||
<select
|
||||
class="l-automator__scripts-dropdown"
|
||||
@input="onScriptDropdown"
|
||||
>
|
||||
<option
|
||||
v-for="script in scripts"
|
||||
:key="script.id"
|
||||
v-bind="selectedScriptAttribute(script.id)"
|
||||
:value="script.id"
|
||||
>
|
||||
{{ dropdownLabel(script) }}
|
||||
</option>
|
||||
<option value="createNewScript">
|
||||
Create new...
|
||||
</option>
|
||||
</select>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Rename script'"
|
||||
class="far fa-edit"
|
||||
@click="rename"
|
||||
/>
|
||||
</template>
|
||||
<input
|
||||
v-else
|
||||
ref="renameInput"
|
||||
class="l-automator__rename-input"
|
||||
@blur="nameEdited"
|
||||
@keyup.enter="$refs.renameInput.blur()"
|
||||
>
|
||||
</div>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Delete this script'"
|
||||
class="fas fa-trash"
|
||||
@click="deleteScript"
|
||||
/>
|
||||
</div>
|
||||
<AutomatorButton
|
||||
v-tooltip="'Delete this script'"
|
||||
class="fas fa-trash"
|
||||
@click="deleteScript"
|
||||
/>
|
||||
<AutomatorButton
|
||||
v-tooltip="fullScreenTooltip"
|
||||
:class="fullScreenIconClass"
|
||||
@click="fullScreen = !fullScreen"
|
||||
/>
|
||||
</div>
|
||||
<div class="c-automator-docs l-automator-pane__content">
|
||||
<AutomatorDocsCommandList v-if="infoPaneID === 1" />
|
||||
|
@ -273,6 +285,28 @@ export default {
|
|||
</template>
|
||||
|
||||
<style scoped>
|
||||
.l-automator__expand-corner {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.l-automator__script-names {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 50%;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.l-automator__scripts-dropdown {
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
border-width: 0.1rem;
|
||||
border-radius: 0;
|
||||
margin: 0.4rem;
|
||||
padding: 0.2rem 0 0.3rem;
|
||||
}
|
||||
|
||||
.c-automator__button--active {
|
||||
background-color: var(--color-reality);
|
||||
border-color: var(--color-reality-light);
|
||||
|
|
|
@ -12,13 +12,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
activeLineRaw: 0,
|
||||
automatorType: 0,
|
||||
runningScriptID: 0,
|
||||
activeLineInfo: {
|
||||
lineNumber: 0,
|
||||
scriptID: 0,
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -42,18 +36,6 @@ export default {
|
|||
isTextAutomator() {
|
||||
return this.automatorType === AUTOMATOR_TYPE.TEXT;
|
||||
},
|
||||
activeLine() {
|
||||
return AutomatorBackend.state.topLevelScript === this.currentScriptID ? this.activeLineRaw : 0;
|
||||
},
|
||||
automatorModeTooltip() {
|
||||
if (this.automatorType === AUTOMATOR_TYPE.BLOCK) return "Switch to the text editor";
|
||||
return "Switch to the block editor";
|
||||
},
|
||||
tutorialClass() {
|
||||
return {
|
||||
"tutorial--glow": ui.view.tutorialState === TUTORIAL_STATE.AUTOMATOR && ui.view.tutorialActive
|
||||
};
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.on$(GAME_EVENT.GAME_LOAD, () => this.onGameLoad());
|
||||
|
@ -62,20 +44,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.runningScriptID = AutomatorBackend.state.topLevelScript;
|
||||
this.automatorType = player.reality.automator.type;
|
||||
if (AutomatorBackend.isOn) {
|
||||
this.activeLineInfo = {
|
||||
lineNumber: AutomatorBackend.stack.top.lineNumber,
|
||||
scriptID: AutomatorBackend.state.topLevelScript,
|
||||
};
|
||||
} else {
|
||||
this.activeLineInfo = {
|
||||
lineNumber: 0,
|
||||
scriptID: "0",
|
||||
};
|
||||
if (AutomatorTextUI.editor) AutomatorTextUI.editor.performLint();
|
||||
}
|
||||
if (!AutomatorBackend.isOn && AutomatorTextUI.editor) AutomatorTextUI.editor.performLint();
|
||||
},
|
||||
onGameLoad() {
|
||||
this.updateCurrentScriptID();
|
||||
|
@ -95,44 +65,14 @@ export default {
|
|||
}
|
||||
this.$nextTick(() => BlockAutomator.fromText(this.currentScript));
|
||||
},
|
||||
toggleAutomatorMode() {
|
||||
const scriptID = ui.view.tabs.reality.automator.editorScriptID;
|
||||
Tutorial.moveOn(TUTORIAL_STATE.AUTOMATOR);
|
||||
if (this.automatorType === AUTOMATOR_TYPE.BLOCK) {
|
||||
// This saves the script after converting it.
|
||||
BlockAutomator.parseTextFromBlocks();
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.TEXT;
|
||||
} else if (BlockAutomator.fromText(this.currentScriptContent)) {
|
||||
AutomatorBackend.saveScript(scriptID, AutomatorTextUI.editor.getDoc().getValue());
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.BLOCK;
|
||||
} else {
|
||||
Modal.message.show("Automator script has errors, cannot convert to blocks.");
|
||||
}
|
||||
this.$recompute("currentScriptContent");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="l-automator-pane">
|
||||
<div class="c-automator__controls l-automator__controls l-automator-pane__controls">
|
||||
<div class="c-automator__controls l-automator__controls">
|
||||
<AutomatorControls />
|
||||
<button
|
||||
v-tooltip="{
|
||||
content: automatorModeTooltip,
|
||||
hideOnTargetClick: false
|
||||
}"
|
||||
:class="{
|
||||
'c-slider-toggle-button': true,
|
||||
'c-slider-toggle-button--right': isTextAutomator,
|
||||
...tutorialClass
|
||||
}"
|
||||
@click="toggleAutomatorMode"
|
||||
>
|
||||
<i class="fas fa-cubes" />
|
||||
<i class="fas fa-code" />
|
||||
</button>
|
||||
</div>
|
||||
<AutomatorTextEditor
|
||||
v-if="isTextAutomator"
|
||||
|
@ -141,47 +81,3 @@ export default {
|
|||
<AutomatorBlockEditor v-if="!isTextAutomator" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.c-slider-toggle-button {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
color: black;
|
||||
background-color: #626262;
|
||||
border: 0.2rem solid #767676;
|
||||
border-radius: 0.2rem;
|
||||
margin: 0.4rem;
|
||||
padding: 0.3rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.c-slider-toggle-button .fas {
|
||||
width: 3rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.c-slider-toggle-button::before {
|
||||
content: "";
|
||||
width: 3rem;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
background-color: white;
|
||||
border-radius: 0.2rem;
|
||||
transition: 0.3s ease all;
|
||||
}
|
||||
|
||||
.c-slider-toggle-button--right::before {
|
||||
left: 3rem;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.tutorial--glow::after {
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
||||
|
|
151
src/components/tabs/automator/AutomatorModeSwitch.vue
Normal file
151
src/components/tabs/automator/AutomatorModeSwitch.vue
Normal file
|
@ -0,0 +1,151 @@
|
|||
<script>
|
||||
export default {
|
||||
name: "AutomatorModeSwitch",
|
||||
data() {
|
||||
return {
|
||||
automatorType: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentScriptID: {
|
||||
get() {
|
||||
return this.$viewModel.tabs.reality.automator.editorScriptID;
|
||||
},
|
||||
set(value) {
|
||||
this.$viewModel.tabs.reality.automator.editorScriptID = value;
|
||||
}
|
||||
},
|
||||
currentScriptContent() {
|
||||
return player.reality.automator.scripts[this.currentScriptID].content;
|
||||
},
|
||||
currentScript() {
|
||||
return CodeMirror.Doc(this.currentScriptContent, "automato").getValue();
|
||||
},
|
||||
isTextAutomator() {
|
||||
return this.automatorType === AUTOMATOR_TYPE.TEXT;
|
||||
},
|
||||
automatorModeTooltip() {
|
||||
if (this.automatorType === AUTOMATOR_TYPE.BLOCK) return "Switch to the text editor";
|
||||
return "Switch to the block editor";
|
||||
},
|
||||
tutorialClass() {
|
||||
return {
|
||||
"tutorial--glow": ui.view.tutorialState === TUTORIAL_STATE.AUTOMATOR && ui.view.tutorialActive
|
||||
};
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.on$(GAME_EVENT.GAME_LOAD, () => this.onGameLoad());
|
||||
this.on$(GAME_EVENT.AUTOMATOR_SAVE_CHANGED, () => this.onGameLoad());
|
||||
this.updateCurrentScriptID();
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.automatorType = player.reality.automator.type;
|
||||
},
|
||||
onGameLoad() {
|
||||
this.updateCurrentScriptID();
|
||||
},
|
||||
updateCurrentScriptID() {
|
||||
const storedScripts = player.reality.automator.scripts;
|
||||
this.currentScriptID = player.reality.automator.state.editorScript;
|
||||
// This shouldn't happen if things are loaded in the right order, but might as well be sure.
|
||||
if (storedScripts[this.currentScriptID] === undefined) {
|
||||
this.currentScriptID = Object.keys(storedScripts)[0];
|
||||
player.reality.automator.state.editorScript = this.currentScriptID;
|
||||
}
|
||||
if (AutomatorData.currentErrors().length !== 0 && player.reality.automator.type === AUTOMATOR_TYPE.BLOCK) {
|
||||
Modal.message.show(`Switched to text editor mode; this script has errors
|
||||
which cannot be converted to block mode.`);
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.TEXT;
|
||||
}
|
||||
this.$nextTick(() => BlockAutomator.fromText(this.currentScript));
|
||||
},
|
||||
toggleAutomatorMode() {
|
||||
if (AutomatorBackend.state.mode === AUTOMATOR_MODE.PAUSE || !player.options.confirmations.switchAutomatorMode) {
|
||||
const scriptID = this.currentScriptID;
|
||||
Tutorial.moveOn(TUTORIAL_STATE.AUTOMATOR);
|
||||
if (this.automatorType === AUTOMATOR_TYPE.BLOCK) {
|
||||
// This saves the script after converting it.
|
||||
BlockAutomator.parseTextFromBlocks();
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.TEXT;
|
||||
} else if (BlockAutomator.fromText(this.currentScriptContent)) {
|
||||
AutomatorBackend.saveScript(scriptID, AutomatorTextUI.editor.getDoc().getValue());
|
||||
player.reality.automator.type = AUTOMATOR_TYPE.BLOCK;
|
||||
} else {
|
||||
Modal.message.show("Automator script has errors, cannot convert to blocks.");
|
||||
}
|
||||
this.$recompute("currentScriptContent");
|
||||
} else {
|
||||
Modal.switchAutomatorEditorMode.show({
|
||||
callBack: () => this.$recompute("currentScriptContent")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="c-automator__controls l-automator__controls">
|
||||
<button
|
||||
v-tooltip="{
|
||||
content: automatorModeTooltip,
|
||||
hideOnTargetClick: false
|
||||
}"
|
||||
:class="{
|
||||
'c-slider-toggle-button': true,
|
||||
'c-slider-toggle-button--right': isTextAutomator,
|
||||
...tutorialClass
|
||||
}"
|
||||
@click="toggleAutomatorMode"
|
||||
>
|
||||
<i class="fas fa-cubes" />
|
||||
<i class="fas fa-code" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.c-slider-toggle-button {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
color: black;
|
||||
background-color: #626262;
|
||||
border: 0.2rem solid #767676;
|
||||
border-radius: 0.2rem;
|
||||
margin: 0.2rem 0.4rem;
|
||||
padding: 0.3rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.c-slider-toggle-button .fas {
|
||||
width: 3rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.c-slider-toggle-button::before {
|
||||
content: "";
|
||||
width: 3rem;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
background-color: white;
|
||||
border-radius: 0.2rem;
|
||||
transition: 0.3s ease all;
|
||||
}
|
||||
|
||||
.c-slider-toggle-button--right::before {
|
||||
left: 3rem;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.tutorial--glow::after {
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
|
@ -179,7 +179,3 @@ export const AutomatorTextUI = {
|
|||
class="c-automator-editor l-automator-editor l-automator-pane__content"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
|
@ -186,12 +186,12 @@ export default {
|
|||
background: black;
|
||||
}
|
||||
|
||||
@keyframes roll {
|
||||
@keyframes a-roll {
|
||||
100% { transform: rotateY(360deg); }
|
||||
}
|
||||
|
||||
.pelle-icon {
|
||||
animation: roll infinite 8s linear;
|
||||
animation: a-roll infinite 8s linear;
|
||||
}
|
||||
|
||||
.o-celestial-quote-history {
|
||||
|
|
|
@ -130,9 +130,6 @@ export default {
|
|||
name: "Equipped Glyphs",
|
||||
glyphSet: this.glyphs,
|
||||
closeOn: GAME_EVENT.GLYPHS_EQUIPPED_CHANGED,
|
||||
isGlyphSelection: false,
|
||||
showSetName: true,
|
||||
displaySacrifice: true,
|
||||
});
|
||||
},
|
||||
clickGlyph(glyph, idx) {
|
||||
|
|
|
@ -57,7 +57,6 @@ export default {
|
|||
closeOn: GAME_EVENT.REALITY_RESET_AFTER,
|
||||
isGlyphSelection: true,
|
||||
showSetName: false,
|
||||
displaySacrifice: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ export default {
|
|||
this.ecCount = EternityChallenges.completions;
|
||||
this.missingAchievements = Achievements.preReality.countWhere(a => !a.isUnlocked);
|
||||
// Repeatable dilation upgrades don't have isBought, but do have boughtAmount
|
||||
this.unpurchasedDilationUpgrades = Object.values(DilationUpgrade)
|
||||
this.unpurchasedDilationUpgrades = DilationUpgrade.all
|
||||
.countWhere(u => (u.isBought === undefined ? u.boughtAmount === 0 : !u.isBought) && !u.config.pelleOnly);
|
||||
this.currLog10EP = player.eternityPoints.log10();
|
||||
this.cheapestLog10TD = Math.min(...TimeDimensions.all.map(x => x.cost.log10()));
|
||||
|
|
|
@ -35,7 +35,7 @@ export default {
|
|||
},
|
||||
save() {
|
||||
this.hideContextMenu();
|
||||
this.preset.studies = TimeStudyTree.formatStudyList(GameCache.currentStudyTree.value.exportString);
|
||||
this.preset.studies = GameCache.currentStudyTree.value.exportString;
|
||||
const presetName = this.name ? `Study preset "${this.name}"` : "Study preset";
|
||||
GameUI.notify.eternity(`${presetName} saved in slot ${this.saveslot}`);
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue
Block a user