From 24e14e9b3c5878e8197b8770c5d5da0de84b6eb8 Mon Sep 17 00:00:00 2001
From: Kevin Bunn <45328239+Pseudonian@users.noreply.github.com>
Date: Thu, 6 Feb 2025 16:25:06 -0500
Subject: [PATCH] Campaigns sans UI
---
Synergism.css | 54 +++++++++++++++++++++
index.html | 16 +++++++
src/Campaign.ts | 90 ++++++++++++++++++++++++-----------
src/Corruptions.ts | 9 ++--
src/Synergism.ts | 4 ++
src/Tabs.ts | 21 +++++---
src/UpdateHTML.ts | 8 ++++
src/UpdateVisuals.ts | 13 +++++
src/saves/PlayerJsonSchema.ts | 4 ++
src/saves/PlayerSchema.ts | 5 ++
src/types/Synergism.d.ts | 3 ++
translations/en.json | 5 ++
translations/source.json | 4 ++
13 files changed, 198 insertions(+), 38 deletions(-)
diff --git a/Synergism.css b/Synergism.css
index 26005b3fe..62e12194b 100644
--- a/Synergism.css
+++ b/Synergism.css
@@ -690,6 +690,11 @@ button.isEvent:hover {
color: red;
}
+#campaigntab {
+ border-color: red;
+ color: orange;
+}
+
#traitstab {
border-color: orange;
color: red;
@@ -2880,6 +2885,55 @@ p#ascendHotKeys {
color: white;
}
+#campaigns {
+ justify-content: center;
+ align-items: start;
+ margin-top: 10px;
+}
+
+#campaignsMain {
+ width: 100%;
+ margin-top: 5%;
+ height: 50%;
+ justify-items: center;
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ grid-template-rows: repeat(3, 1fr);
+ grid-column-gap: 0px;
+ grid-row-gap: 0px;
+}
+
+#campaignsIcons {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ justify-items: center;
+ grid-area: 1 / 1 / 3 / 2;
+}
+
+#campaignIconGrid {
+ display: grid;
+ grid-template-columns: repeat(10, 1fr);
+ grid-template-rows: repeat(5, 1fr);
+ grid-column-gap: 5px;
+ grid-row-gap: 5px;
+}
+
+#campaignsIcons p {
+ text-align: center;
+}
+
+#campaignsIcons img {
+ width: 48px;
+ height: 48px;
+ font-size: 0;
+ cursor: pointer;
+}
+
+#campaignsDescriptions { grid-area: 1 / 2 / 3 / 4; }
+
+#campaignsTokensInfo { grid-area: 3 / 1 / 4 / 4; }
+
#traits {
justify-content: center;
align-items: start;
diff --git a/index.html b/index.html
index 9f9eafc65..6ddf95ae8 100644
--- a/index.html
+++ b/index.html
@@ -2807,6 +2807,22 @@
+
diff --git a/src/Campaign.ts b/src/Campaign.ts
index f4719bb86..9b4856383 100644
--- a/src/Campaign.ts
+++ b/src/Campaign.ts
@@ -1,6 +1,8 @@
import i18next from 'i18next'
import { CorruptionLoadout, type Corruptions } from './Corruptions'
import { player } from './Synergism'
+import { DOMCacheGetOrSet } from './Cache/DOM'
+import { IconSets } from './Themes'
export type AscensionModifiers = 'GlobalSpeed'
@@ -10,38 +12,44 @@ export type CampaignModifiers = Partial>
export type CampaignKeys = 'test1' | 'test2' | 'test3'
export interface ICampaignManagerData {
- currentCampaign: CampaignKeys | undefined
- campaigns: Record
+ currentCampaign?: CampaignKeys | undefined
+ campaigns?: Record
}
export interface ICampaignData {
- campaignLoadout: CampaignLoadout
+ campaignCorruptions: Partial
campaignModifiers: CampaignModifiers
limit: number
isMeta: boolean
- c10Completions?: number
}
export class CampaignManager {
- totalCampaignTokens: number
- currentCampaign: Campaign | undefined
- campaigns!: Record
-
- constructor (campaignManagerData: ICampaignManagerData) {
- for (const campaignKey of Object.keys(campaignManagerData.campaigns)) {
- const key = campaignKey as keyof typeof campaignManagerData.campaigns
- this.campaigns[key] = new Campaign(campaignDatas[key], key)
+ private totalCampaignTokens: number
+ private currentCampaign: Campaign | undefined
+ private campaigns!: Record
+
+ constructor (campaignManagerData?: ICampaignManagerData) {
+ this.campaigns = {} as Record
+ if (campaignManagerData !== undefined) {
+ for (const campaignKey of Object.keys(campaignDatas)) {
+ const key = campaignKey as keyof typeof campaignDatas
+ this.campaigns[key] = new Campaign(campaignDatas[key], key, campaignManagerData.campaigns?.[key])
+ }
+ const currentKey = campaignManagerData.currentCampaign
+ if (currentKey !== undefined) {
+ this.currentCampaign = this.campaigns[currentKey]
+ player.corruptions.used = new CorruptionLoadout(this.currentCampaign.campaignCorruptions)
+ } else {
+ this.currentCampaign = undefined
+ }
}
-
- const currentKey = campaignManagerData.currentCampaign
-
- if (currentKey !== undefined) {
- this.currentCampaign = this.campaigns[currentKey]
- player.corruptions.used = this.currentCampaign.createUsableLoadout()
- } else {
+ else {
+ for (const campaignKey of Object.keys(campaignDatas)) {
+ const key = campaignKey as keyof typeof campaignDatas
+ this.campaigns[key] = new Campaign(campaignDatas[key], key, 0)
+ }
this.currentCampaign = undefined
}
-
this.totalCampaignTokens = this.computeTotalCampaignTokens()
}
@@ -53,13 +61,28 @@ export class CampaignManager {
}
return sum
}
+
+ get tokens () {
+ return this.totalCampaignTokens
+ }
+
+ get current () {
+ return this.currentCampaign
+ }
+
+ // Store as this in player
+ get c10Completions (): Record {
+ return Object.fromEntries(
+ Object.entries(this.campaigns).map(([key, value]) => [key, value.c10Completions])
+ ) as Record
+ }
}
export class Campaign {
// Stored as variable out of scope
name: string
description: string
- campaignLoadout: CampaignLoadout
+ campaignCorruptions: CampaignLoadout
campaignModifiers: CampaignModifiers
limit: number
isMeta: boolean
@@ -67,14 +90,14 @@ export class Campaign {
// Saved as a variable
_c10Completions = 0
- constructor (campaignData: ICampaignData, key: string) {
+ constructor (campaignData: ICampaignData, key: string, c10?: number) {
this.name = i18next.t(`campaigns.data.${key}.name`)
this.description = i18next.t(`campaigns.data.${key}.description`)
- this.campaignLoadout = campaignData.campaignLoadout
+ this.campaignCorruptions = campaignData.campaignCorruptions
this.campaignModifiers = campaignData.campaignModifiers
this.limit = campaignData.limit
this.isMeta = campaignData.isMeta
- this._c10Completions = campaignData.c10Completions ?? 0
+ this._c10Completions = c10 ?? 0
}
public computeTokenValue = () => {
@@ -83,7 +106,7 @@ export class Campaign {
}
public createUsableLoadout = (): CorruptionLoadout => {
- return new CorruptionLoadout(this.campaignLoadout)
+ return new CorruptionLoadout(this.campaignCorruptions)
}
public set c10Completions (value: number) {
@@ -96,7 +119,7 @@ export class Campaign {
export const campaignDatas: Record = {
test1: {
- campaignLoadout: {
+ campaignCorruptions: {
viscosity: 1
},
campaignModifiers: {
@@ -106,7 +129,7 @@ export const campaignDatas: Record = {
limit: 10
},
test2: {
- campaignLoadout: {
+ campaignCorruptions: {
viscosity: 1,
deflation: 1
},
@@ -117,7 +140,7 @@ export const campaignDatas: Record = {
limit: 15
},
test3: {
- campaignLoadout: {
+ campaignCorruptions: {
viscosity: 1,
deflation: 1,
dilation: 1
@@ -129,3 +152,14 @@ export const campaignDatas: Record = {
limit: 20
}
}
+
+export const campaignTest = () => {
+ const campaignIconDiv = DOMCacheGetOrSet('campaignIconGrid')
+
+ for (let i = 0; i < 50; i++) {
+ const campaignIcon = document.createElement('img')
+ campaignIcon.classList.add('campaignIcon')
+ campaignIcon.src = `Pictures/${IconSets[player.iconSet][0]}/Quark.png`
+ campaignIconDiv.appendChild(campaignIcon)
+ }
+}
\ No newline at end of file
diff --git a/src/Corruptions.ts b/src/Corruptions.ts
index 704e0e27d..e927a4d1a 100644
--- a/src/Corruptions.ts
+++ b/src/Corruptions.ts
@@ -6,6 +6,7 @@ import { toggleCorruptionLevel } from './Toggles'
import { Alert, Prompt } from './UpdateHTML'
import { getElementById, productContents, sumContents, validateNonnegativeInteger } from './Utility'
import { Globals as G } from './Variables'
+import { PCoinUpgradeEffects } from './PseudoCoinUpgrades'
export const convertInputToCorruption = (array: number[]): Corruptions => {
return {
@@ -59,7 +60,6 @@ export class CorruptionLoadout {
constructor (p: Partial) {
Object.assign(this.#levels, p)
- console.log('test', this.#levels)
}
public setCorruptionLevels (corruptions: Partial) {
@@ -569,15 +569,18 @@ export const corruptionLoadoutTableCreate = () => {
zeroCell.title = i18next.t('corruptions.loadoutTable.zeroTitle')
// Do the rest of the thing
- for (let i = 0; i < corrSaves.length; i++) {
+ const allowedRows = 8 + PCoinUpgradeEffects.CORRUPTION_LOADOUT_SLOT_QOL
+ for (let i = 0; i < Math.min(corrSaves.length, allowedRows); i++) {
const corrSave = corrSaves[i]
const corrLoadout = corrSave?.loadout.loadout
+ const corrName = corrSave?.name
+
const row = table.insertRow()
// Title Cell
const titleCell = row.insertCell()
titleCell.className = `test${'Title'}`
titleCell.title = i18next.t('corruptions.loadoutTable.otherRowTitle', { value: i + 1 })
- console.log(corrLoadout)
+ titleCell.textContent = corrName
for (const corr in corrLoadout) {
const corrKey = corr as keyof Corruptions
const cell = row.insertCell()
diff --git a/src/Synergism.ts b/src/Synergism.ts
index e52219152..b7b5c24d3 100644
--- a/src/Synergism.ts
+++ b/src/Synergism.ts
@@ -180,6 +180,7 @@ import { changeSubTab, changeTab, Tabs } from './Tabs'
import { settingAnnotation, toggleIconSet, toggleTheme } from './Themes'
import { clearTimeout, clearTimers, setInterval, setTimeout } from './Timers'
import { playerUpdateVarSchema } from './saves/PlayerUpdateVarSchema'
+import { CampaignManager, campaignTest } from './Campaign'
export const player: Player = {
firstPlayed: new Date().toISOString(),
@@ -902,6 +903,8 @@ export const player: Player = {
}),
showStats: true
},
+
+ campaigns: new CampaignManager(),
/*prototypeCorruptions: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
usedCorruptions: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
corruptionLoadouts: {
@@ -6392,6 +6395,7 @@ window.addEventListener('load', async () => {
reloadShit()
corruptionLoadoutTableCreate()
+ campaignTest()
}, { once: true })
window.addEventListener('unload', () => {
diff --git a/src/Tabs.ts b/src/Tabs.ts
index 09b8ae303..c14438951 100644
--- a/src/Tabs.ts
+++ b/src/Tabs.ts
@@ -27,12 +27,13 @@ export enum Tabs {
Research = 5,
AntHill = 6,
WowCubes = 7,
- Corruption = 8,
- Singularity = 9,
- Settings = 10,
- Shop = 11,
- Event = 12,
- Purchase = 13
+ Campaign = 8,
+ Corruption = 9,
+ Singularity = 10,
+ Settings = 11,
+ Shop = 12,
+ Event = 13,
+ Purchase = 14
}
/**
@@ -222,6 +223,7 @@ const subtabInfo: Record = {
}
]
},
+ [Tabs.Campaign]: { subTabList: [] },
[Tabs.Corruption]: {
tabSwitcher: () => toggleCorruptionLoadoutsStats,
subTabList: [
@@ -578,8 +580,13 @@ tabRow.appendButton(
.setType(Tabs.WowCubes)
.makeDraggable()
.makeRemoveable(),
- new $Tab({ class: 'chal11', id: 'traitstab', i18n: 'tabs.main.corruption' })
+ new $Tab({ class: 'chal11', id: 'campaigntab', i18n: 'tabs.main.campaign' })
.setUnlockedState(() => player.challengecompletions[11] > 0)
+ .setType(Tabs.Campaign)
+ .makeDraggable()
+ .makeRemoveable(),
+ new $Tab({ class: 'chal14', id: 'traitstab', i18n: 'tabs.main.corruption' })
+ .setUnlockedState(() => player.challengecompletions[14] > 0)
.setType(Tabs.Corruption)
.makeDraggable()
.makeRemoveable(),
diff --git a/src/UpdateHTML.ts b/src/UpdateHTML.ts
index ff2a87d44..5378287b9 100644
--- a/src/UpdateHTML.ts
+++ b/src/UpdateHTML.ts
@@ -22,6 +22,7 @@ import {
visualUpdateAchievements,
visualUpdateAnts,
visualUpdateBuildings,
+ visualUpdateCampaign,
visualUpdateChallenges,
visualUpdateCorruptions,
visualUpdateCubes,
@@ -609,6 +610,8 @@ export const hideStuff = () => {
DOMCacheGetOrSet('ants').style.display = 'none'
DOMCacheGetOrSet('anttab').style.backgroundColor = ''
DOMCacheGetOrSet('cubetab').style.backgroundColor = ''
+ DOMCacheGetOrSet('campaigntab').style.backgroundColor = ''
+ DOMCacheGetOrSet('campaigns').style.display = 'none'
DOMCacheGetOrSet('traitstab').style.backgroundColor = ''
DOMCacheGetOrSet('cubes').style.display = 'none'
DOMCacheGetOrSet('traits').style.display = 'none'
@@ -682,6 +685,10 @@ export const hideStuff = () => {
DOMCacheGetOrSet('cubes').style.display = 'flex'
DOMCacheGetOrSet('cubetab').style.backgroundColor = 'white'
}
+ if (G.currentTab === Tabs.Campaign) {
+ DOMCacheGetOrSet('campaigns').style.display = 'block'
+ DOMCacheGetOrSet('campaigntab').style.backgroundColor = 'red'
+ }
if (G.currentTab === Tabs.Corruption) {
DOMCacheGetOrSet('traits').style.display = 'flex'
DOMCacheGetOrSet('traitstab').style.backgroundColor = 'white'
@@ -718,6 +725,7 @@ const visualTab: Record void> = {
[Tabs.Shop]: visualUpdateShop,
[Tabs.AntHill]: visualUpdateAnts,
[Tabs.WowCubes]: visualUpdateCubes,
+ [Tabs.Campaign]: visualUpdateCampaign,
[Tabs.Corruption]: visualUpdateCorruptions,
[Tabs.Singularity]: visualUpdateSingularity,
[Tabs.Event]: visualUpdateEvent,
diff --git a/src/UpdateVisuals.ts b/src/UpdateVisuals.ts
index e1dc4c4d8..68ee64d58 100644
--- a/src/UpdateVisuals.ts
+++ b/src/UpdateVisuals.ts
@@ -1865,3 +1865,16 @@ export const visualUpdateEvent = () => {
}
export const visualUpdatePurchase = () => {}
+
+// Experimental: Some things in the Campaign need only loaded once.
+// What if I just made it so that it loads exactly once and then
+// Never again? - 2025 Platonic
+let cachedVisualCampaignUpdates = false
+
+export const visualUpdateCampaign = () => {
+ if (!cachedVisualCampaignUpdates) {
+ DOMCacheGetOrSet('campaignsIntroduction').innerHTML = i18next.t('campaigns.intro')
+ DOMCacheGetOrSet('campaignsInfo1').innerHTML = i18next.t('campaigns.campaignInfo')
+ cachedVisualCampaignUpdates = true
+ }
+}
\ No newline at end of file
diff --git a/src/saves/PlayerJsonSchema.ts b/src/saves/PlayerJsonSchema.ts
index 2d7811c09..a38117465 100644
--- a/src/saves/PlayerJsonSchema.ts
+++ b/src/saves/PlayerJsonSchema.ts
@@ -24,6 +24,10 @@ export const playerJsonSchema = playerSchema.extend({
wowHypercubes: z.any().transform((hypercubes: Player['wowHypercubes']) => Number(hypercubes)),
wowPlatonicCubes: z.any().transform((cubes: Player['wowPlatonicCubes']) => Number(cubes)),
+ campaigns: z.any().transform((campaignManager: Player['campaigns']) => {
+ return campaignManager.c10Completions
+ }),
+
corruptions: z.any().transform((stuff: Player['corruptions']) => {
return {
used: stuff.used.loadout,
diff --git a/src/saves/PlayerSchema.ts b/src/saves/PlayerSchema.ts
index c83c2816b..0ea193b36 100644
--- a/src/saves/PlayerSchema.ts
+++ b/src/saves/PlayerSchema.ts
@@ -11,6 +11,7 @@ import { blankSave } from '../Synergism'
import type { Player } from '../types/Synergism'
import { deepClone, padArray } from '../Utility'
import { CorruptionLoadout, CorruptionSaves } from '../Corruptions'
+import { CampaignManager } from '../Campaign'
const decimalSchema = z.custom((value) => {
try {
@@ -531,6 +532,10 @@ export const playerSchema = z.object({
roombaResearchIndex: z.number().default(() => blankSave.roombaResearchIndex),
ascStatToggles: z.record(integerStringSchema, z.boolean()).default(() => ({ ...blankSave.ascStatToggles })),
+ campaigns: z.record(z.string(), z.number()).transform((campaigns => {
+ return new CampaignManager(campaigns)
+ })).default(() => JSON.parse(JSON.stringify(blankSave.campaigns))),
+
corruptions: z.object({
used: optionalCorruptionSchema.transform((value) => {
return new CorruptionLoadout(value)
diff --git a/src/types/Synergism.d.ts b/src/types/Synergism.d.ts
index aaab4f132..5bca3fa9f 100644
--- a/src/types/Synergism.d.ts
+++ b/src/types/Synergism.d.ts
@@ -16,6 +16,7 @@ import type {
} from '../StatCache'
import type { Tabs } from '../Tabs'
import type { Corruptions, CorruptionLoadout } from '../Corruptions'
+import { CampaignManager } from '../Campaign'
type ArrayStartingWithNull = [null, ...T[]]
@@ -537,6 +538,8 @@ export interface Player {
roombaResearchIndex: number
ascStatToggles: Record
+ campaigns: CampaignManager
+
corruptions: {
next: CorruptionLoadout
used: CorruptionLoadout
diff --git a/translations/en.json b/translations/en.json
index c78fcdd0b..f3c3f7931 100644
--- a/translations/en.json
+++ b/translations/en.json
@@ -2487,6 +2487,7 @@
"research": "Research",
"antHill": "Anthill",
"wowCubes": "WOW! Cubes",
+ "campaign": "Campaigns",
"corruption": "Corruption",
"singularity": "Singularity",
"settings": "Settings",
@@ -2558,6 +2559,10 @@
"currentAscensionTimer": "Current Ascension Timer: +<> seconds",
"exportQuarks": "Export Quarks: +<>"
},
+ "campaigns": {
+ "intro": "Campaigns - <> but <>",
+ "campaignInfo": "Play through <> with various modifiers to make it spicier, but also more cubical! \n Each Campaign is a <> form of <>. \n <> "
+ },
"corruptions": {
"names": {
"viscosity": "Viscous Multiplier and Accelerators",
diff --git a/translations/source.json b/translations/source.json
index 8c562b9e5..043063e07 100644
--- a/translations/source.json
+++ b/translations/source.json
@@ -2556,6 +2556,10 @@
"currentAscensionTimer": "Current Ascension Timer: +<> seconds",
"exportQuarks": "Export Quarks: +<>"
},
+ "campaigns": {
+ "intro": "Campaigns - Ascensions but harderâ„¢",
+ "campaignInfo": "Play through Ascensions with various modifiers to make it spicier, but also more cubical! \n Each Campaign is a Corrupted form of Ascension. \n Click on an icon to see what I mean! "
+ },
"corruptions": {
"names": {
"1": "Corruption I: Viscosity",