diff --git a/Pictures/Legacy/CubeUpgrade16.png b/Pictures/Legacy/CubeUpgrade16.png index cd87c6a0b..5bc608477 100644 Binary files a/Pictures/Legacy/CubeUpgrade16.png and b/Pictures/Legacy/CubeUpgrade16.png differ diff --git a/Pictures/Legacy/CubeUpgrade2.png b/Pictures/Legacy/CubeUpgrade2.png index f925a85cc..9873fac12 100644 Binary files a/Pictures/Legacy/CubeUpgrade2.png and b/Pictures/Legacy/CubeUpgrade2.png differ diff --git a/Pictures/Legacy/CubeUpgrade37.png b/Pictures/Legacy/CubeUpgrade37.png index a46bd76dd..efb3e647c 100644 Binary files a/Pictures/Legacy/CubeUpgrade37.png and b/Pictures/Legacy/CubeUpgrade37.png differ diff --git a/Pictures/Legacy/CubeUpgrade47.png b/Pictures/Legacy/CubeUpgrade47.png index 45e486f76..f68dd0a2a 100644 Binary files a/Pictures/Legacy/CubeUpgrade47.png and b/Pictures/Legacy/CubeUpgrade47.png differ diff --git a/Pictures/Legacy/CubeUpgrade49.png b/Pictures/Legacy/CubeUpgrade49.png index 8d6128552..476f6b0d2 100644 Binary files a/Pictures/Legacy/CubeUpgrade49.png and b/Pictures/Legacy/CubeUpgrade49.png differ diff --git a/Pictures/Legacy/Research110.png b/Pictures/Legacy/Research110.png index 6ad07b5f8..d07970b84 100644 Binary files a/Pictures/Legacy/Research110.png and b/Pictures/Legacy/Research110.png differ diff --git a/Pictures/Legacy/Research148.png b/Pictures/Legacy/Research148.png index 10942e7a7..321a9a6de 100644 Binary files a/Pictures/Legacy/Research148.png and b/Pictures/Legacy/Research148.png differ diff --git a/Pictures/Legacy/Research169.png b/Pictures/Legacy/Research169.png index 87dd5d890..2f7b8d66f 100644 Binary files a/Pictures/Legacy/Research169.png and b/Pictures/Legacy/Research169.png differ diff --git a/Pictures/Monotonous/CubeUpgrade16.png b/Pictures/Monotonous/CubeUpgrade16.png index 0c9d82b18..5bc608477 100644 Binary files a/Pictures/Monotonous/CubeUpgrade16.png and b/Pictures/Monotonous/CubeUpgrade16.png differ diff --git a/Pictures/Monotonous/CubeUpgrade2.png b/Pictures/Monotonous/CubeUpgrade2.png index f829ad962..9873fac12 100644 Binary files a/Pictures/Monotonous/CubeUpgrade2.png and b/Pictures/Monotonous/CubeUpgrade2.png differ diff --git a/Pictures/Monotonous/CubeUpgrade37.png b/Pictures/Monotonous/CubeUpgrade37.png index 98a45bcc2..efb3e647c 100644 Binary files a/Pictures/Monotonous/CubeUpgrade37.png and b/Pictures/Monotonous/CubeUpgrade37.png differ diff --git a/Pictures/Monotonous/CubeUpgrade47.png b/Pictures/Monotonous/CubeUpgrade47.png index e9a14e6a3..f68dd0a2a 100644 Binary files a/Pictures/Monotonous/CubeUpgrade47.png and b/Pictures/Monotonous/CubeUpgrade47.png differ diff --git a/Pictures/Monotonous/CubeUpgrade49.png b/Pictures/Monotonous/CubeUpgrade49.png index 317132ac0..476f6b0d2 100644 Binary files a/Pictures/Monotonous/CubeUpgrade49.png and b/Pictures/Monotonous/CubeUpgrade49.png differ diff --git a/Pictures/Monotonous/Research110.png b/Pictures/Monotonous/Research110.png index 591ec2ff0..d07970b84 100644 Binary files a/Pictures/Monotonous/Research110.png and b/Pictures/Monotonous/Research110.png differ diff --git a/Pictures/Monotonous/Research148.png b/Pictures/Monotonous/Research148.png index 69082a2f1..321a9a6de 100644 Binary files a/Pictures/Monotonous/Research148.png and b/Pictures/Monotonous/Research148.png differ diff --git a/Pictures/Monotonous/Research169.png b/Pictures/Monotonous/Research169.png index 0f2d98e49..2f7b8d66f 100644 Binary files a/Pictures/Monotonous/Research169.png and b/Pictures/Monotonous/Research169.png differ diff --git a/Pictures/PseudoShop/REBORN_ELO_BUFF.png b/Pictures/PseudoShop/REBORN_ELO_BUFF.png index 7ee440d7a..eae039164 100644 Binary files a/Pictures/PseudoShop/REBORN_ELO_BUFF.png and b/Pictures/PseudoShop/REBORN_ELO_BUFF.png differ diff --git a/Pictures/Simplified/CubeUpgrade16.png b/Pictures/Simplified/CubeUpgrade16.png index 10ded31d1..5bc608477 100644 Binary files a/Pictures/Simplified/CubeUpgrade16.png and b/Pictures/Simplified/CubeUpgrade16.png differ diff --git a/Pictures/Simplified/CubeUpgrade2.png b/Pictures/Simplified/CubeUpgrade2.png index d60107740..9873fac12 100644 Binary files a/Pictures/Simplified/CubeUpgrade2.png and b/Pictures/Simplified/CubeUpgrade2.png differ diff --git a/Pictures/Simplified/CubeUpgrade37.png b/Pictures/Simplified/CubeUpgrade37.png index 9b001919d..efb3e647c 100644 Binary files a/Pictures/Simplified/CubeUpgrade37.png and b/Pictures/Simplified/CubeUpgrade37.png differ diff --git a/Pictures/Simplified/CubeUpgrade47.png b/Pictures/Simplified/CubeUpgrade47.png index f9f40ff08..f68dd0a2a 100644 Binary files a/Pictures/Simplified/CubeUpgrade47.png and b/Pictures/Simplified/CubeUpgrade47.png differ diff --git a/Pictures/Simplified/CubeUpgrade49.png b/Pictures/Simplified/CubeUpgrade49.png index e082a8516..476f6b0d2 100644 Binary files a/Pictures/Simplified/CubeUpgrade49.png and b/Pictures/Simplified/CubeUpgrade49.png differ diff --git a/Pictures/Simplified/Research110.png b/Pictures/Simplified/Research110.png index f58e00638..d07970b84 100644 Binary files a/Pictures/Simplified/Research110.png and b/Pictures/Simplified/Research110.png differ diff --git a/Pictures/Simplified/Research148.png b/Pictures/Simplified/Research148.png index 6505a6e99..321a9a6de 100644 Binary files a/Pictures/Simplified/Research148.png and b/Pictures/Simplified/Research148.png differ diff --git a/Pictures/Simplified/Research169.png b/Pictures/Simplified/Research169.png index 968a40400..2f7b8d66f 100644 Binary files a/Pictures/Simplified/Research169.png and b/Pictures/Simplified/Research169.png differ diff --git a/Synergism.css b/Synergism.css index 9a81d8a66..767910762 100644 --- a/Synergism.css +++ b/Synergism.css @@ -343,6 +343,15 @@ body button:active:not(:disabled):not(.disable-hover-color) { animation-fill-mode: forwards; } +.iconAndNameContainer { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 10px; + padding: 10px; +} + #notification > p { position: fixed; top: 50%; @@ -2601,6 +2610,32 @@ p#reincarnatehotkeys { margin: 0; } +#lotusCorner { + border: 2px solid pink; + width: 66%; + justify-self: center; +} + +#lotusCorner p { + margin: 0; +} + +#lotusButtons { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; +} + +#use-lotus { + border: 2px solid pink; + width: 50%; + height: 30px; +} + + + #antSacrificeObtainiumOfferings, #antSacrificeShardsRow1, #antSacrificeShardsRow2 { @@ -4488,6 +4523,16 @@ header #obtainiumDisplay { color: pink; } --gradient-end: lightgoldenrodyellow; } +.bellGradient { + --gradient-start: gold; + --gradient-end: darkgoldenrod; +} + +.lotusGradient { + --gradient-start: purple; + --gradient-end: pink; +} + .singularityUpgrade > img, .octeractUpgrade > img, .singularityChallenge img { @@ -5446,6 +5491,7 @@ form input:hover { border: 2px solid var(--amber-text-color); padding: 5px; box-sizing: border-box; + width: 50%; } .consumablePurchaseBtn { @@ -5463,7 +5509,7 @@ form input:hover { flex-direction: row; justify-content: center; align-items: center; - margin: 0 auto; + width: 100%; } .timeSkipContainer { @@ -5471,8 +5517,7 @@ form input:hover { flex-direction: column; justify-content: center; align-items: center; - margin: 0; - width: 33%; + width: 33.333%; height: 30%; } @@ -5485,6 +5530,24 @@ form input:hover { padding: 0; } +#topRowConsumables { + display: flex; + flex-direction: row; + width: 100%; +} + +.lotusHeaderText { + text-align: center; +} + +.lotusHeaderText p { + margin: 0; +} + +.lotusContainer { + border: 2px solid pink !important; +} + /* Cost text */ #consumablesGrid > div > button > :nth-child(2) { color: var(--amber-text-color); diff --git a/index.html b/index.html index 46dbe440f..235094d4d 100644 --- a/index.html +++ b/index.html @@ -1813,6 +1813,26 @@

