antimatter, infinity, time, active, passive, idle, light, dark+ A variable name may be used in place of the entire Time Study list as well (see the definition panel), + although in that case the shorthand ranges and aliases are not allowed.` + }, + ] + } + ], + examples: [ + "studies nowait purchase 11,21,31", + "studies purchase 11-62, antimatter, 111, idle", + "studies nowait purchase ec6Studies", + ] + }, + { + id: 3, + isUnlocked: () => true, + keyword: "PRESTIGE", + category: 1, + syntax: ` + infinity [nowait]
commands- }
- tt all- }`, - ] - }, - { - id: 11, - isUnlocked: () => true, - keyword: "while", - name: "while - repeats commands while a condition is met", - syntax: `while [quantity] (comparison) [number]{
- studies nowait 11-62
commands- }
- tt all- }`, - `while myThreshold > am { ...`, - ] - }, - { - id: 12, - isUnlocked: () => true, - keyword: "studies respec", - name: "studies respec - respec Time Studies on next Eternity", - syntax: `studies respec`, - examples: [ - `studies respec`, - ] - }, - { - id: 13, - isUnlocked: () => true, - keyword: "studies load preset", - name: "studies load preset - Load a saved Time Study preset", - syntax: `studies [nowait] load preset [name | number]`, - description: `Loads a Time Study preset, as if you'd clicked on the button in the Time Study tab. - Number is 1 to 6 (corresponding to slot), but the given name can also be used. - If nowait is present, then the Automator will purchase as many Time Studies as - possible from the preset before moving on to the next command, even if some cannot be bought.
- studies nowait 11-62
antimatter, infinity, time, active, passive, idle, light, dark- A variable name may be used in place of Time Study list, see define.`, - examples: [ - "studies nowait 11,21,31", - "studies 11-62, antimatter, 111, idle", - "studies nowait ec6Studies", - ] - }, - { - id: 15, - isUnlocked: () => true, - keyword: "define", - name: "define - defining constants", - syntax: `define [constant_name] = [constant]`, - description: `Define constants for either numbers or Time Study tree imports`, - examples: [ - "define inf = 1e308", - "define studytree = 11,21,22,31,32,33" - ] - }, - { - id: 16, - isUnlocked: () => true, - keyword: "currencies", - name: "List of currencies", - syntax: "You can use these in any if, while, until, or wait command.", - description: `This is a list of "currencies" or numbers that you can use.
commands- `, - `while ec10 completions >= 1 -
commands` - ] - }, - { - id: 17, - isUnlocked: () => true, - keyword: "notify", - name: "notify - send a progress notification", - syntax: "notify \"text\"", + keyword: "NOTIFY", + category: 3, + syntax: "notify \"text\"", description: `Takes the specified text and posts it in the top-right corner as - a text notification, in the same spot as other notifications such as auto-save + a text notification, in the same spot and style as other notifications such as auto-save and achievement/upgrade unlocks. Can be useful for seeing automator status while on tabs other than the Automator tab.`, examples: [ @@ -434,20 +291,298 @@ GameDatabase.reality.automator = { ] }, { - id: 18, + id: 10, isUnlocked: () => true, - keyword: "(Comments)", - name: "#|// - leaves a comment in your script", + keyword: "Adding Comments", + category: 3, syntax: "# text
commands+ }`, + description: `Defines an inner block of block of the automator script which will only be executed if the specified + comparison is true when this line is reached. If the comparison is false, the automator will instead skip to the + first line after the block and continue execution from there.`, + examples: [ + "if ec10 completions < 5", + "if ep > 1e6000" + ] + }, + { + id: 14, + isUnlocked: () => true, + keyword: "UNTIL", + category: 4, + syntax: `until comparison {
commands+ }
commands+ }`, + description: `Defines an inner block of the script where commands are repeated; the comparison is checked at the + start and every time the loop repeats. If the condition is false when the UNTIL statement is first reached, the + inner block of commands will be skipped entirely. +
commands+ }`, + description: `Defines an inner block of the script where commands are repeated; the comparison is checked at the + start and every time the loop repeats. If the condition is false when the WHILE statement is first reached, the + inner block of commands will be skipped entirely.`, + examples: [ + `while ep < 1e500`, + `while myThreshold > am`, + ] + }, + { + id: 16, + isUnlocked: () => true, + keyword: "Currency List", + category: 4, + syntax: "You can use these in any IF, WHILE, UNTIL, or WAIT command", + description: `This is a list of "currencies" or numbers that you can use within the Automator.
inner_commands+ }`, + description: `Some commands are associated with an "inner block" of commands. This inner block can contain still + contain any other valid command, but may or may not actually get executed based on what the state of the game is + when header_command is executed. This allows you to repeat some commands over and over (eg. Time Study + purchasing), or to skip them entirely (eg. not entering an EC if it already has full completions). These blocks + can be nested if desired, with inner blocks being placed within one another. +
+ unlock ec10+ }`, + `until ep > 1e8 {
+ start ec10
+ studies nowait purchase 11-62+ }` + ] + }, ] }; diff --git a/javascripts/core/secret-formula/reality/glyph-effects.js b/javascripts/core/secret-formula/reality/glyph-effects.js new file mode 100644 index 000000000..50912a468 --- /dev/null +++ b/javascripts/core/secret-formula/reality/glyph-effects.js @@ -0,0 +1,688 @@ +import { DC } from "../../constants"; +import { GameDatabase } from "../game-database"; + +export const GlyphCombiner = Object.freeze({ + /** + * @param {number[]} x + * @returns {number} + */ + add: x => x.reduce(Number.sumReducer, 0), + /** + * @param {number[]} x + * @returns {number} + */ + multiply: x => x.reduce(Number.prodReducer, 1), + /** + * For exponents, the base value is 1, so when we add two exponents a and b we want to get a + b - 1, + * so that if a and b are both close to 1 so is their sum. In general, when we add a list x of exponents, + * we have to add 1 - x.length to the actual sum, so that if all the exponents are close to 1 the result + * is also close to 1 rather than close to x.length. + * @param {number[]} x + * @returns {number} + */ + addExponents: x => x.reduce(Number.sumReducer, 1 - x.length), + /** + * @param {Decimal[]} x + * @returns {Decimal} + */ + multiplyDecimal: x => x.reduce(Decimal.prodReducer, DC.D1) +}); + + +GameDatabase.reality.glyphEffects = { + timepow: { + id: "timepow", + bitmaskIndex: 0, + isGenerated: true, + glyphTypes: ["time"], + singleDesc: "Time Dimension power +{value}", + totalDesc: "Time Dimension multipliers ^{value}", + shortDesc: "TD power +{value}", + effect: (level, strength) => 1.01 + Math.pow(level, 0.32) * Math.pow(strength, 0.45) / 75, + formatEffect: x => format(x, 3, 3), + formatSingleEffect: x => format(x - 1, 3, 3), + combine: GlyphCombiner.addExponents, + enabledInDoomed: true, + }, + timespeed: { + id: "timespeed", + bitmaskIndex: 1, + isGenerated: true, + glyphTypes: ["time"], + singleDesc: "Multiply game speed by {value}", + totalDesc: "Game runs ×{value} faster", + genericDesc: "Game speed multiplier", + shortDesc: "Game speed ×{value}", + effect: (level, strength) => (GlyphAlteration.isEmpowered("time") + ? 1 + Math.pow(level, 0.35) + : 1 + Math.pow(level, 0.3) * Math.pow(strength, 0.65) / 20), + formatEffect: x => format(x, 3, 3), + combine: GlyphCombiner.multiply, + alteredColor: () => GlyphAlteration.getEmpowermentColor("time"), + alterationType: ALTERATION_TYPE.EMPOWER, + enabledInDoomed: true, + }, + timeetermult: { + id: "timeetermult", + bitmaskIndex: 2, + isGenerated: true, + glyphTypes: ["time"], + singleDesc: "Multiply Eternity gain by {value}", + totalDesc: "Eternity gain ×{value}", + genericDesc: "Eternity gain multiplier", + shortDesc: "Eternities ×{value}", + effect: (level, strength) => Math.pow((strength + 3) * level, 0.9) * + Math.pow(3, GlyphAlteration.sacrificeBoost("time")), + formatEffect: x => format(x, 2, 2), + combine: GlyphCombiner.multiply, + alteredColor: () => GlyphAlteration.getBoostColor("time"), + alterationType: ALTERATION_TYPE.BOOST + }, + timeEP: { + id: "timeEP", + bitmaskIndex: 3, + isGenerated: true, + glyphTypes: ["time"], + singleDesc: () => (GlyphAlteration.isAdded("time") + ? "Eternity Point gain \n×{value} [and ^]{value2}" + : "Multiply Eternity Point gain by {value}"), + totalDesc: () => (GlyphAlteration.isAdded("time") + ? "Eternity Point gain ×{value} and ^{value2}" + : "Eternity Point gain ×{value}"), + genericDesc: () => (GlyphAlteration.isAdded("time") + ? "Eternity Point gain multiplier and power" + : "Eternity Point gain multiplier"), + shortDesc: () => (GlyphAlteration.isAdded("time") + ? "EP ×{value} and ^{value2}" + : "EP ×{value}"), + effect: (level, strength) => Math.pow(level * strength, 3) * 100, + formatEffect: x => format(x, 2, 3), + combine: GlyphCombiner.multiply, + conversion: x => 1 + Math.log10(x) / 1000, + formatSecondaryEffect: x => format(x, 4, 4), + alteredColor: () => GlyphAlteration.getAdditionColor("time"), + alterationType: ALTERATION_TYPE.ADDITION + }, + dilationDT: { + id: "dilationDT", + bitmaskIndex: 4, + isGenerated: true, + glyphTypes: ["dilation"], + singleDesc: "Multiply Dilated Time gain by {value}", + totalDesc: "Dilated Time gain ×{value}", + shortDesc: "DT ×{value}", + effect: (level, strength) => (GlyphAlteration.isEmpowered("dilation") + ? DC.D1_005.pow(level).times(15) + : Decimal.pow(level * strength, 1.5).times(2)), + formatEffect: x => format(x, 2, 1), + combine: GlyphCombiner.multiplyDecimal, + alteredColor: () => GlyphAlteration.getEmpowermentColor("dilation"), + alterationType: ALTERATION_TYPE.EMPOWER + }, + dilationgalaxyThreshold: { + id: "dilationgalaxyThreshold", + bitmaskIndex: 5, + isGenerated: true, + glyphTypes: ["dilation"], + singleDesc: "Tachyon Galaxy threshold multiplier ×{value}", + genericDesc: "Tachyon Galaxy cost multiplier", + shortDesc: "TG threshold ×{value}", + effect: (level, strength) => 1 - Math.pow(level, 0.17) * Math.pow(strength, 0.35) / 100 - + GlyphAlteration.sacrificeBoost("dilation") / 50, + formatEffect: x => format(x, 3, 3), + alteredColor: () => GlyphAlteration.getBoostColor("dilation"), + alterationType: ALTERATION_TYPE.BOOST, + combine: effects => { + const prod = effects.reduce(Number.prodReducer, 1); + return prod < 0.4 + ? { value: 0.4 - Math.pow(0.4 - prod, 1.7), capped: true } + : { value: prod, capped: false }; + }, + enabledInDoomed: true, + }, + dilationTTgen: { + // TTgen slowly generates TT, value amount is per second, displayed per hour + id: "dilationTTgen", + bitmaskIndex: 6, + isGenerated: true, + glyphTypes: ["dilation"], + singleDesc: () => (GlyphAlteration.isAdded("dilation") + ? "Generates {value} Time Theorems/hour \n[and multiplies Time Theorem \ngeneration by] {value2}" + : "Generates {value} Time Theorems per hour"), + totalDesc: () => (GlyphAlteration.isAdded("dilation") + ? "Generating {value} Time Theorems/hour and Time Theorem generation ×{value2}" + : "Generating {value} Time Theorems per hour"), + genericDesc: () => (GlyphAlteration.isAdded("dilation") + ? "Time Theorem generation and multiplier" + : "Time Theorem generation"), + shortDesc: () => (GlyphAlteration.isAdded("dilation") + ? "{value} TT/hr and TTgen ×{value2}" + : "{value} TT/hr"), + effect: (level, strength) => Math.pow(level * strength, 0.5) / 10000, + /** @type {function(number): string} */ + formatEffect: x => format(3600 * x, 2, 2), + combine: GlyphCombiner.add, + conversion: x => Math.clampMin(Math.pow(10000 * x, 1.6), 1), + formatSecondaryEffect: x => format(x, 2, 2), + alteredColor: () => GlyphAlteration.getAdditionColor("dilation"), + alterationType: ALTERATION_TYPE.ADDITION + }, + dilationpow: { + id: "dilationpow", + bitmaskIndex: 7, + isGenerated: true, + glyphTypes: ["dilation"], + singleDesc: "Antimatter Dimension power +{value} while Dilated", + totalDesc: "Antimatter Dimension multipliers ^{value} while Dilated", + genericDesc: "Antimatter Dimensions ^x while Dilated", + shortDesc: "Dilated AD power +{value}", + effect: (level, strength) => 1.1 + Math.pow(level, 0.7) * Math.pow(strength, 0.7) / 25, + formatEffect: x => format(x, 2, 2), + formatSingleEffect: x => format(x - 1, 2, 2), + combine: GlyphCombiner.addExponents, + enabledInDoomed: true, + }, + replicationspeed: { + id: "replicationspeed", + bitmaskIndex: 8, + isGenerated: true, + glyphTypes: ["replication"], + singleDesc: "Multiply Replication speed by {value}", + totalDesc: "Replication speed ×{value}", + genericDesc: "Replication speed multiplier", + shortDesc: "Replication speed ×{value}", + effect: (level, strength) => (GlyphAlteration.isEmpowered("replication") + ? DC.D1_007.pow(level).times(10) + : Decimal.times(level, strength).times(3)), + formatEffect: x => format(x, 2, 1), + combine: GlyphCombiner.multiplyDecimal, + alteredColor: () => GlyphAlteration.getEmpowermentColor("replication"), + alterationType: ALTERATION_TYPE.EMPOWER + }, + replicationpow: { + id: "replicationpow", + bitmaskIndex: 9, + isGenerated: true, + glyphTypes: ["replication"], + singleDesc: "Replicanti multiplier power +{value}", + totalDesc: "Replicanti multiplier ^{value}", + shortDesc: "Replicanti mult. power +{value}", + effect: (level, strength) => 1.1 + Math.pow(level, 0.5) * strength / 25 + + GlyphAlteration.sacrificeBoost("replication") * 3, + formatEffect: x => format(x, 2, 2), + formatSingleEffect: x => format(x - 1, 2, 2), + combine: GlyphCombiner.addExponents, + alteredColor: () => GlyphAlteration.getBoostColor("replication"), + alterationType: ALTERATION_TYPE.BOOST, + enabledInDoomed: true, + }, + replicationdtgain: { + id: "replicationdtgain", + bitmaskIndex: 10, + isGenerated: true, + glyphTypes: ["replication"], + singleDesc: () => (GlyphAlteration.isAdded("replication") + ? "Multiply Dilated Time \n[and Replicanti speed] by \nlog₁₀(replicanti)×{value}" + : "Multiply Dilated Time gain by \nlog₁₀(replicanti)×{value}"), + totalDesc: () => (GlyphAlteration.isAdded("replication") + ? "Dilated Time gain and Replication speed ×(log₁₀(replicanti)×{value})" + : "Dilated Time gain ×(log₁₀(replicanti)×{value})"), + genericDesc: () => (GlyphAlteration.isAdded("replication") + ? "Dilated Time+Replicanti mult (log₁₀(replicanti))" + : "Dilated Time gain multiplier (log₁₀(replicanti))"), + shortDesc: () => (GlyphAlteration.isAdded("replication") + ? "DT and repl. ×log₁₀(repl.)×{value}" + : "DT ×log₁₀(repl.)×{value}"), + effect: (level, strength) => 0.0003 * Math.pow(level, 0.3) * Math.pow(strength, 0.65), + formatEffect: x => format(x, 5, 5), + formatSingleEffect: x => format(x, 5, 5), + // It's bad to stack this one additively (N glyphs acts as a DT mult of N) or multiplicatively (the raw number is + // less than 1), so instead we do a multiplicative stacking relative to the "base" effect of a level 1, 0% glyph. + // We also introduce a 3x mult per glyph after the first, so that stacking level 1, 0% glyphs still has an effect. + // This is still just a flat DT mult when stacking multiple glyphs, but at least it's bigger than 2 or 3. + combine: effects => ({ + value: effects.length === 0 ? 0 : effects.reduce(Number.prodReducer, Math.pow(0.0001, 1 - effects.length)), + capped: false + }), + conversion: x => x, + formatSecondaryEffect: x => format(x, 2, 3), + formatSingleSecondaryEffect: x => format(x, 5, 5), + alteredColor: () => GlyphAlteration.getAdditionColor("replication"), + alterationType: ALTERATION_TYPE.ADDITION + }, + replicationglyphlevel: { + id: "replicationglyphlevel", + bitmaskIndex: 11, + isGenerated: true, + glyphTypes: ["replication"], + singleDesc: () => `Replicanti factor for Glyph level:\n ^${format(0.4, 1, 1)} + ➜ ^(${format(0.4, 1, 1)} + {value})`, + totalDesc: () => `Replicanti factor for Glyph level: ^${format(0.4, 1, 1)} + ➜ ^(${format(0.4, 1, 1)} + {value})`, + genericDesc: "Replicanti factor for Glyph level", + shortDesc: "Replicanti pow. for level +{value}", + effect: (level, strength) => Math.pow(Math.pow(level, 0.25) * Math.pow(strength, 0.4), 0.5) / 50, + formatEffect: x => format(x, 3, 3), + combine: effects => { + let sum = effects.reduce(Number.sumReducer, 0); + if (effects.length > 2) sum *= 6 / (effects.length + 4); + return sum > 0.1 + ? { value: 0.1 + 0.2 * (sum - 0.1), capped: true } + : { value: sum, capped: effects.length > 2 }; + } + }, + infinitypow: { + id: "infinitypow", + bitmaskIndex: 12, + isGenerated: true, + glyphTypes: ["infinity"], + singleDesc: "Infinity Dimension power +{value}", + totalDesc: "Infinity Dimension multipliers ^{value}", + shortDesc: "ID power +{value}", + effect: (level, strength) => 1.007 + Math.pow(level, 0.21) * Math.pow(strength, 0.4) / 75 + + GlyphAlteration.sacrificeBoost("infinity") / 50, + formatEffect: x => format(x, 3, 3), + formatSingleEffect: x => format(x - 1, 3, 3), + combine: GlyphCombiner.addExponents, + alteredColor: () => GlyphAlteration.getBoostColor("infinity"), + alterationType: ALTERATION_TYPE.BOOST, + enabledInDoomed: true, + }, + infinityrate: { + id: "infinityrate", + bitmaskIndex: 13, + isGenerated: true, + glyphTypes: ["infinity"], + singleDesc: () => `Infinity Power conversion rate: \n^${formatInt(7)} + ➜ ^(${formatInt(7)} + {value})`, + totalDesc: () => `Infinity Power conversion rate: ^${formatInt(7)} + ➜ ^(${formatInt(7)} + {value})`, + genericDesc: "Infinity Power conversion rate", + shortDesc: "Infinity Power conversion +{value}", + effect: (level, strength) => Math.pow(level, 0.2) * Math.pow(strength, 0.4) * 0.04, + formatEffect: x => format(x, 2, 2), + combine: GlyphCombiner.add, + enabledInDoomed: true, + }, + infinityIP: { + id: "infinityIP", + bitmaskIndex: 14, + isGenerated: true, + glyphTypes: ["infinity"], + singleDesc: () => (GlyphAlteration.isAdded("infinity") + ? "Infinity Point gain \n×{value} [and ^]{value2}" + : "Multiply Infinity Point gain by {value}"), + totalDesc: () => (GlyphAlteration.isAdded("infinity") + ? "Infinity Point gain ×{value} and ^{value2}" + : "Infinity Point gain ×{value}"), + genericDesc: () => (GlyphAlteration.isAdded("infinity") + ? "Infinity Point gain multiplier and power" + : "Infinity Point gain multiplier"), + shortDesc: () => (GlyphAlteration.isAdded("infinity") + ? "IP ×{value} and ^{value2}" + : "IP ×{value}"), + effect: (level, strength) => Math.pow(level * (strength + 1), 6) * 10000, + formatEffect: x => format(x, 2, 3), + combine: GlyphCombiner.multiply, + // eslint-disable-next-line no-negated-condition + softcap: value => ((Effarig.eternityCap !== undefined) ? Math.min(value, Effarig.eternityCap.toNumber()) : value), + conversion: x => 1 + Math.log10(x) / 1800, + formatSecondaryEffect: x => format(x, 4, 4), + alteredColor: () => GlyphAlteration.getAdditionColor("infinity"), + alterationType: ALTERATION_TYPE.ADDITION + }, + infinityinfmult: { + id: "infinityinfmult", + bitmaskIndex: 15, + isGenerated: true, + glyphTypes: ["infinity"], + singleDesc: "Multiply Infinity gain by {value}", + totalDesc: "Infinity gain ×{value}", + genericDesc: "Infinity gain multiplier", + shortDesc: "Infinities ×{value}", + effect: (level, strength) => (GlyphAlteration.isEmpowered("infinity") + ? DC.D1_02.pow(level) + : Decimal.pow(level * strength, 1.5).times(2)), + formatEffect: x => format(x, 2, 1), + combine: GlyphCombiner.multiplyDecimal, + alteredColor: () => GlyphAlteration.getEmpowermentColor("infinity"), + alterationType: ALTERATION_TYPE.EMPOWER + }, + powerpow: { + id: "powerpow", + bitmaskIndex: 16, + isGenerated: true, + glyphTypes: ["power"], + singleDesc: () => (GlyphAlteration.isAdded("power") + ? "Antimatter Dimension power +{value}\n[and Antimatter Galaxy cost ×]{value2}" + : "Antimatter Dimension power +{value}"), + totalDesc: () => (GlyphAlteration.isAdded("power") + ? "Antimatter Dimension multipliers ^{value} and Antimatter Galaxy cost ×{value2}" + : "Antimatter Dimension multipliers ^{value}"), + genericDesc: () => (GlyphAlteration.isAdded("power") + ? "Antimatter Dimensions multipliers ^x and Antimatter Galaxy cost multiplier" + : "Antimatter Dimension multipliers ^x"), + shortDesc: () => (GlyphAlteration.isAdded("power") + ? "AD power +{value} and AG cost ×{value2}" + : "AD power +{value}"), + effect: (level, strength) => 1.015 + Math.pow(level, 0.2) * Math.pow(strength, 0.4) / 75, + formatEffect: x => format(x, 3, 3), + formatSingleEffect: x => format(x - 1, 3, 3), + combine: GlyphCombiner.addExponents, + conversion: x => 2 / (x + 1), + formatSecondaryEffect: x => format(x, 3, 3), + alteredColor: () => GlyphAlteration.getAdditionColor("power"), + alterationType: ALTERATION_TYPE.ADDITION, + enabledInDoomed: true, + }, + powermult: { + id: "powermult", + bitmaskIndex: 17, + isGenerated: true, + glyphTypes: ["power"], + singleDesc: "Antimatter Dimension multipliers ×{value}", + shortDesc: "AD ×{value}", + effect: (level, strength) => (GlyphAlteration.isEmpowered("power") + ? DC.D11111.pow(level * 220) + : Decimal.pow(level * strength * 10, level * strength * 10)), + formatEffect: x => formatPostBreak(x, 2, 0), + combine: GlyphCombiner.multiplyDecimal, + alteredColor: () => GlyphAlteration.getEmpowermentColor("power"), + alterationType: ALTERATION_TYPE.EMPOWER, + enabledInDoomed: true, + }, + powerdimboost: { + id: "powerdimboost", + bitmaskIndex: 18, + isGenerated: true, + glyphTypes: ["power"], + singleDesc: "Dimension Boost multiplier ×{value}", + genericDesc: "Dimension Boost multiplier", + shortDesc: "Dimboost mult. ×{value}", + effect: (level, strength) => Math.pow(level * strength, 0.5) * + Math.pow(1 + GlyphAlteration.sacrificeBoost("power"), 3), + formatEffect: x => format(x, 2, 2), + combine: GlyphCombiner.multiply, + alteredColor: () => GlyphAlteration.getBoostColor("power"), + alterationType: ALTERATION_TYPE.BOOST, + enabledInDoomed: true, + }, + powerbuy10: { + id: "powerbuy10", + bitmaskIndex: 19, + isGenerated: true, + glyphTypes: ["power"], + singleDesc: () => `Increase the bonus from buying ${formatInt(10)} Antimatter Dimensions by {value}`, + totalDesc: () => `Multiplier from "Buy ${formatInt(10)}" ×{value}`, + genericDesc: () => `"Buy ${formatInt(10)}" bonus increase`, + shortDesc: () => `AD "Buy ${formatInt(10)}" mult. ×{value}`, + effect: (level, strength) => 1 + level * strength / 12, + formatEffect: x => format(x, 2, 2), + combine: GlyphCombiner.addExponents, + enabledInDoomed: true, + }, + effarigblackhole: { + id: "effarigblackhole", + bitmaskIndex: 20, + isGenerated: true, + glyphTypes: ["effarig"], + singleDesc: "Game speed power +{value}", + totalDesc: "Game speed ^{value}", + genericDesc: "Game speed ^x", + shortDesc: "Game speed power +{value}", + effect: (level, strength) => 1 + Math.pow(level, 0.25) * Math.pow(strength, 0.4) / 75, + formatEffect: x => format(x, 3, 3), + formatSingleEffect: x => format(x - 1, 3, 3), + combine: GlyphCombiner.addExponents, + }, + effarigrm: { + id: "effarigrm", + bitmaskIndex: 21, + isGenerated: true, + glyphTypes: ["effarig"], + singleDesc: "Reality Machine multiplier ×{value}", + genericDesc: "Reality Machine multiplier", + shortDesc: "RM ×{value}", + effect: (level, strength) => (GlyphAlteration.isEmpowered("effarig") + ? Math.pow(level, 1.5) + : Math.pow(level, 0.6) * strength), + formatEffect: x => format(x, 2, 2), + combine: GlyphCombiner.multiply, + alteredColor: () => GlyphAlteration.getEmpowermentColor("effarig"), + alterationType: ALTERATION_TYPE.EMPOWER + }, + effarigglyph: { + id: "effarigglyph", + bitmaskIndex: 22, + isGenerated: true, + glyphTypes: ["effarig"], + singleDesc: "Glyph Instability starting level +{value}", + genericDesc: "Glyph Instability delay", + shortDesc: "Instability delay +{value}", + effect: (level, strength) => Math.floor(10 * Math.pow(level * strength, 0.5)), + formatEffect: x => formatInt(x), + combine: GlyphCombiner.add, + }, + effarigachievement: { + id: "effarigachievement", + bitmaskIndex: 23, + isGenerated: true, + glyphTypes: ["effarig"], + singleDesc: "Achievement multiplier power +{value}", + totalDesc: "Achievement multiplier ^{value}", + genericDesc: "Achievement multiplier ^x", + shortDesc: "Achievement mult. power +{value}", + effect: (level, strength) => 1 + Math.pow(level, 0.4) * Math.pow(strength, 0.6) / 60 + + GlyphAlteration.sacrificeBoost("effarig") / 10, + formatEffect: x => format(x, 3, 3), + formatSingleEffect: x => format(x - 1, 3, 3), + combine: GlyphCombiner.addExponents, + alteredColor: () => GlyphAlteration.getBoostColor("effarig"), + alterationType: ALTERATION_TYPE.BOOST + }, + effarigforgotten: { + id: "effarigforgotten", + bitmaskIndex: 24, + isGenerated: true, + glyphTypes: ["effarig"], + singleDesc: () => (GlyphAlteration.isAdded("effarig") + ? `"Buy ${formatInt(10)}" multiplier ^{value} [and\nDimension Boost multiplier ^]{value2}` + : `Bonus from buying ${formatInt(10)} Dimensions ^{value}`), + totalDesc: () => (GlyphAlteration.isAdded("effarig") + ? `Multiplier from "Buy ${formatInt(10)}" ^{value} and Dimension Boost multiplier ^{value2}` + : `Multiplier from "Buy ${formatInt(10)}" ^{value}`), + genericDesc: () => (GlyphAlteration.isAdded("effarig") + ? `"Buy ${formatInt(10)}" and Dimension Boost multipliers ^x` + : `"Buy ${formatInt(10)}" multiplier ^x`), + shortDesc: () => (GlyphAlteration.isAdded("effarig") + ? `Buy ${formatInt(10)} mult. ^{value}, Dimboost mult. ^{value2}` + : `Buy ${formatInt(10)} mult. ^{value}`), + effect: (level, strength) => 1 + 2 * Math.pow(level, 0.25) * Math.pow(strength, 0.4), + formatEffect: x => format(x, 2, 2), + combine: GlyphCombiner.multiply, + conversion: x => Math.pow(x, 0.4), + formatSecondaryEffect: x => format(x, 2, 2), + alteredColor: () => GlyphAlteration.getAdditionColor("effarig"), + alterationType: ALTERATION_TYPE.ADDITION + }, + effarigdimensions: { + id: "effarigdimensions", + bitmaskIndex: 25, + isGenerated: true, + glyphTypes: ["effarig"], + singleDesc: "All Dimension power +{value}", + totalDesc: "All Dimension multipliers ^{value}", + genericDesc: "All Dimension multipliers ^x", + shortDesc: "All Dimension power +{value}", + effect: (level, strength) => 1 + Math.pow(level, 0.25) * Math.pow(strength, 0.4) / 500, + formatEffect: x => format(x, 3, 3), + formatSingleEffect: x => format(x - 1, 3, 3), + combine: GlyphCombiner.addExponents, + }, + effarigantimatter: { + id: "effarigantimatter", + bitmaskIndex: 26, + isGenerated: true, + glyphTypes: ["effarig"], + singleDesc: () => `Antimatter production:\n${formatInt(10)}^x ➜ ${formatInt(10)}^(x^{value})`, + genericDesc: "Antimatter production exponent power", + shortDesc: "AM production exponent ^{value}", + effect: (level, strength) => 1 + Math.pow(level, 0.25) * Math.pow(strength, 0.4) / 5000, + formatEffect: x => format(x, 4, 4), + combine: GlyphCombiner.multiply, + }, + timeshardpow: { + id: "timeshardpow", + bitmaskIndex: 27, + isGenerated: true, + // This gets explicitly added to time glyphs elsewhere (once unlocked) + glyphTypes: [], + singleDesc: "Time Shard power +{value}", + totalDesc: "Time Shard gain ^{value}", + genericDesc: "Time Shards ^x", + shortDesc: "Time Shard power +{value}", + effect: (level, strength) => 1 + (strength / 3.5) * Math.pow(level, 0.35) / 400, + formatEffect: x => format(x, 3, 3), + formatSingleEffect: x => format(x - 1, 3, 3), + combine: GlyphCombiner.addExponents, + enabledInDoomed: true, + }, + cursedgalaxies: { + id: "cursedgalaxies", + bitmaskIndex: 0, + isGenerated: false, + glyphTypes: ["cursed"], + singleDesc: `All Galaxies are {value} weaker`, + totalDesc: "All Galaxy strength -{value}", + shortDesc: "Galaxy Strength -{value}", + // Multiplies by 0.768 per glyph + effect: level => Math.pow(level, -0.03), + formatEffect: x => formatPercents(1 - x, 2), + combine: GlyphCombiner.multiply, + }, + curseddimensions: { + id: "curseddimensions", + bitmaskIndex: 1, + isGenerated: false, + glyphTypes: ["cursed"], + singleDesc: "All Dimension multipliers ^{value}", + shortDesc: "All Dimensions ^{value}", + // Multiplies by 0.734 per glyph + effect: level => Math.pow(level, -0.035), + formatEffect: x => format(x, 3, 3), + combine: GlyphCombiner.multiply, + }, + cursedtickspeed: { + id: "cursedtickspeed", + bitmaskIndex: 2, + isGenerated: false, + glyphTypes: ["cursed"], + singleDesc: "The threshold for Tickspeed Upgrades from Time Dimensions is multiplied by ×{value}", + totalDesc: "The threshold for Tickspeed Upgrades from Time Dimensions is increased by ×{value}", + shortDesc: "TD Tickspeed threshold ×{value}", + // Additive 3.82 per glyph + effect: level => Math.clampMin(Math.log10(level), 1), + formatEffect: x => format(x, 3, 3), + combine: GlyphCombiner.add, + }, + cursedEP: { + id: "cursedEP", + bitmaskIndex: 3, + isGenerated: false, + glyphTypes: ["cursed"], + singleDesc: "Divide Eternity Point gain by {value}", + totalDesc: "Eternity Point gain / {value}", + shortDesc: "EP / {value}", + // Divides e666.6 per glyph + effect: level => Decimal.pow10(-level / 10), + formatEffect: x => format(x.reciprocal()), + combine: GlyphCombiner.multiplyDecimal, + }, + realityglyphlevel: { + id: "realityglyphlevel", + bitmaskIndex: 4, + isGenerated: false, + glyphTypes: ["reality"], + singleDesc: "Increase the effective level of equipped basic Glyphs by {value}", + totalDesc: "Equipped basic Glyph level +{value}", + shortDesc: "Basic Glyph Level +{value}", + effect: level => Math.floor(Math.sqrt(level * 90)), + formatEffect: x => formatInt(x), + combine: GlyphCombiner.add, + }, + realitygalaxies: { + id: "realitygalaxies", + bitmaskIndex: 5, + isGenerated: false, + glyphTypes: ["reality"], + singleDesc: "All Galaxies are {value} stronger", + totalDesc: "All Galaxy strength +{value}", + shortDesc: "Galaxy Strength +{value}", + effect: level => 1 + Math.pow(level / 100000, 0.5), + formatEffect: x => formatPercents(x - 1, 2), + combine: GlyphCombiner.multiply, + }, + realityrow1pow: { + id: "realityrow1pow", + bitmaskIndex: 6, + isGenerated: false, + glyphTypes: ["reality"], + singleDesc: "Multiplier from Reality Upgrade Amplifiers ^{value}", + totalDesc: "Reality Upgrade Amplifier multiplier ^{value}", + shortDesc: "Amplifier Multiplier ^{value}", + effect: level => 1 + level / 125000, + formatEffect: x => format(x, 3, 3), + combine: GlyphCombiner.addExponents, + }, + realityDTglyph: { + id: "realityDTglyph", + bitmaskIndex: 7, + isGenerated: false, + glyphTypes: ["reality"], + singleDesc: () => `Dilated Time factor for Glyph level: \n^${format(1.3, 1, 1)} + ➜ ^(${format(1.3, 1, 1)} + {value})`, + totalDesc: () => `Dilated Time factor for Glyph level: ^${format(1.3, 1, 1)} + ➜ ^(${format(1.3, 1, 1)} + {value})`, + genericDesc: "Dilated Time factor for Glyph level", + shortDesc: "DT pow. for level +{value}", + // You can only get this effect on level 25000 reality glyphs anyway, might as well make it look nice + effect: () => 0.1, + formatEffect: x => format(x, 2, 2), + combine: GlyphCombiner.add, + }, + companiondescription: { + id: "companiondescription", + bitmaskIndex: 8, + isGenerated: false, + glyphTypes: ["companion"], + singleDesc: "It does nothing but sit there and cutely smile at you, whisper into your dreams politely, " + + "and plot the demise of all who stand against you. This one-of-a-kind Glyph will never leave you.", + totalDesc: "+{value} happiness", + shortDesc: "Doesn't want to hurt you", + effect: () => { + if (Enslaved.isRunning) return 0; + const cursedCount = Glyphs.active.countWhere(g => g?.type === "cursed"); + if (cursedCount > 0) return Math.pow(0.2 + 0.2 * Math.random(), cursedCount); + return 0.4 + 0.6 * Math.random(); + }, + formatEffect: x => formatPercents(x, 2, 2), + combine: GlyphCombiner.add, + enabledInDoomed: true, + }, + companionEP: { + id: "companionEP", + bitmaskIndex: 9, + isGenerated: false, + glyphTypes: ["companion"], + singleDesc: "Thanks for your dedication for the game! You reached {value} Eternity Points on your first Reality.", + shortDesc: "It loves you very, very much", + totalDesc: () => ((Enslaved.isRunning || Glyphs.active.countWhere(g => g?.type === "cursed")) ? "Help me" : "Yay!"), + // The EP value for this is entirely encoded in rarity, but level needs to be present to + // make sure the proper parameter is being used. The actual glyph level shouldn't do anything. + // eslint-disable-next-line no-unused-vars + effect: (level, strength) => Decimal.pow10(1e6 * strengthToRarity(strength)), + formatEffect: x => formatPostBreak(x, 2), + combine: GlyphCombiner.multiplyDecimal, + enabledInDoomed: true, + } +}; diff --git a/javascripts/core/secret-formula/reality/glyph-sacrifices.js b/javascripts/core/secret-formula/reality/glyph-sacrifices.js index edb2aaad9..4df2bf7bc 100644 --- a/javascripts/core/secret-formula/reality/glyph-sacrifices.js +++ b/javascripts/core/secret-formula/reality/glyph-sacrifices.js @@ -1,7 +1,7 @@ -import { GameDatabase } from "../game-database.js"; +import { GameDatabase } from "../game-database"; -GameDatabase.reality.glyphSacrifice = [ - { +GameDatabase.reality.glyphSacrifice = { + "power": { id: "power", effect: added => { if (Pelle.isDisabled("glyphsac")) return 0; @@ -11,15 +11,16 @@ GameDatabase.reality.glyphSacrifice = [ return Math.floor(750 * Math.pow(base, 1.2)); }, description: amount => { - if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`; const sacCap = GlyphSacrificeHandler.maxSacrificeForEffects; const nextDistantGalaxy = Math.pow(10, Math.pow((amount + 1) / 750, 1 / 1.2) * Math.log10(sacCap)) - 1; const nextGalaxyText = amount < 750 ? ` (next at ${format(nextDistantGalaxy, 2, 2)})` : ""; return `Distant Galaxy scaling starts ${formatInt(amount)} later${nextGalaxyText}`; - } - }, { + }, + cap: () => GlyphSacrificeHandler.maxSacrificeForEffects + }, + "infinity": { id: "infinity", effect: added => { if (Pelle.isDisabled("glyphsac")) return 1; @@ -27,11 +28,10 @@ GameDatabase.reality.glyphSacrifice = [ const capped = Math.clampMax(sac, GlyphSacrificeHandler.maxSacrificeForEffects); return 1 + Math.log10(1 + Math.pow(capped, 0.2) / 100); }, - description: amount => { - if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`; - return `${formatX(amount, 2, 2)} bigger multiplier when buying 8th Infinity Dimension.`; - } - }, { + description: amount => `${formatX(amount, 2, 2)} bigger multiplier when buying 8th Infinity Dimension`, + cap: () => GlyphSacrificeHandler.maxSacrificeForEffects + }, + "time": { id: "time", effect: added => { if (Pelle.isDisabled("glyphsac")) return 1; @@ -39,11 +39,10 @@ GameDatabase.reality.glyphSacrifice = [ const capped = Math.clampMax(sac, GlyphSacrificeHandler.maxSacrificeForEffects); return Math.pow(1 + Math.pow(capped, 0.2) / 100, 2); }, - description: amount => { - if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`; - return `${formatX(amount, 2, 2)} bigger multiplier when buying 8th Time Dimension.`; - } - }, { + description: amount => `${formatX(amount, 2, 2)} bigger multiplier when buying 8th Time Dimension`, + cap: () => GlyphSacrificeHandler.maxSacrificeForEffects + }, + "replication": { id: "replication", effect: added => { if (Pelle.isDisabled("glyphsac")) return 0; @@ -53,15 +52,16 @@ GameDatabase.reality.glyphSacrifice = [ return Math.floor(1500 * Math.pow(base, 1.2)); }, description: amount => { - if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`; const sacCap = GlyphSacrificeHandler.maxSacrificeForEffects; const nextDistantGalaxy = Math.pow(10, Math.pow((amount + 1) / 1500, 1 / 1.2) * Math.log10(sacCap)) - 1; const nextGalaxyText = amount < 1500 ? ` (next at ${format(nextDistantGalaxy, 2, 2)})` : ""; return `Replicanti Galaxy scaling starts ${formatInt(amount)} later${nextGalaxyText}`; - } - }, { + }, + cap: () => GlyphSacrificeHandler.maxSacrificeForEffects + }, + "dilation": { id: "dilation", effect: added => { if (Pelle.isDisabled("glyphsac")) return 1; @@ -71,32 +71,29 @@ GameDatabase.reality.glyphSacrifice = [ Math.log10(GlyphSacrificeHandler.maxSacrificeForEffects), 0.1); return Math.pow(Math.clampMin(capped, 1), exponent); }, - description: amount => { - if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`; - return `Multiply Tachyon Particle gain by ${formatX(amount, 2, 2)}`; - } - }, { + description: amount => `Multiply Tachyon Particle gain by ${formatX(amount, 2, 2)}`, + cap: () => GlyphSacrificeHandler.maxSacrificeForEffects + }, + "effarig": { id: "effarig", effect: added => { if (Pelle.isDisabled("glyphsac")) return 0; const sac = player.reality.glyphs.sac.effarig + (added ?? 0); - const capped = Math.clampMax(sac, GlyphSacrificeHandler.maxSacrificeForEffects); + // This doesn't use the GlyphSacrificeHandler cap because it hits its cap (+100%) earlier + const capped = Math.clampMax(sac, 1e70); return 2 * Math.log10(capped / 1e20 + 1); }, - description: amount => { - if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`; - return `+${formatPercents(amount / 100, 2)} additional Glyph rarity`; - } - }, { + description: amount => `+${formatPercents(amount / 100, 2)} additional Glyph rarity`, + cap: () => 1e70 + }, + "reality": { id: "reality", effect: added => { if (Pelle.isDisabled("glyphsac")) return 0; const sac = player.reality.glyphs.sac.reality + (added ?? 0); - return 1 + Math.sqrt(sac) / 25; + return 1 + Math.sqrt(sac) / 15; }, - description: amount => { - if (Pelle.isDisabled("glyphsac")) return `Glyph Sacrifice is disabled in Pelle`; - return `${formatPercents(amount - 1, 2)} increased Alchemy yield`; - } + description: amount => `Multiply Memory Chunk gain by ${formatX(amount, 2, 3)}`, + cap: () => GlyphSacrificeHandler.maxSacrificeForEffects } -].mapToObject(g => g.id, g => g); +}; diff --git a/javascripts/core/secret-formula/reality/glyph-types.js b/javascripts/core/secret-formula/reality/glyph-types.js new file mode 100644 index 000000000..4e6db5189 --- /dev/null +++ b/javascripts/core/secret-formula/reality/glyph-types.js @@ -0,0 +1,71 @@ +import { GameDatabase } from "../game-database"; + +GameDatabase.reality.glyphTypes = { + time: { + id: "time", + symbol: GLYPH_SYMBOLS.time, + color: "#b241e3", + primaryEffect: "timepow", + alchemyResource: ALCHEMY_RESOURCE.TIME, + hasRarity: true + }, + dilation: { + id: "dilation", + symbol: GLYPH_SYMBOLS.dilation, + color: "#64dd17", + alchemyResource: ALCHEMY_RESOURCE.DILATION, + hasRarity: true + }, + replication: { + id: "replication", + symbol: GLYPH_SYMBOLS.replication, + color: "#03a9f4", + alchemyResource: ALCHEMY_RESOURCE.REPLICATION, + hasRarity: true + }, + infinity: { + id: "infinity", + symbol: GLYPH_SYMBOLS.infinity, + color: "#b67f33", + primaryEffect: "infinitypow", + alchemyResource: ALCHEMY_RESOURCE.INFINITY, + hasRarity: true + }, + power: { + id: "power", + symbol: GLYPH_SYMBOLS.power, + color: "#22aa48", + primaryEffect: "powerpow", + alchemyResource: ALCHEMY_RESOURCE.POWER, + hasRarity: true + }, + effarig: { + id: "effarig", + symbol: GLYPH_SYMBOLS.effarig, + color: "#e21717", + isUnlocked: () => EffarigUnlock.reality.isUnlocked, + alchemyResource: ALCHEMY_RESOURCE.EFFARIG, + hasRarity: true + // Effarig glyphs have no primary effect; all are equally likely + }, + reality: { + id: "reality", + symbol: GLYPH_SYMBOLS.reality, + color: "#555555", + isUnlocked: () => false, + // Refining a reality glyph is pretty wasteful anyway, but might as well have this here + alchemyResource: ALCHEMY_RESOURCE.REALITY + }, + cursed: { + id: "cursed", + symbol: GLYPH_SYMBOLS.cursed, + color: "black", + isUnlocked: () => false, + }, + companion: { + id: "companion", + symbol: GLYPH_SYMBOLS.companion, + color: "#feaec9", + isUnlocked: () => false, + }, +}; diff --git a/javascripts/core/secret-formula/reality/imaginary-upgrades.js b/javascripts/core/secret-formula/reality/imaginary-upgrades.js index 8b33e189d..767fcf13b 100644 --- a/javascripts/core/secret-formula/reality/imaginary-upgrades.js +++ b/javascripts/core/secret-formula/reality/imaginary-upgrades.js @@ -1,293 +1,303 @@ -import { GameDatabase } from "../game-database.js"; -import { DC } from "../../constants.js"; +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)}`, + isDisabledInDoomed: true + }, + { + 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)}`, + isDisabledInDoomed: true + }, + { + name: "Transience of Information", + id: 13, + cost: 5e7, + requirement: () => `Reach ${format(Number.MAX_VALUE, 2)} projected Reality Machines within + The Nameless 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)}`, + isDisabledInDoomed: true + }, + { + 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, + isDisabledInDoomed: true + }, + { + 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: () => `${ + Pelle.isDoomed ? "Unlock" : "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.effectOrDefault(Infinity)), + 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, + isDisabledInDoomed: true + }, + { + 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)}`, + isDisabledInDoomed: true + }, + { + 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, + isDisabledInDoomed: true + }, + { + 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)}`, + isDisabledInDoomed: true + }, + { + 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)}`, + isDisabledInDoomed: true + }, + { + 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", + }, +]; diff --git a/javascripts/core/secret-formula/reality/perks.js b/javascripts/core/secret-formula/reality/perks.js index 831642e83..dc323fe6c 100644 --- a/javascripts/core/secret-formula/reality/perks.js +++ b/javascripts/core/secret-formula/reality/perks.js @@ -1,5 +1,5 @@ -import { GameDatabase } from "../game-database.js"; -import { DC } from "../../constants.js"; +import { DC } from "../../constants"; +import { GameDatabase } from "../game-database"; export const PERK_FAMILY = { ANTIMATTER: "ANTIMATTER", @@ -402,22 +402,22 @@ GameDatabase.reality.perks = { shortDescription: () => "Faster Dilation Autobuyers", defaultPosition: new Vector(490, 450) }, - ttFree: { - id: 104, - label: "TTF", - family: PERK_FAMILY.AUTOMATION, - get description() { - return `Purchasing Time Theorems no longer spends your Antimatter, Infinity Points, or Eternity Points.`; - }, - defaultPosition: new Vector(190, -410) - }, ttBuySingle: { - id: 105, + id: 104, label: "TTS", family: PERK_FAMILY.AUTOMATION, description: "Unlock a Time Theorem Autobuyer which buys single Time Theorems every tick.", automatorPoints: 5, shortDescription: () => "Single TT Autobuyer", + defaultPosition: new Vector(190, -410) + }, + ttFree: { + id: 105, + label: "TTF", + family: PERK_FAMILY.AUTOMATION, + get description() { + return `Purchasing Time Theorems no longer spends your Antimatter, Infinity Points, or Eternity Points.`; + }, defaultPosition: new Vector(255, -540) }, ttBuyMax: { @@ -515,7 +515,7 @@ GameDatabase.reality.perkConnections = (function() { [p.studyPassive, p.bypassEC1Lock], [p.autocompleteEC1, p.autocompleteEC2], [p.autocompleteEC2, p.autocompleteEC3], - [p.studyActiveEP, p.bypassEC2Lock, p.ttFree], + [p.studyActiveEP, p.bypassEC2Lock, p.ttBuySingle], [p.studyIdleEP, p.bypassEC3Lock, p.autocompleteEC1], [p.studyECRequirement, p.studyECBulk], [p.retroactiveTP1, p.bypassTGReset, p.startTP, p.retroactiveTP2], @@ -523,8 +523,8 @@ GameDatabase.reality.perkConnections = (function() { [p.retroactiveTP3, p.retroactiveTP4], [p.autobuyerDilation, p.autounlockEU2, p.autounlockDilation1, p.bypassECDilation, p.bypassTGReset], [p.autobuyerFasterID], - [p.ttFree, p.ttBuySingle], - [p.ttBuySingle, p.ttBuyMax], + [p.ttBuySingle, p.ttFree], + [p.ttFree, p.ttBuyMax], [p.achievementGroup1, p.achievementGroup2], [p.achievementGroup2, p.achievementGroup3], [p.achievementGroup3, p.achievementGroup4], diff --git a/javascripts/core/secret-formula/reality/reality-upgrades.js b/javascripts/core/secret-formula/reality/reality-upgrades.js index c6e765759..e40ee731b 100644 --- a/javascripts/core/secret-formula/reality/reality-upgrades.js +++ b/javascripts/core/secret-formula/reality/reality-upgrades.js @@ -1,345 +1,345 @@ -import { GameDatabase } from "../game-database.js"; -import { DC } from "../../constants.js"; +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.TT_BOOST.effect.eternity(), - formatEffect: value => `${format(value)} per second` - }, - { - name: "The Paradoxical Forever", - id: 15, - cost: 50, - requirement: () => `Eternity for ${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`, + }, +]; diff --git a/javascripts/core/secret-formula/script-templates.js b/javascripts/core/secret-formula/script-templates.js index 46d2e3f8b..1a1272131 100644 --- a/javascripts/core/secret-formula/script-templates.js +++ b/javascripts/core/secret-formula/script-templates.js @@ -1,5 +1,5 @@ -import { GameDatabase } from "./game-database.js"; import { AutobuyerInputFunctions } from "@/components/tabs/autobuyers/AutobuyerInput"; +import { GameDatabase } from "./game-database"; GameDatabase.reality.automator.templates = { /** @@ -18,8 +18,11 @@ GameDatabase.reality.automator.templates = { name: "tree", isValidString: str => { const validImport = TimeStudyTree.isValidImportString(str); - const presetName = str.match(/^PRESET (.{1,4})$/u); - const validPreset = presetName ? player.timestudy.presets.map(p => p.name).includes(presetName[1]) : false; + const preset = str.match(/^(NAME (.{1,4})|ID (\d))$/u); + const validPreset = preset ? ( + player.timestudy.presets.some(p => p.name === preset[2]) || + (Number(preset[3]) > 0 && Number(preset[3]) < 7) + ) : false; return validImport || validPreset; }, }, diff --git a/javascripts/core/secret-formula/shop-purchases.js b/javascripts/core/secret-formula/shop-purchases.js index fbc167e51..4f9d990cd 100644 --- a/javascripts/core/secret-formula/shop-purchases.js +++ b/javascripts/core/secret-formula/shop-purchases.js @@ -1,4 +1,4 @@ -import { GameDatabase } from "./game-database.js"; +import { GameDatabase } from "./game-database"; GameDatabase.shopPurchases = { dimPurchases: { @@ -10,19 +10,58 @@ GameDatabase.shopPurchases = { IPPurchases: { key: "IPPurchases", cost: 40, - description: "Double your Infinity Point gain from all sources. (additive) ", + description: "Double your Infinity Point gain from all sources. (additive)", multiplier: purchases => (purchases === 0 ? 1 : 2 * purchases), }, EPPurchases: { key: "EPPurchases", cost: 50, - description: "Triple your Eternity Point gain from all sources. (additive) ", + description: "Triple your Eternity Point gain from all sources. (additive)", multiplier: purchases => (purchases === 0 ? 1 : 3 * purchases), }, + RMPurchases: { + key: "RMPurchases", + cost: 60, + description: "Increase your Reality Machine gain by 100%. (additive)", + multiplier: purchases => purchases + 1, + formatEffect: x => formatX(x, 2), + }, allDimPurchases: { key: "allDimPurchases", cost: 60, - description: "Double ALL Dimension multipliers (Antimatter, Infinity, Time) (multiplicative until 32x). Forever. ", - multiplier: purchases => (purchases > 4 ? 32 * (purchases - 4) : Math.pow(2, purchases)), - } + description: "Double ALL Dimension multipliers (Antimatter, Infinity, Time) (multiplicative until 32x). Forever.", + multiplier: purchases => (purchases > 4 ? 32 + (purchases - 5) * 2 : Math.pow(2, purchases)), + }, + replicantiPurchases: { + key: "replicantiPurchases", + cost: 60, + description: "Increase your Replicanti gain by 50%. (additive)", + multiplier: purchases => (purchases === 0 ? 1 : 1 + 0.5 * purchases), + formatEffect: x => formatX(x, 2, 1), + }, + dilatedTimePurchases: { + key: "dilatedTimePurchases", + cost: 40, + description: "Increase your Dilated Time gain by 50%. (additive)", + multiplier: purchases => (purchases === 0 ? 1 : 1 + 0.5 * purchases), + formatEffect: x => formatX(x, 2, 1), + }, + smallTimeSkip: { + key: "smallTimeSkip", + cost: 10, + description: "Get 6 hours worth of offline production. (Autobuyers don't work at full speed)", + singleUse: true, + onPurchase: () => { + kong.purchaseTimeSkip(); + } + }, + bigTimeSkip: { + key: "bigTimeSkip", + cost: 20, + description: "Get 24 hours worth of offline production. (Autobuyers don't work at full speed)", + singleUse: true, + onPurchase: () => { + kong.purchaseLongerTimeSkip(); + } + }, }; diff --git a/javascripts/core/secret-formula/speedrun-milestones.js b/javascripts/core/secret-formula/speedrun-milestones.js index 02e675cac..d435ef202 100644 --- a/javascripts/core/secret-formula/speedrun-milestones.js +++ b/javascripts/core/secret-formula/speedrun-milestones.js @@ -1,4 +1,4 @@ -import { GameDatabase } from "./game-database.js"; +import { GameDatabase } from "./game-database"; GameDatabase.speedrunMilestones = [ { @@ -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, }, { @@ -164,8 +164,8 @@ GameDatabase.speedrunMilestones = [ { id: 21, key: "completeEnslavedReality", - name: "The Enslaved Ones' Reality", - description: "Complete The Enslaved Ones' Reality", + name: "The Nameless Ones' Reality", + description: "Complete The Nameless Ones' Reality", checkRequirement: () => Enslaved.isRunning, checkEvent: GAME_EVENT.REALITY_RESET_BEFORE, }, diff --git a/javascripts/core/secret-formula/tab-notifications.js b/javascripts/core/secret-formula/tab-notifications.js index 8f03eb1e9..58de3555b 100644 --- a/javascripts/core/secret-formula/tab-notifications.js +++ b/javascripts/core/secret-formula/tab-notifications.js @@ -1,5 +1,6 @@ -import { GameDatabase } from "./game-database.js"; -import { DC } from "../constants.js"; +import { DC } from "../constants"; + +import { GameDatabase } from "./game-database"; GameDatabase.tabNotifications = { firstInfinity: { @@ -107,7 +108,8 @@ GameDatabase.tabNotifications = { } ], condition: () => !PlayerProgress.realityUnlocked() && TimeStudy.reality.canBeBought, - events: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.SAVE_CONVERTED_FROM_PREVIOUS_VERSION] + events: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.SAVE_CONVERTED_FROM_PREVIOUS_VERSION, + GAME_EVENT.OFFLINE_CURRENCY_GAINED, GAME_EVENT.ACHIEVEMENT_UNLOCKED] }, blackHoleUnlock: { id: 8, @@ -143,7 +145,7 @@ GameDatabase.tabNotifications = { tab: "teresa" } ], - condition: () => player.celestials.teresa.pouredAmount !== 0 && Teresa.isUnlocked, + condition: () => player.celestials.teresa.pouredAmount === 0 && Teresa.isUnlocked, events: [GAME_EVENT.REALITY_UPGRADE_BOUGHT] }, alchemyUnlock: { @@ -161,4 +163,15 @@ GameDatabase.tabNotifications = { condition: () => player.celestials.ra.pets.effarig.level >= 2, events: [GAME_EVENT.GAME_TICK_AFTER] }, + newAutobuyer: { + id: 12, + tabsToHighLight: [ + { + parent: "automation", + tab: "autobuyers" + }, + ], + // Always externally triggered + condition: () => true, + }, }; diff --git a/javascripts/core/secret-formula/tabs.js b/javascripts/core/secret-formula/tabs.js index 8f256ffbe..3ef407045 100644 --- a/javascripts/core/secret-formula/tabs.js +++ b/javascripts/core/secret-formula/tabs.js @@ -1,4 +1,4 @@ -import { GameDatabase } from "./game-database.js"; +import { GameDatabase } from "./game-database"; GameDatabase.tabs = [ { @@ -160,6 +160,7 @@ GameDatabase.tabs = [ name: "Automation", id: 4, hideAt: 2.1, + condition: () => player.records.totalAntimatter.gte(1e40), hidable: true, subtabs: [ { @@ -322,7 +323,6 @@ GameDatabase.tabs = [ key: "reality", name: "Reality", hideAt: 2.3, - before: "RealityMachinesHeader", UIClass: "o-tab-btn--reality", condition: () => PlayerProgress.realityUnlocked() || TimeStudy.reality.isBought, id: 8, @@ -375,7 +375,7 @@ GameDatabase.tabs = [ name: "Glyph Alchemy", symbol: "", component: "AlchemyTab", - condition: () => Ra.has(RA_UNLOCKS.GLYPH_ALCHEMY), + condition: () => Ra.unlocks.unlockGlyphAlchemy.canBeApplied, id: 5, hidable: true, }, @@ -411,14 +411,14 @@ GameDatabase.tabs = [ name: "Effarig", symbol: "Ϙ", component: "EffarigTab", - condition: () => Teresa.has(TERESA_UNLOCKS.EFFARIG), + condition: () => TeresaUnlocks.effarig.isUnlocked, id: 2, hidable: true, }, { key: "enslaved", - name: "The Enslaved Ones", - symbol: "", + name: "The Nameless Ones", + symbol: "
+ pause 10s
+ eternity respec