+
+
+
+
+ +

+
+

+

+

+
+

+

+
+ + +
+
+

+

diff --git a/src/Calculate.ts b/src/Calculate.ts index a5865b135..40ec958a0 100644 --- a/src/Calculate.ts +++ b/src/Calculate.ts @@ -20,7 +20,7 @@ import { calculateAscensionScorePlatonicBlessing } from './PlatonicCubes' import { PCoinUpgradeEffects } from './PseudoCoinUpgrades' import { quarkHandler } from './Quark' import { getRedAmbrosiaUpgradeEffects } from './RedAmbrosiaUpgrades' -import { reset, updatePrestigeCount, updateReincarnationCount, updateTranscensionCount } from './Reset' +import { updatePrestigeCount, updateReincarnationCount, updateTranscensionCount } from './Reset' import { getRuneEffects, sumOfRuneLevels } from './Runes' import { getGQUpgradeEffect } from './singularity' import { @@ -802,17 +802,6 @@ export const calculateOffline = (forceTime = 0, fromTips = false) => { ) player.offlinetick = updatedTime - if (!player.loadedNov13Vers) { - if ( - player.challengecompletions[14] > 0 - || player.highestchallengecompletions[14] > 0 - ) { - const ascCount = player.ascensionCount - reset('ascensionChallenge') - player.ascensionCount = ascCount + 1 - } - player.loadedNov13Vers = true - } saveSynergy() diff --git a/src/Event.ts b/src/Event.ts index 395149e1b..7315469c6 100644 --- a/src/Event.ts +++ b/src/Event.ts @@ -3,7 +3,7 @@ import { allDurableConsumables, type PseudoCoinConsumableNames } from './Login' import { getGQUpgradeEffect } from './singularity' import { getTimePinnedToLoadDate, player } from './Synergism' import { revealStuff } from './UpdateHTML' -import { timeReminingHours } from './Utility' +import { timeRemainingHours } from './Utility' import { Globals as G } from './Variables' export enum BuffType { @@ -69,7 +69,7 @@ export const eventCheck = async () => { } const eventNowEndDate = new Date(nowEvent?.end ?? 0) - DOMCacheGetOrSet('globalEventTimer').textContent = timeReminingHours(eventNowEndDate) + DOMCacheGetOrSet('globalEventTimer').textContent = timeRemainingHours(eventNowEndDate) const updateIsEventCheck = G.isEvent diff --git a/src/EventListeners.ts b/src/EventListeners.ts index d11de4fc4..9e0e750d6 100644 --- a/src/EventListeners.ts +++ b/src/EventListeners.ts @@ -88,7 +88,7 @@ import { resetGame, updateSaveString } from './ImportExport' -import { exitFastForward, getTips, sendToWebsocket, setTips } from './Login' +import { exitFastForward, getLotusTimeExpiresAt, getOwnedLotus, getTips, sendToWebsocket, setTips } from './Login' import { buyOcteractUpgradeLevel, type OcteractDataKeys, @@ -184,6 +184,7 @@ import { } from './Toggles' import type { FirstToEighth, FirstToFifth, OneToFive, Player } from './types/Synergism' import { + Alert, closeChangelog, CloseModal, Confirm, @@ -895,6 +896,32 @@ export const generateEventHandlers = () => { updateOnlySacrificeMaxRebornELOToggle(player.ants.toggles.onlySacrificeMaxRebornELO) }) + document.getElementById('use-lotus')?.addEventListener('click', () => { + const timeNow = Date.now() + const lotusTime = getLotusTimeExpiresAt() + let extraHTML = '' + if (lotusTime !== undefined && timeNow < lotusTime) { + extraHTML = `${i18next.t('pseudoCoins.lotus.useConfirmMulti')}` + } + Confirm(`${i18next.t('pseudoCoins.lotus.useConfirm')} ${extraHTML}`) + .then((bool) => { + if (!bool) { + return + } + + if (getOwnedLotus() < 1) { + return Alert(i18next.t('pseudoCoins.lotus.noLotus')) + } + + sendToWebsocket( + JSON.stringify({ + type: 'applied-lotus', + amount: 1 + }) + ) + }) + }) + // Part 3.5: Leaderboard DOMCacheGetOrSet('antLeaderboardToggle').addEventListener('click', () => toggleLeaderboardMode()) DOMCacheGetOrSet('antLeaderboardValueAmount').addEventListener('mousemove', (e: MouseEvent) => { diff --git a/src/Features/Ants/AntSacrifice/Rewards/ELO/RebornELO/lib/create-reborn.ts b/src/Features/Ants/AntSacrifice/Rewards/ELO/RebornELO/lib/create-reborn.ts index 41f4e36a7..14b823b70 100644 --- a/src/Features/Ants/AntSacrifice/Rewards/ELO/RebornELO/lib/create-reborn.ts +++ b/src/Features/Ants/AntSacrifice/Rewards/ELO/RebornELO/lib/create-reborn.ts @@ -1,3 +1,4 @@ +import { getLotusTimeExpiresAt } from '../../../../../../../Login' import { player } from '../../../../../../../Synergism' import { availableQuarksFromELO } from '../QuarkCorner/lib/calculate-quarks' import { updateAntLeaderboards } from '../QuarkCorner/lib/leaderboard-update' @@ -7,22 +8,29 @@ import { calculateAvailableRebornELO, rebornELOCreationSpeedMult } from './calcu export const activateELO = (dt: number) => { const toActivate = calculateAvailableRebornELO() if (toActivate > 0) { - const limit = player.ants.immortalELO - player.ants.rebornELO - const gain = Math.min(limit, dt * rebornELOCreationSpeedMult()) - let stages = calculateRebornELOThresholds(player.ants.rebornELO) - let ELOToNextThreshold = calculateToNextELOThreshold(player.ants.rebornELO, stages) - let budget = gain + const time = Date.now() + // Lotus is active. + const lotusTimeExpiresAt = getLotusTimeExpiresAt() + if (lotusTimeExpiresAt !== undefined && time < lotusTimeExpiresAt) { + player.ants.rebornELO = player.ants.immortalELO + } else { + const limit = player.ants.immortalELO - player.ants.rebornELO + const gain = Math.min(limit, dt * rebornELOCreationSpeedMult()) + let stages = calculateRebornELOThresholds(player.ants.rebornELO) + let ELOToNextThreshold = calculateToNextELOThreshold(player.ants.rebornELO, stages) + let budget = gain - while (budget >= ELOToNextThreshold) { - player.ants.rebornELO += ELOToNextThreshold - budget -= ELOToNextThreshold - budget /= 1.02 // Each threshold makes further ELO harder to gain - stages++ - ELOToNextThreshold = calculateToNextELOThreshold(player.ants.rebornELO, stages) - } + while (budget >= ELOToNextThreshold) { + player.ants.rebornELO += ELOToNextThreshold + budget -= ELOToNextThreshold + budget /= 1.02 // Each threshold makes further ELO harder to gain + stages++ + ELOToNextThreshold = calculateToNextELOThreshold(player.ants.rebornELO, stages) + } - player.ants.rebornELO += budget - player.ants.rebornELO = Math.min(player.ants.rebornELO, player.ants.immortalELO) + player.ants.rebornELO += budget + player.ants.rebornELO = Math.min(player.ants.rebornELO, player.ants.immortalELO) + } } updateAntLeaderboards() const quarksToBeGained = availableQuarksFromELO() diff --git a/src/Features/Ants/HTML/updates/sacrifice.ts b/src/Features/Ants/HTML/updates/sacrifice.ts index 1a217bc7c..cc1ce5f84 100644 --- a/src/Features/Ants/HTML/updates/sacrifice.ts +++ b/src/Features/Ants/HTML/updates/sacrifice.ts @@ -2,8 +2,9 @@ import type Decimal from 'break_infinity.js' import i18next from 'i18next' import { getAchievementReward } from '../../../../Achievements' import { DOMCacheGetOrSet } from '../../../../Cache/DOM' +import { getLotusTimeExpiresAt, getOwnedLotus } from '../../../../Login' import { format, player } from '../../../../Synergism' -import { toOrdinal } from '../../../../Utility' +import { timeRemainingMinutes, toOrdinal } from '../../../../Utility' import { antSacrificeRewards } from '../../AntSacrifice/Rewards/calculate-rewards' import { calculateEffectiveAntELO } from '../../AntSacrifice/Rewards/ELO/AntELO/lib/calculate' import { calculateAntSpeedMultFromELO } from '../../AntSacrifice/Rewards/ELO/RebornELO/lib/ant-speed' @@ -86,6 +87,13 @@ export const showSacrifice = () => { DOMCacheGetOrSet('antSacrificeOffering').textContent = `+${format(sacRewards.offerings)}` DOMCacheGetOrSet('antSacrificeObtainium').textContent = `+${format(sacRewards.obtainium)}` + DOMCacheGetOrSet('lotusStatus').innerHTML = i18next.t('pseudoCoins.lotus.status', { + time: timeRemainingMinutes(getLotusTimeExpiresAt()) + }) + DOMCacheGetOrSet('lotusOwnedAnt').innerHTML = i18next.t('pseudoCoins.lotus.owned', { + x: format(getOwnedLotus(), 0, true) + }) + if (player.challengecompletions[9] > 0) { // Helper function to update reward display and styling const updateRewardDisplay = ( diff --git a/src/Login.ts b/src/Login.ts index 0cecdf94c..80ae6a07c 100644 --- a/src/Login.ts +++ b/src/Login.ts @@ -8,6 +8,7 @@ import { calculateAmbrosiaGenerationSpeed, calculateOffline, calculateRedAmbrosi import { updateGlobalsIsEvent } from './Event' import { addTimers, automaticTools } from './Helper' import { exportData, importSynergism, saveFilename } from './ImportExport' +import { updateLotusDisplay } from './purchases/ConsumablesTab' import { updatePseudoCoins } from './purchases/UpgradesSubtab' import { QuarkHandler, setPersonalQuarkBonus } from './Quark' import { updatePrestigeCount, updateReincarnationCount, updateTranscensionCount } from './Reset' @@ -69,13 +70,22 @@ const DIAMOND_SMITH_MESSIAH = '1311165096378105906' let ws: WebSocket | undefined let loggedIn = false let tips = 0 +let ownedLotus = 0 +let usedLotus = 0 let subscription: SubscriptionMetadata = null +let lotusTimeExpiresAt: number | undefined = undefined const cloudSaves: Save[] = [] export const isLoggedIn = () => loggedIn + export const getTips = () => tips export const setTips = (newTips: number) => tips = newTips + +export const getOwnedLotus = () => ownedLotus +export const getUsedLotus = () => usedLotus +export const getLotusTimeExpiresAt = () => lotusTimeExpiresAt + export const getSubMetadata = () => subscription // For testing purposes only export const setSubMetadata = (newSub: SubscriptionMetadata) => { @@ -125,7 +135,12 @@ const messageSchema = z.preprocess( internalName: z.string(), endsAt: z.number().int() }).array(), - tips: z.number().int().nonnegative() + tips: z.number().int().nonnegative(), + inventory: z.object({ + type: z.literal('LOTUS'), + amount: z.number().int().positive(), + used: z.number().int().positive() + }).array() }), /** Received after the *user* successfully redeems a consumable. */ z.object({ type: z.literal('thanks') }), @@ -143,6 +158,27 @@ const messageSchema = z.preprocess( amount: z.number().int() }), + /** Received when a player *buys* a Lotus Package */ + z.object({ + type: z.literal('lotus'), + consumableName: z.string(), + amount: z.number().int() + }), + + /** Received when a player *consumes* a Lotus */ + z.object({ + type: z.literal('applied-lotus'), + remaining: z.number(), + lifetimePurchased: z.number() + }), + + z.object({ type: z.literal('lotus-ended') }), + + z.object({ + type: z.literal('lotus-active'), + remainingMs: z.number() + }), + /** A warning - should *NOT* disconnect from the WebSocket */ z.object({ type: z.literal('warn'), message: z.string() }) ]) @@ -414,7 +450,7 @@ const queue: string[] = [] const exponentialBackoff = [5000, 15000, 30000, 60000] let tries = 0 -function resetConsumables () { +function resetWebSocket () { for (const key of Object.keys(allDurableConsumables)) { allDurableConsumables[key as PseudoCoinConsumableNames] = { amount: 0, @@ -422,6 +458,8 @@ function resetConsumables () { displayName: '' } } + + lotusTimeExpiresAt = undefined } function handleWebSocket () { @@ -438,7 +476,7 @@ function handleWebSocket () { Notification( 'Could not re-establish your connection. Consumables and events related to Consumables will not work.' ) - resetConsumables() + resetWebSocket() } }) @@ -459,7 +497,7 @@ function handleWebSocket () { Notification(data.message, 5_000) } else if (data.type === 'error') { Notification(data.message, 5_000) - resetConsumables() + resetWebSocket() } else if (data.type === 'consumed') { const consumable = allDurableConsumables[data.consumable as PseudoCoinConsumableNames] consumable.ends.push(data.startedAt + 3600 * 1000) @@ -478,7 +516,7 @@ function handleWebSocket () { } else if (data.type === 'join') { Notification('Connection was established!') } else if (data.type === 'info-all') { - resetConsumables() // So that we can get an accurate count each time + resetWebSocket() // So that we can get an accurate count each time if (data.active.length !== 0) { let message = 'The following consumables are active:\n' @@ -501,6 +539,14 @@ function handleWebSocket () { } tips = data.tips + + const lotusInventory = data.inventory.find((item) => item.type === 'LOTUS') + + if (lotusInventory) { + ownedLotus = lotusInventory.amount + usedLotus = lotusInventory.used + updateLotusDisplay() + } } else if (data.type === 'thanks') { Alert(i18next.t('pseudoCoins.consumables.thanks')) updatePseudoCoins() @@ -527,6 +573,33 @@ function handleWebSocket () { })) setTimeout(() => updatePseudoCoins(), 4000) + } else if (data.type === 'lotus') { + buyLotusNotification(data.amount) + ownedLotus += data.amount + updateLotusDisplay() + + setTimeout(() => updatePseudoCoins(), 4000) + } else if (data.type === 'applied-lotus') { + ownedLotus -= 1 + usedLotus = data.lifetimePurchased + lotusTimeExpiresAt = Date.now() + data.remaining + + updateLotusDisplay() + } else if (data.type === 'lotus-ended') { + lotusTimeExpiresAt = undefined + + updateLotusDisplay() + } else if (data.type === 'lotus-active') { + lotusTimeExpiresAt = Date.now() + data.remainingMs + updateLotusDisplay() + + Notification(i18next.t('pseudoCoins.lotus.lotusActive')) + } else { + const assertNever = (_x: never) => { + throw new Error() + } + + assertNever(data) } updateGlobalsIsEvent() @@ -740,6 +813,14 @@ const activateTimeSkip = (name: PseudoCoinTimeskipNames, minutes: number) => { } } +const buyLotusNotification = (amount: number) => { + if (amount === 1) { + Notification('You have successfully purchased a lotus. Enjoy!') + } else { + Notification(`You have successfully purchased ${amount} loti. Enjoy!`) + } +} + function handleCloudSaves () { const subtabElement = document.querySelector('#accountSubTab div#right.scrollbarX')! const table = subtabElement.querySelector('#table > #dataGrid')! diff --git a/src/PseudoCoinUpgrades.ts b/src/PseudoCoinUpgrades.ts index 1c42d116d..d3f6befde 100644 --- a/src/PseudoCoinUpgrades.ts +++ b/src/PseudoCoinUpgrades.ts @@ -43,7 +43,7 @@ export const PCoinUpgrades: PseudoCoinUpgrades = { 'BASE_OFFERING_BUFF': 0, 'BASE_OBTAINIUM_BUFF': 0, 'RED_GENERATION_BUFF': 0, - 'RED_LUCK_BUFF': 0 + 'RED_LUCK_BUFF': 0, } export const PCoinUpgradeEffects: PseudoCoinUpgradeEffects = { @@ -62,7 +62,7 @@ export const PCoinUpgradeEffects: PseudoCoinUpgradeEffects = { BASE_OFFERING_BUFF: 0, BASE_OBTAINIUM_BUFF: 0, RED_GENERATION_BUFF: 1, - RED_LUCK_BUFF: 0 + RED_LUCK_BUFF: 0, } export const initializePCoinCache = async () => { diff --git a/src/Synergism.ts b/src/Synergism.ts index e693cb8b2..de1982602 100644 --- a/src/Synergism.ts +++ b/src/Synergism.ts @@ -612,12 +612,6 @@ export const player: Player = { // create a Map with keys defaulting to false codes: new Map(Array.from({ length: 48 }, (_, i) => [i + 1, false])), - loaded1009: true, - loaded1009hotfix1: true, - loaded10091: true, - loaded1010: true, - loaded10101: true, - shopUpgrades: { offeringPotion: 1, obtainiumPotion: 1, @@ -1047,17 +1041,6 @@ export const player: Player = { overfluxPowder: 0, dailyPowderResetUses: 1, autoWarpCheck: false, - loadedOct4Hotfix: false, - loadedNov13Vers: true, - loadedDec16Vers: true, - loadedV253: true, - loadedV255: true, - loadedV297Hotfix1: true, - loadedV2927Hotfix1: true, - loadedV2930Hotfix1: true, - loadedV2931Hotfix1: true, - loadedV21003Hotfix1: true, - loadedV21007Hotfix1: true, version, rngCode: 0, promoCodeTiming: { @@ -1186,8 +1169,6 @@ export const blankSave = deepClone()(player) export const saveSynergy = (button?: boolean) => { player.offlinetick = Date.now() - player.loaded1009 = true - player.loaded1009hotfix1 = true // save to player.goldenQuarkUpgrades, taking the level and freeLevel from corresponding goldenQuarkUpgrades from singularity.ts player.goldenQuarkUpgrades = Object.fromEntries( @@ -1361,22 +1342,6 @@ const loadSynergy = () => { } } - if (data.loaded1009 === undefined || !data.loaded1009) { - player.loaded1009 = false - } - if (data.loaded1009hotfix1 === undefined || !data.loaded1009hotfix1) { - player.loaded1009hotfix1 = false - } - if (data.loaded10091 === undefined) { - player.loaded10091 = false - } - if (data.loaded1010 === undefined) { - player.loaded1010 = false - } - if (data.loaded10101 === undefined) { - player.loaded10101 = false - } - // Does this need to be kept here? if (player.transcendCount < 0) { player.transcendCount = 0 diff --git a/src/UpdateVisuals.ts b/src/UpdateVisuals.ts index 8459334aa..e22a56197 100644 --- a/src/UpdateVisuals.ts +++ b/src/UpdateVisuals.ts @@ -125,7 +125,7 @@ import { } from './Tesseracts' import type { Player, ZeroToFour } from './types/Synergism' import { updateChallengeDisplay } from './UpdateHTML' -import { sumContents, timeReminingHours } from './Utility' +import { sumContents, timeRemainingHours } from './Utility' import { Globals as G } from './Variables' export const visualUpdateBuildings = () => { @@ -2050,7 +2050,7 @@ export const visualUpdateShop = () => { export const constructConsumableTimes = (p: PseudoCoinConsumableNames) => { const msg: string[] = [] for (const time of allDurableConsumables[p].ends) { - msg.push(timeReminingHours(new Date(time))) + msg.push(timeRemainingHours(new Date(time))) } return msg.join(', ') } @@ -2059,7 +2059,7 @@ export const visualUpdateEvent = () => { const event = getEvent() if (event !== null) { const eventEnd = new Date(event.end) - DOMCacheGetOrSet('globalEventTimer').textContent = timeReminingHours(eventEnd) + DOMCacheGetOrSet('globalEventTimer').textContent = timeRemainingHours(eventEnd) DOMCacheGetOrSet('globalEventName').textContent = `(${event.name.length}) - ${event.name.join(', ')}` for (let i = 0; i < eventBuffType.length; i++) { diff --git a/src/Utility.ts b/src/Utility.ts index 7b3b5fa59..34ba8d5a2 100644 --- a/src/Utility.ts +++ b/src/Utility.ts @@ -192,7 +192,7 @@ export const addLeadingZero = (n: number): string => { return n < 10 ? `0${n}` : String(n) } -export const timeReminingHours = (targetDate: Date): string => { +export const timeRemainingHours = (targetDate: Date): string => { const now = new Date() const timeDifference = targetDate.getTime() - now.getTime() @@ -206,6 +206,24 @@ export const timeReminingHours = (targetDate: Date): string => { return `${hours}:${minutes}:${seconds}` } +export const timeRemainingMinutes = (targetDate: number | Date | undefined): string => { + if (targetDate === undefined) { + return '--:--' + } + + const now = Date.now() + const targetTime = targetDate instanceof Date ? targetDate.getTime() : targetDate + const timeDifference = targetTime - now + + if (timeDifference < 0) { + return '--:--' + } + + const minutes = addLeadingZero(Math.floor(timeDifference / (1000 * 60))) + const seconds = addLeadingZero(Math.floor((timeDifference % (1000 * 60)) / 1000)) + + return `${minutes}:${seconds}` +} export const cleanString = (s: string): string => { let cleaned = '' diff --git a/src/mock/browser.ts b/src/mock/browser.ts index c5c75a81d..685dad942 100644 --- a/src/mock/browser.ts +++ b/src/mock/browser.ts @@ -91,6 +91,28 @@ const GETHandlers = [ internalName: 'JUMBO_AMBROSIA_TIMESKIP', cost: 400, length: '1440' + }, + { + name: 'Lotus of Rejuvenation', + description: + 'Grants +1 Lotus, which you can use in the Anthill to instantly gain Reborn ELO for the next five Ant Sacrifices.', + internalName: 'LOTUS_SINGLE', + cost: 20, + length: '1' + }, + { + name: 'dozen Loti of Rejuvenation', + description: 'Grants +12 Lotuses, for the price of 11.', + internalName: 'LOTUS_DOZEN', + cost: 220, + length: '12' + }, + { + name: 'Loti of Rejuvenation bouquet (50)', + description: 'Grants +50 Lotuses, for the price of 40. What a steal!', + internalName: 'LOTUS_BUNDLE', + cost: 800, + length: '50' } ]) }), @@ -529,7 +551,187 @@ const GETHandlers = [ internalName: 'ADD_CODE_CAP_BUFF', level: 2, cost: 600 - } + }, + { + upgradeId: 16, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +6 Base Offerings per level, affected by all multipliers!', + internalName: 'BASE_OFFERING_BUFF', + level: 1, + cost: 100 + }, + { + upgradeId: 16, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +6 Base Offerings per level, affected by all multipliers!', + internalName: 'BASE_OFFERING_BUFF', + level: 2, + cost: 150 + }, + { + upgradeId: 16, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +6 Base Offerings per level, affected by all multipliers!', + internalName: 'BASE_OFFERING_BUFF', + level: 3, + cost: 200 + }, + { + upgradeId: 16, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +6 Base Offerings per level, affected by all multipliers!', + internalName: 'BASE_OFFERING_BUFF', + level: 4, + cost: 250 + }, + { + upgradeId: 16, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +6 Base Offerings per level, affected by all multipliers!', + internalName: 'BASE_OFFERING_BUFF', + level: 5, + cost: 300 + }, + { + upgradeId: 17, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +3 Base Obtainium per level, affected by all multipliers!', + internalName: 'BASE_OBTAINIUM_BUFF', + level: 1, + cost: 100 + }, + { + upgradeId: 17, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +3 Base Obtainium per level, affected by all multipliers!', + internalName: 'BASE_OBTAINIUM_BUFF', + level: 2, + cost: 150 + }, + { + upgradeId: 17, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +3 Base Obtainium per level, affected by all multipliers!', + internalName: 'BASE_OBTAINIUM_BUFF', + level: 3, + cost: 200 + }, + { + upgradeId: 17, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +3 Base Obtainium per level, affected by all multipliers!', + internalName: 'BASE_OBTAINIUM_BUFF', + level: 4, + cost: 250 + }, + { + upgradeId: 17, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +3 Base Obtainium per level, affected by all multipliers!', + internalName: 'BASE_OBTAINIUM_BUFF', + level: 5, + cost: 300 + }, + { + upgradeId: 18, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +20 Red Ambrosia Luck per level', + internalName: 'RED_LUCK_BUFF', + level: 1, + cost: 100 + }, + { + upgradeId: 18, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +20 Red Ambrosia Luck per level', + internalName: 'RED_LUCK_BUFF', + level: 2, + cost: 150 + }, + { + upgradeId: 18, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +20 Red Ambrosia Luck per level', + internalName: 'RED_LUCK_BUFF', + level: 3, + cost: 200 + }, + { + upgradeId: 18, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +20 Red Ambrosia Luck per level', + internalName: 'RED_LUCK_BUFF', + level: 4, + cost: 250 + }, + { + upgradeId: 18, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +20 Red Ambrosia Luck per level', + internalName: 'RED_LUCK_BUFF', + level: 5, + cost: 300 + }, + { + upgradeId: 19, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +5% more Red Ambrosia Bar Points per level', + internalName: 'RED_GENERATION_BUFF', + level: 5, + cost: 300 + }, + { + upgradeId: 19, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +5% more Red Ambrosia Bar Points per level', + internalName: 'RED_GENERATION_BUFF', + level: 4, + cost: 250 + }, + { + upgradeId: 19, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +5% more Red Ambrosia Bar Points per level', + internalName: 'RED_GENERATION_BUFF', + level: 3, + cost: 200 + }, + { + upgradeId: 19, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +5% more Red Ambrosia Bar Points per level', + internalName: 'RED_GENERATION_BUFF', + level: 2, + cost: 150 + }, + { + upgradeId: 19, + maxLevel: 5, + name: 'Multi-Level', + description: 'Receive +5% more Red Ambrosia Bar Points per level', + internalName: 'RED_GENERATION_BUFF', + level: 1, + cost: 100 + }, ], playerUpgrades: [], tier: 0 @@ -651,7 +853,7 @@ const GETHandlers = [ upgradeId: 5, maxLevel: 5, name: 'Multi-Level', - description: 'Rceeive +5% Ambrosia Generation Speed per level', + description: 'Receive +5% Ambrosia Generation Speed per level', internalName: 'AMBROSIA_GENERATION_BUFF', level: 1, cost: 100 @@ -1150,7 +1352,7 @@ const GETHandlers = [ internalName: 'RED_GENERATION_BUFF', level: 1, cost: 100 - } + }, ], playerUpgrades: [], tier: 0 diff --git a/src/mock/util/messages.ts b/src/mock/util/messages.ts index 879680de5..04825aafb 100644 --- a/src/mock/util/messages.ts +++ b/src/mock/util/messages.ts @@ -35,11 +35,12 @@ export const messages = { }) }, - infoAll (active: unknown, tips: number) { + infoAll (active: unknown, inventory: unknown, tips: number) { return JSON.stringify({ type: 'info-all', active, - tips + tips, + inventory }) }, @@ -70,6 +71,39 @@ export const messages = { amount, remaining }) + }, + + /* Received after a player buys loti */ + lotus (name: string, amount: number) { + return JSON.stringify({ + type: 'lotus', + consumableName: name, + amount + }) + }, + + /* Received after a player uses a lotus */ + appliedLotus (remaining: number, lifetimePurchased: number) { + return JSON.stringify({ + type: 'applied-lotus', + remaining, + lifetimePurchased + }) + }, + + /* Received when all loti end */ + lotusEnded () { + return JSON.stringify({ + type: 'lotus-ended' + }) + }, + + /* Received when the timer starts (usually when the player connects, letting them know how many loti they have active) */ + lotusActive (remaining: number) { + return JSON.stringify({ + type: 'lotus-active', + remainingMs: remaining + }) } } @@ -91,6 +125,10 @@ export const messageSchema = z.preprocess( z.object({ type: z.union([z.literal('applied-tip'), z.literal('use-tips')]), amount: z.number().int().nonnegative().safe() + }), + z.object({ + type: z.literal('applied-lotus'), + amount: z.number().int().min(0).safe() }) ]) ) diff --git a/src/mock/websocket.ts b/src/mock/websocket.ts index 2d380b5df..a982a588a 100644 --- a/src/mock/websocket.ts +++ b/src/mock/websocket.ts @@ -4,17 +4,26 @@ import { sleep } from './util/util' const consumable = ws.link('wss://synergism.cc/consumables/connect') let tips = 1000 +const lotus = { + inventory: 0, + used: 0, + active: 0, + activeUntil: 0, + timer: 0 +} export const consumeHandlers = [ consumable.addEventListener('connection', ({ client }) => { console.log('connected', client.url) client.send(messages.join()) + sleep(1000).then(() => client.send(messages.infoAll([], [], tips))) client.addEventListener('message', ({ data: body }) => { const { success, data } = messageSchema.safeParse(body) if (!success) { + console.log('received invalid message', body) client.close(1003, 'invalid message') return } @@ -29,6 +38,16 @@ export const consumeHandlers = [ : 1440 // jumbo sleep(2500).then(() => client.send(messages.timeSkip(data.consumable, length))) + } else if (data.consumable.includes('LOTUS')) { + const amount = data.consumable.includes('SINGLE') + ? 1 + : data.consumable.includes('DOZEN') + ? 12 + : 50 // Huge bundle + + sleep(2500).then(() => { + client.send(messages.lotus(data.consumable, amount)) + }) } else { // Happy Hour Bell sleep(1000).then(() => { consumable.broadcast(messages.consumed(data.consumable, 'Happy Hour Bell', Date.now() + (1000 * 60 * 60))) @@ -42,6 +61,30 @@ export const consumeHandlers = [ const previous = tips tips -= data.amount messages.appliedTips(Math.max(previous - tips, 0), Math.max(tips, 0)) + return + } + case 'applied-lotus': { + if (lotus.activeUntil < Date.now()) { + lotus.activeUntil = Date.now() + } + + lotus.activeUntil += data.amount * 300_000 + console.log('Applying lotus at time', new Date()) + + lotus.active += data.amount + lotus.used += data.amount + lotus.inventory -= data.amount + + client.send(messages.appliedLotus(lotus.activeUntil - Date.now(), lotus.used)) + + if (lotus.timer) { + clearTimeout(lotus.timer) + } + + lotus.timer = setTimeout(() => { + lotus.active -= data.amount + client.send(messages.lotusEnded()) + }, lotus.activeUntil - Date.now()) } } }) diff --git a/src/purchases/ConsumablesTab.ts b/src/purchases/ConsumablesTab.ts index 8f80f79fd..6deb54cce 100644 --- a/src/purchases/ConsumablesTab.ts +++ b/src/purchases/ConsumablesTab.ts @@ -1,5 +1,6 @@ import i18next from 'i18next' -import { sendToWebsocket } from '../Login' +import { DOMCacheGetOrSet } from '../Cache/DOM' +import { getOwnedLotus, getUsedLotus, sendToWebsocket } from '../Login' import { format } from '../Synergism' import { Alert, Confirm } from '../UpdateHTML' import { memoize } from '../Utility' @@ -22,28 +23,36 @@ const initializeConsumablesTab = memoize(() => { .then((r) => r.json()) .then((consumables: ConsumableListItems[]) => { // Thank you Gemini for the number test - const durableConsume = consumables.filter((u) => !u.internalName.includes('TIMESKIP')) + // TODO: Erm... + const durableConsume = consumables.filter((u) => u.internalName.includes('BELL')) const timeSkip = consumables.filter((u) => u.internalName.includes('TIMESKIP')) + const lotus = consumables.filter((u) => u.internalName.includes('LOTUS')) // Update coin count just in case updatePseudoCoins() + const grid = tab!.querySelector('#consumablesGrid')! - grid.innerHTML = `${ + grid.innerHTML = ` +
+ ${ durableConsume.map((u) => ` -
- ${u.name} Consumable -

${u.name}

-

${u.description.replace(/\\n/g, '\n')}

- -
- `).join('') +
+
+ ${u.name} Consumable +

${u.name}

+
+

${u.description.replace(/\\n/g, '\n')}

+ +
+ `).join('') } + ${createLotusHTML(lotus)} +
${createTimeskipHTML(timeSkip, 'GLOBAL')} ${createTimeskipHTML(timeSkip, 'ASCENSION')} @@ -54,17 +63,40 @@ const initializeConsumablesTab = memoize(() => { const key = element.parentElement!.getAttribute('data-key')! const cost = element.parentElement!.getAttribute('data-cost')! const name = element.parentElement!.getAttribute('data-name')! - element.addEventListener('click', async () => { - const alert = await Confirm(`Please confirm you would like to activate a ${name} for ${cost} PseudoCoins`) - if (!alert) return Alert('Purchase cancelled') - else { - sendToWebsocket(JSON.stringify({ - type: 'consume', - consumable: key, - version: '2' + const lotus = element.parentElement?.getAttribute('data-lotus') === 'true' + // TODO (for a future time): Lotus has different verbage since we don't actually + // "activate" them right away. Also, Platonic needs to i18n this like yesterday + if (!lotus) { + element.addEventListener('click', async () => { + const alert = await Confirm(i18next.t('pseudoCoins.consumables.confirmActivation', { + name, + cost + })) + if (!alert) return Alert(i18next.t('pseudoCoins.consumables.cancelled')) + else { + sendToWebsocket(JSON.stringify({ + type: 'consume', + consumable: key, + version: '2' + })) + } + }) + } else { + element.addEventListener('click', async () => { + const alert = await Confirm(i18next.t('pseudoCoins.lotus.buyConfirm', { + name, + cost })) - } - }) + if (!alert) return Alert(i18next.t('pseudoCoins.consumables.cancelled')) + else { + sendToWebsocket(JSON.stringify({ + type: 'consume', + consumable: key, + version: '2' + })) + } + }) + } }) }) }) @@ -78,7 +110,7 @@ export const createTimeskipHTML = (timeSkips: ConsumableListItems[], filter: Tim
${filter} TimeSkip Box

${i18next.t(`pseudoCoins.timeSkips.${filter}.title`)}

-

${i18next.t(`pseudoCoins.timeSkips.${filter}.description`)}

+

${i18next.t(`pseudoCoins.timeSkips.${filter}.description`)}

${i18next.t('pseudoCoins.timeSkips.warning')}

${ @@ -100,6 +132,41 @@ export const createTimeskipHTML = (timeSkips: ConsumableListItems[], filter: Tim ` } +export const createLotusHTML = (lotusItems: ConsumableListItems[]) => { + const orderedLotus = lotusItems.sort((a, b) => +a.length - +b.length) + const html = ` +
+
+ Lotus Box +

${i18next.t('pseudoCoins.lotus.nameSingular')}

+
+
+

${i18next.t('pseudoCoins.lotus.owned', { x: format(getOwnedLotus(), 0, true) })}

+

${i18next.t('pseudoCoins.lotus.lifetimeUsed', { x: format(getUsedLotus(), 0, true) })}

+
+

${i18next.t('pseudoCoins.lotus.intro')}

+
+ ${ + orderedLotus.map((u) => ` +
+ +
+ `).join('') + } +
+
+ ` + + return html +} + export const toggleConsumablesTab = () => { initializeConsumablesTab() @@ -109,3 +176,12 @@ export const toggleConsumablesTab = () => { export const clearConsumablesTab = () => { tab.style.display = 'none' } + +export const updateLotusDisplay = () => { + DOMCacheGetOrSet('lotusOwned').textContent = i18next.t('pseudoCoins.lotus.owned', { + x: format(getOwnedLotus(), 0, true) + }) + DOMCacheGetOrSet('lotusUsed').textContent = i18next.t('pseudoCoins.lotus.lifetimeUsed', { + x: format(getUsedLotus(), 0, true) + }) +} diff --git a/src/purchases/UpgradesSubtab.ts b/src/purchases/UpgradesSubtab.ts index 7473f926d..196f76ce0 100644 --- a/src/purchases/UpgradesSubtab.ts +++ b/src/purchases/UpgradesSubtab.ts @@ -73,10 +73,10 @@ function setActiveUpgrade (upgrade: UpgradesList) { const nextEffect = DOMCacheGetOrSet('pCoinEffectNext') currEffect.innerHTML = `${i18next.t('pseudoCoins.currEffect')} ${ - i18next.t(displayPCoinEffect(upgrade.internalName, upgrade.playerLevel)) + displayPCoinEffect(upgrade.internalName, upgrade.playerLevel) }` nextEffect.innerHTML = `${i18next.t('pseudoCoins.nextEffect')} ${ - i18next.t(displayPCoinEffect(upgrade.internalName, upgrade.playerLevel + 1)) + displayPCoinEffect(upgrade.internalName, upgrade.playerLevel + 1) }` const costs = DOMCacheGetOrSet('pCoinScalingCosts') diff --git a/src/saves/PlayerSchema.ts b/src/saves/PlayerSchema.ts index b78e9fe70..908539614 100644 --- a/src/saves/PlayerSchema.ts +++ b/src/saves/PlayerSchema.ts @@ -639,12 +639,6 @@ export const playerSchema = z.object({ deepClone()([...blankSave.codes]) ), - loaded1009: z.boolean().default(() => blankSave.loaded1009), - loaded1009hotfix1: z.boolean().default(() => blankSave.loaded1009hotfix1), - loaded10091: z.boolean().default(() => blankSave.loaded10091), - loaded1010: z.boolean().default(() => blankSave.loaded1010), - loaded10101: z.boolean().default(() => blankSave.loaded10101), - shopUpgrades: z.record(z.string(), z.union([z.number(), z.null(), z.boolean()])) .transform((object) => { return Object.fromEntries( @@ -880,17 +874,6 @@ export const playerSchema = z.object({ overfluxPowder: z.number().default(() => blankSave.overfluxPowder), dailyPowderResetUses: z.number().default(() => blankSave.dailyPowderResetUses), autoWarpCheck: z.boolean().default(() => blankSave.autoWarpCheck), - loadedOct4Hotfix: z.boolean().default(() => blankSave.loadedOct4Hotfix), - loadedNov13Vers: z.boolean().default(() => blankSave.loadedNov13Vers), - loadedDec16Vers: z.boolean().default(() => blankSave.loadedDec16Vers), - loadedV253: z.boolean().default(() => blankSave.loadedV253), - loadedV255: z.boolean().default(() => blankSave.loadedV255), - loadedV297Hotfix1: z.boolean().default(() => blankSave.loadedV297Hotfix1), - loadedV2927Hotfix1: z.boolean().default(() => blankSave.loadedV2927Hotfix1), - loadedV2930Hotfix1: z.boolean().default(() => blankSave.loadedV2930Hotfix1), - loadedV2931Hotfix1: z.boolean().default(() => blankSave.loadedV2931Hotfix1), - loadedV21003Hotfix1: z.boolean().default(() => blankSave.loadedV21003Hotfix1), - loadedV21007Hotfix1: z.boolean().default(() => blankSave.loadedV21007Hotfix1), version: z.string().default(() => blankSave.version), rngCode: z.number().default(() => blankSave.rngCode), promoCodeTiming: z.record(z.string(), z.number()).default(() => ({ time: Date.now() - 60 * 1000 * 15 })), diff --git a/src/types/Synergism.ts b/src/types/Synergism.ts index 48e6ac622..d76d6b205 100644 --- a/src/types/Synergism.ts +++ b/src/types/Synergism.ts @@ -301,12 +301,6 @@ export interface Player { // create a Map with keys defaulting to boolean codes: Map - loaded1009: boolean - loaded1009hotfix1: boolean - loaded10091: boolean - loaded1010: boolean - loaded10101: boolean - shopUpgrades: { offeringPotion: number obtainiumPotion: number @@ -546,17 +540,7 @@ export interface Player { hypercubeQuarkDaily: number platonicCubeOpenedDaily: number platonicCubeQuarkDaily: number - loadedOct4Hotfix: boolean - loadedNov13Vers: boolean - loadedDec16Vers: boolean - loadedV253: boolean - loadedV255: boolean - loadedV297Hotfix1: boolean - loadedV2927Hotfix1: boolean - loadedV2930Hotfix1: boolean - loadedV2931Hotfix1: boolean - loadedV21003Hotfix1: boolean - loadedV21007Hotfix1: boolean + version: string rngCode: number diff --git a/translations/da.json b/translations/da.json index d2c419ccf..8ef15712e 100644 --- a/translations/da.json +++ b/translations/da.json @@ -1970,15 +1970,6 @@ "buyMaxOff": "Buy Max: OFF", "on": "ON", "off": "OFF", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Changing the language requires a reload! Would you like to reload now?" }, "upgrades": { diff --git a/translations/de.json b/translations/de.json index 513673e28..c130c68d0 100644 --- a/translations/de.json +++ b/translations/de.json @@ -3773,15 +3773,6 @@ "off": "AUS", "buyOne": "Buy x1", "buyMax": "Buy MAX", - "updateAlerts": { - "june282021": "28. Juni. 2021: V2.5.3. Du hast deine Quarks von den Taschenrechnern wiedergekriegt, wenn du welche gekauft hattest. Diese sind nicht länger zurücksetzbar, also sei vorsichtig!", - "july22021": "2. Juli. 2021: V. 2.5.5. Du hast deine Quarks von dem Powder EX Upgrade wiedergekriegt, wenn du welche gekauft hast. Auch deine T1 Ameisen wurden zurückgesetzt und die Grundkosten auf 1e700 Partikel gesetzt. Powder EX ist nicht länger zurücksetzbar, also sei vorsichtig!", - "sing230Balancing": "Aufgrund von Balance Veränderung, wurdest du zu Singularity 230 zurückgesetzt, um dein Speicherstand vor Softlocking zu schützen!", - "december22xxxx": "Du wurdest in den Dezember 22 Patch v1 geladen.", - "january42023": "Du wurdest in den 4. Januar 2023, Patch v1 geladen.", - "v297hotfix1NoSing": "Du wurdest in die Version 2.9.7 Hotfix 1 geladen!", - "v297hotfix1Sing": "Du wurdest in die Version 2.9.7 Hotfix 1 geladen! Deine unbegrenzten Singularity Upgrades wurden zurückerstattet! Entschuldung für die Unannehmlichkeiten." - }, "languageChange": "Wechseln der Sprache erfordert ein neu laden! Möchtest du jetzt neu laden?", "resources": { "offering": "Offering", diff --git a/translations/en.json b/translations/en.json index d2228e317..5e666c87a 100644 --- a/translations/en.json +++ b/translations/en.json @@ -4276,15 +4276,6 @@ "off": "OFF", "buyOne": "Buy x1", "buyMax": "Buy MAX", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Changing the language requires a reload! Would you like to reload now?", "resources": { "offering": "Offering", @@ -7463,9 +7454,11 @@ "thanks": "The booster is now in effect! Thank you for supporting the game!", "eventTitle": "Active Consumables", "consumableSpoiler": "Start an event for everyone, with the Happy Hour Bell!", - "consumableButton": "Buy at the PseudoShop!", + "consumableButton": "Consumables Shop", "applyTips": "Use Tips!", - "applyTipsPrompt": "How many tips would you like to use? Each tip gives 1 minute of Offline Time. You have {{tips}} tip(s). You may only use up to 1,440 tips per " + "applyTipsPrompt": "How many tips would you like to use? Each tip gives 1 minute of Offline Time. You have {{tips}} tip(s). You may only use up to 1,440 tips per ", + "confirmActivation": "You are about to activate a {{name}} for {{cost}} PseudoCoins. Continue?", + "cancelled": "Puchase has been cancelled." }, "timeSkips": { "GLOBAL": { @@ -7482,6 +7475,24 @@ }, "purchaseBtn": "+{{time}} hours [<>]", "warning": "<> Takes a few seconds to apply after purchase! <>" + }, + "lotus": { + "name": "Loti of Rejuvenation", + "nameSingular": "Lotus of Rejuvenation", + "owned": "Owned: {{x}}", + "lifetimeUsed": "Used: {{x}}", + "intro": "When you activate a Lotus, immediately gain the full amount of Reborn ELO you can get from Immortal ELO, no waiting required! Effect applies for 5 minutes after purchasing. Use Loti at the Ant Altar.", + "boxText1": "Don't like waiting for Reborn ELO?", + "boxText2": "Use a Lotus to skip the wait!", + "boxText3": "Each Lotus lasts for 5 minutes.", + "useLotus": "Use Lotus!", + "purchaseBtn": "+{{amount}} Lotus [<>]", + "buyConfirm": "You are about to buy a {{name}} for {{cost}} PseudoCoins. Continue?", + "useConfirm": "You are about to use a Lotus of Rejuvenation. This will consume one of your Loti and activate its effect for 5 minutes, granting you Reborn ELO without having to wait. Continue?", + "useConfirmMulti": "Since you have this effect active, consuming a Lotus will add 5 minutes to the remaining time.", + "noLotus": "You do not currently possess a Lotus. Buy some at the PseudoCoins shop!", + "status": "Lotus Time: {{time}}", + "lotusActive": "You've used a Lotus! For the next 5 minutes, you will gain Reborn ELO from your Immortal ELO without having to wait!" } }, "hotkeys": { diff --git a/translations/es.json b/translations/es.json index 06ddd3c2f..a23d161ce 100644 --- a/translations/es.json +++ b/translations/es.json @@ -3773,15 +3773,6 @@ "off": "OFF", "buyOne": "Buy x1", "buyMax": "Buy MAX", - "updateAlerts": { - "june282021": "28 de junio de 2021: V2.5.3. Se te han reembolsado los quarks de las calculadoras si las compraste. ¡Ya no son reembolsables, así que cuidado!", - "july22021": "2 de julio de 2021: V2.5.5. Has sido reembolsado los quarks de la mejora de Polvo EX, si compraste. Tus hormigas de Rango 1 también se resetearon y el costo base establecido en 1e700 partículas. ¡Polvo EX ya no es reembolsable, así que cuidado!", - "sing230Balancing": "¡Debido a un reequilibrio, fuiste enviado de vuelta a la Singularidad 230 para evitar el bloqueo parcial de tu fichero de guardado!", - "december22xxxx": "Has cargado el parche v1 del 22 de Diciembre.", - "january42023": "Has cargado el Parche v1 del 4 de Enero 2023.", - "v297hotfix1NoSing": "¡Has cargado la revisión 1 de la versión 2.9.7!", - "v297hotfix1Sing": "¡Has cargado la revisión 1 de la versión 2.9.7! ¡Tus mejoras de singularidad sin límite se han devuelto! Disculpa los inconvenientes." - }, "languageChange": "¡Para cambiar de lenguaje se necesita recargar! ¿Quieres hacerlo ahora?", "resources": { "offering": "Offering", diff --git a/translations/fr.json b/translations/fr.json index ac0ccbd72..092d07bf1 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -3773,15 +3773,6 @@ "off": "NON", "buyOne": "Buy x1", "buyMax": "Buy MAX", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Le changement de langue requiert un rechargement ! Voulez-vous recharger maintenant ?", "resources": { "offering": "Offering", diff --git a/translations/ja.json b/translations/ja.json index 3fec2665f..268504cbe 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -3768,15 +3768,6 @@ "off": "OFF", "buyOne": "Buy x1", "buyMax": "Buy MAX", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Changing the language requires a reload! Would you like to reload now?", "resources": { "offering": "Offering", diff --git a/translations/kaa.json b/translations/kaa.json index 670b80752..d85bbfaa2 100644 --- a/translations/kaa.json +++ b/translations/kaa.json @@ -1970,15 +1970,6 @@ "buyMaxOff": "Buy Max: OFF", "on": "ON", "off": "OFF", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Changing the language requires a reload! Would you like to reload now?" }, "upgrades": { diff --git a/translations/nl.json b/translations/nl.json index 873759377..a41a75945 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -2190,15 +2190,6 @@ "buyMaxOff": "Buy Max: OFF", "on": "ON", "off": "OFF", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Changing the language requires a reload! Would you like to reload now?" }, "upgrades": { diff --git a/translations/pl.json b/translations/pl.json index 2a99b78b1..67484303d 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -3773,15 +3773,6 @@ "off": "OFF", "buyOne": "Buy x1", "buyMax": "Buy MAX", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Changing the language requires a reload! Would you like to reload now?", "resources": { "offering": "Offering", diff --git a/translations/pt.json b/translations/pt.json index 87e62ca44..13df86642 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -1970,15 +1970,6 @@ "buyMaxOff": "Buy Max: OFF", "on": "ON", "off": "OFF", - "updateAlerts": { - "june282021": "June 28, 2021: V2.5.3. You have been refunded quarks from calculators if you purchased them. They are no longer refundable so be wary!", - "july22021": "July 2, 2021: V2.5.5. You have been refunded quarks from Powder EX upgrade, if you purchased levels. Your T1 ants were also reset and base cost set to 1e700 particles. Powder EX is no longer refundable, though, so be careful!", - "sing230Balancing": "Due to balancing changes, you were sent back to Singularity 230 to prevent softlocking your savefile!", - "december22xxxx": "You have loaded into the December 22 patch v1.", - "january42023": "You have loaded into the January 4, 2023 Patch v1.", - "v297hotfix1NoSing": "You have loaded into the version 2.9.7 hotfix 1!", - "v297hotfix1Sing": "You have loaded into the version 2.9.7 hotfix 1! Your uncapped resource singularity upgrades have been refunded! Sorry for the inconvenience." - }, "languageChange": "Changing the language requires a reload! Would you like to reload now?" }, "upgrades": { diff --git a/translations/pt_BR.json b/translations/pt_BR.json index a3571ac0b..bafde3f77 100644 --- a/translations/pt_BR.json +++ b/translations/pt_BR.json @@ -1966,15 +1966,6 @@ "buyMaxOff": "", "on": "", "off": "", - "updateAlerts": { - "june282021": "", - "july22021": "", - "sing230Balancing": "", - "december22xxxx": "", - "january42023": "", - "v297hotfix1NoSing": "", - "v297hotfix1Sing": "" - }, "languageChange": "" }, "upgrades": { diff --git a/translations/ru.json b/translations/ru.json index acbad3aa2..a4d775e31 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -3773,15 +3773,6 @@ "off": "ВЫКЛ", "buyOne": "Купить x1", "buyMax": "Купить МАКС", - "updateAlerts": { - "june282021": "28 Июня, 2021: Вер. 2.5.3. Вам были возвращены кварки за калькуляторы, если они были куплены. Средства за них возврату более не подлежат, так что будьте осторожны!", - "july22021": "2 Июля, 2021: Вер. 2.5.5. Вам возвращены кварки за улучшение Порошок EX, если были куплены уровни. Ваши У1 муравьи также были сброшены и их базовая цена была установлена на 1e700 частиц. Впрочем, Порошок EX более не подлежит возврату, так что будьте осторожны!", - "sing230Balancing": "Из-за изменений баланса, вы были отправлены обратно в Сингулярность 230, дабы избежать софтлока вашего сохранения!", - "december22xxxx": "Успешная загрузка в патч v1 от 22 Декабря.", - "january42023": "Успешная загрузка в патч v1 от 4 Января, 2023 года.", - "v297hotfix1NoSing": "Успешная загрузка в версию 2.9.7, хотфикс 1!", - "v297hotfix1Sing": "Успешная загрузка в версию 2.9.7, хотфикс 1! Средства за неограниченные ресурсные улучшения сингулярности были возвращены! Приносим извинения за неудобства." - }, "languageChange": "Смена языка требует перезагрузки! Хотите перезагрузить сейчас?", "resources": { "offering": "Подношение", diff --git a/translations/zh.json b/translations/zh.json index f1553d107..a1a6a38e0 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -3773,15 +3773,6 @@ "off": "关", "buyOne": "购买1个", "buyMax": "购买最大", - "updateAlerts": { - "june282021": "2021年6月28日:V2.5.3。如果您之前购买过计算器,则将重置相应购买。它们之后将无法重置,请注意这一点!", - "july22021": "2021年7月2日:V2.5.5。如果您之前购买过EX超通量粉,则将重置该项购买。您的T1蚂蚁数量也进行了重置,基础花费变为1e700粒子。EX超通量粉之后将无法重置,请注意这一点!", - "sing230Balancing": "由于平衡性调整,您被送回了第230次奇点,以避免进度软锁死!", - "december22xxxx": "您载入了12月22日v1版补丁。", - "january42023": "您载入了2023年1月4日v1版补丁。", - "v297hotfix1NoSing": "您载入了2.9.7热修复1补丁!", - "v297hotfix1Sing": "您载入了2.9.7热修复1补丁!部分无上限的奇点升级进行了重置,对此表示抱歉。" - }, "languageChange": "切换语言需要刷新页面,您现在就想要刷新页面吗?", "resources": { "offering": "祭品",