diff --git a/TableturfBattleClient/src/Pages/GalleryPage.ts b/TableturfBattleClient/src/Pages/GalleryPage.ts index 8a52f9c..495c49b 100644 --- a/TableturfBattleClient/src/Pages/GalleryPage.ts +++ b/TableturfBattleClient/src/Pages/GalleryPage.ts @@ -106,18 +106,20 @@ function openGalleryCardView(card: Card) { galleryCardEditorSubmitButton.hidden = true; galleryCardEditorCancelButton.innerText = 'Close'; - galleryCardEditorRarityBox.value = card.rarity.toString(); - galleryCardEditorColour1.value = `#${card.inkColour1.r.toString(16).padStart(2, '0')}${card.inkColour1.g.toString(16).padStart(2, '0')}${card.inkColour1.b.toString(16).padStart(2, '0')}`; - galleryCardEditorColour2.value = `#${card.inkColour2.r.toString(16).padStart(2, '0')}${card.inkColour2.g.toString(16).padStart(2, '0')}${card.inkColour2.b.toString(16).padStart(2, '0')}`; - updateSelectedPreset([card.inkColour1, card.inkColour2]); + if (card.isCustom) { + galleryCardEditorRarityBox.value = card.rarity.toString(); + galleryCardEditorColour1.value = `#${card.inkColour1.r.toString(16).padStart(2, '0')}${card.inkColour1.g.toString(16).padStart(2, '0')}${card.inkColour1.b.toString(16).padStart(2, '0')}`; + galleryCardEditorColour2.value = `#${card.inkColour2.r.toString(16).padStart(2, '0')}${card.inkColour2.g.toString(16).padStart(2, '0')}${card.inkColour2.b.toString(16).padStart(2, '0')}`; + updateSelectedPreset([card.inkColour1, card.inkColour2]); - galleryCardEditorName.value = card.line2 == null ? card.name : `${card.line1}\n${card.line2}`; - for (let y = 0; y < 8; y++) { - for (let x = 0; x < 8; x++) { - galleryCardEditorGridButtons[y][x].dataset.state = card.grid[y][x].toString(); + galleryCardEditorName.value = card.line2 == null ? card.name : `${card.line1}\n${card.line2}`; + for (let y = 0; y < 8; y++) { + for (let x = 0; x < 8; x++) { + galleryCardEditorGridButtons[y][x].dataset.state = card.grid[y][x].toString(); + } } + updateCustomCardSize(); } - updateCustomCardSize(); galleryCardDialog.showModal(); } @@ -176,7 +178,7 @@ function updateBitsToComplete() { if (!cardDatabase.cards) throw new Error('Card database not loaded'); let bitsRequired = 0; for (const card of cardDatabase.cards) { - if (card.number in ownedCards) continue; + if (card.isUpcoming || card.number in ownedCards) continue; switch (card.rarity) { case Rarity.Fresh: bitsRequired += 40; break; case Rarity.Rare: bitsRequired += 15; break; diff --git a/TableturfBattleClient/src/Pages/PreGamePage.ts b/TableturfBattleClient/src/Pages/PreGamePage.ts index 89a420d..fbc5dff 100644 --- a/TableturfBattleClient/src/Pages/PreGamePage.ts +++ b/TableturfBattleClient/src/Pages/PreGamePage.ts @@ -63,7 +63,9 @@ function setLoadingMessage(message: string | null) { function preGameInitStageDatabase(stages: Stage[]) { for (let i = 0; i < stages.length; i++) { const stage = stages[i]; - const status = userConfig.lastCustomRoomConfig ? userConfig.lastCustomRoomConfig.stageSwitch[i] : 0; + const status = userConfig.lastCustomRoomConfig && userConfig.lastCustomRoomConfig.stageSwitch.length > i + ? userConfig.lastCustomRoomConfig.stageSwitch[i] + : (stages[i].name.startsWith('Upcoming') ? 2 : 0); const button = document.createElement('button'); diff --git a/TableturfBattleClient/src/StageButton.ts b/TableturfBattleClient/src/StageButton.ts index adb87db..da56ad9 100644 --- a/TableturfBattleClient/src/StageButton.ts +++ b/TableturfBattleClient/src/StageButton.ts @@ -23,17 +23,36 @@ class StageButton extends CheckButton { for (var x = 0; x < stage.grid.length; x++) { let col = [ ]; for (var y = 0; y < stage.grid[x].length; y++) { - if (stage.grid[x][y] == Space.Empty) { + if (stage.grid[x][y] == Space.OutOfBounds) + col.push(null); + else { const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); - rect.classList.add('empty'); + rect.classList.add(Space[stage.grid[x][y]].toString()); rect.setAttribute('x', (100 * x).toString()); rect.setAttribute('y', (100 * y + offset).toString()); rect.setAttribute('width', '100'); rect.setAttribute('height', '100'); gridSvg.appendChild(rect); col.push(rect); - } else - col.push(null); + + if (stage.grid[x][y] & Space.SpecialInactive1) { + const image = document.createElementNS('http://www.w3.org/2000/svg', 'image'); + image.setAttribute('href', 'assets/SpecialOverlay.png'); + image.setAttribute('x', rect.getAttribute('x')!); + image.setAttribute('y', rect.getAttribute('y')!); + image.setAttribute('width', rect.getAttribute('width')!); + image.setAttribute('height', rect.getAttribute('height')!); + gridSvg.appendChild(image); + } else if (stage.grid[x][y] & Space.Ink1) { + const image = document.createElementNS('http://www.w3.org/2000/svg', 'image'); + image.setAttribute('href', 'assets/InkOverlay.png'); + image.setAttribute('x', rect.getAttribute('x')!); + image.setAttribute('y', rect.getAttribute('y')!); + image.setAttribute('width', rect.getAttribute('width')!); + image.setAttribute('height', rect.getAttribute('height')!); + gridSvg.appendChild(image); + } + } } cols.push(col); } @@ -50,7 +69,7 @@ class StageButton extends CheckButton { setStartSpaces(numPlayers: number) { for (const el of this.startCells) { - el[0].setAttribute('class', 'empty'); + el[0].setAttribute('class', 'Empty'); el[1].parentElement!.removeChild(el[1]); } this.startCells.splice(0); @@ -59,7 +78,7 @@ class StageButton extends CheckButton { for (let i = 0; i < numPlayers; i++) { const space = startSpaces[i]; const cell = this.cells[space.x][space.y]!; - cell.classList.add(`start${i + 1}`); + cell.setAttribute('class', `SpecialInactive${i + 1}`); const image = document.createElementNS('http://www.w3.org/2000/svg', 'image'); image.setAttribute('href', 'assets/SpecialOverlay.png'); diff --git a/TableturfBattleClient/tableturf.css b/TableturfBattleClient/tableturf.css index a958a4f..f45003b 100644 --- a/TableturfBattleClient/tableturf.css +++ b/TableturfBattleClient/tableturf.css @@ -389,10 +389,14 @@ dialog::backdrop { box-sizing: border-box; } -.stageGrid rect.start1 { fill: var(--special-colour-1); } -.stageGrid rect.start2 { fill: var(--special-colour-2); } -.stageGrid rect.start3 { fill: var(--special-colour-3); } -.stageGrid rect.start4 { fill: var(--special-colour-4); } +.stageGrid rect.Ink1 { fill: var(--primary-colour-1); } +.stageGrid rect.Ink2 { fill: var(--primary-colour-2); } +.stageGrid rect.Ink3 { fill: var(--primary-colour-3); } +.stageGrid rect.Ink4 { fill: var(--primary-colour-4); } +.stageGrid rect.SpecialInactive1 { fill: var(--special-colour-1); } +.stageGrid rect.SpecialInactive2 { fill: var(--special-colour-2); } +.stageGrid rect.SpecialInactive3 { fill: var(--special-colour-3); } +.stageGrid rect.SpecialInactive4 { fill: var(--special-colour-4); } :is(.stage, .stageRandom):is(:hover, :focus-within):not(.checked, .disabled)::before { content: ''; @@ -632,15 +636,16 @@ svg.card text.cardDisplayName { transform: scaleX(var(--scale)); } -rect.empty { +rect.Empty, rect.empty { fill: #00000080; stroke: #60606080; stroke-width: 6; } -.stageGrid rect.empty { +.stageGrid rect.Empty { stroke: grey; stroke-width: 12; } +rect.Wall { fill: grey; } rect.ink { fill: var(--player-primary-colour); @@ -1956,7 +1961,7 @@ button.dragging { #galleryCardEditorImageFile { display: none; } #galleryCardEditorImageToolbar2 input { - width: 3em; + width: 3em; } #galleryCardEditorColourPresetBox { diff --git a/TableturfBattleServer/CardDatabase.cs b/TableturfBattleServer/CardDatabase.cs index f1510e7..a43ae06 100644 --- a/TableturfBattleServer/CardDatabase.cs +++ b/TableturfBattleServer/CardDatabase.cs @@ -2326,14 +2326,215 @@ public static class CardDatabase { { 0, I, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } }), + + new(-24, "Order Dualies", Rarity.Fresh, 2, "UpcomingOrderDualies", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, S, 0, 0, 0, 0 }, + { 0, 0, I, 0, I, 0, 0, 0 }, + { 0, 0, I, I, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-25, "Marina", Rarity.Fresh, "UpcomingMarina", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, I, 0, I, 0, 0 }, + { 0, I, I, I, I, 0, 0, 0 }, + { 0, I, 0, 0, I, I, 0, 0 }, + { 0, I, I, I, I, 0, 0, 0 }, + { 0, 0, I, I, 0, I, 0, 0 }, + { 0, S, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(242, 159, 104), InkColour2 = new(27, 27, 186) }, + new(-26, "Pearl", Rarity.Fresh, "UpcomingPearl", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, I, 0, I, 0, 0, I, 0 }, + { 0, 0, I, I, I, I, 0, 0 }, + { 0, I, I, 0, 0, I, I, 0 }, + { 0, 0, I, I, I, I, 0, 0 }, + { 0, 0, 0, I, 0, 0, S, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(232, 232, 232), InkColour2 = new(248, 177, 213) }, + new(-27, "Pearl Drone", Rarity.Fresh, 2, "UpcomingPearlDrone", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, I, 0, 0 }, + { 0, 0, 0, S, I, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(248, 177, 213), InkColour2 = new(232, 232, 232) }, + new(-28, "Acht", Rarity.Rare, "UpcomingAcht", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, I, 0, I, 0, 0 }, + { 0, I, 0, I, I, 0, 0, 0 }, + { 0, I, I, 0, I, S, 0, 0 }, + { 0, I, 0, I, I, 0, 0, 0 }, + { 0, 0, I, I, 0, I, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(237, 61, 65), InkColour2 = new(80, 80, 239) }, + new(-29, "Cipher", Rarity.Rare, "UpcomingCipher", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, I, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, I, I, I, I, 0, 0 }, + { 0, 0, I, 0, S, I, I, 0 }, + { 0, I, 0, 0, I, I, 0, 0 }, + { 0, 0, 0, 0, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(221, 183, 172), InkColour2 = new(182, 187, 219) }, + new(-30, "Flow", Rarity.Rare, "UpcomingFlow", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, I, 0, I, 0, I, 0, 0 }, + { 0, 0, S, I, I, 0, 0, 0 }, + { 0, 0, I, I, I, 0, 0, 0 }, + { 0, I, 0, I, 0, I, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(r: 159, 104, 242), InkColour2 = new(240, 111, 96) }, + new(-31, "Jelfonzo", Rarity.Rare, "UpcomingJelfonzo", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, I, 0, 0, 0 }, + { 0, 0, I, I, 0, I, 0, 0 }, + { 0, I, I, I, I, 0, 0, 0 }, + { 0, 0, I, S, 0, I, 0, 0 }, + { 0, 0, 0, 0, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(149, 119, 220), InkColour2 = new(106, 178, 215) }, + new(-32, "Bisk", Rarity.Rare, "UpcomingBisk", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, I, I, I, I, 0, 0, 0 }, + { 0, 0, I, S, 0, I, 0, 0 }, + { 0, 0, I, 0, I, 0, I, 0 }, + { 0, 0, 0, I, 0, I, 0, 0 }, + { 0, 0, 0, 0, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }) { InkColour1 = new(228, 94, 69), InkColour2 = new(240, 225, 96) }, + new(-33, "Douser\nDualies FF", Rarity.Common, "UpcomingDouserDualiesFF", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, S, 0, 0, 0 }, + { 0, 0, I, I, I, 0, 0, 0 }, + { 0, 0, I, 0, I, 0, 0, 0 }, + { 0, 0, I, I, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-34, "Recycled Brella\n24 Mk I", Rarity.Common, "UpcomingRecycledBrellaMkI", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, I, 0, 0 }, + { 0, 0, I, 0, I, 0, 0, 0 }, + { 0, 0, S, I, 0, 0, 0, 0 }, + { 0, 0, I, I, I, I, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-35, ".52 Gal Deco", Rarity.Common, "Upcoming52GalDeco", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, S, 0, 0, 0, 0, 0 }, + { 0, 0, I, I, 0, 0, 0, 0 }, + { 0, 0, I, I, 0, 0, 0, 0 }, + { 0, 0, I, 0, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-36, "Foil\nFlingza Roller", Rarity.Common, "UpcomingFoilFlingzaRoller", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, I, I, I, 0, 0, 0 }, + { 0, 0, S, I, I, I, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, I, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-37, "New Squiffer", Rarity.Common, "UpcomingNewSquiffer", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, S, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-38, "Custom E-Liter 4K", Rarity.Common, "UpcomingCustomELiter4K", new Space[,] { + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, S, 0, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-39, "Custom E-Liter\n4K Scope", Rarity.Common, "UpcomingCustomELiter4KScope", new Space[,] { + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, S, I, 0, 0, 0, 0 }, + { 0, 0, I, I, 0, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-40, "Custom Explosher", Rarity.Common, "UpcomingCustomExplosher", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, S, 0, 0, 0 }, + { 0, 0, I, I, I, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, 0, I, I, 0, 0, 0 }, + { 0, 0, I, I, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-41, "Dread Wringer D", Rarity.Common, "UpcomingDreadWringerD", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, S, I, 0, 0 }, + { 0, 0, I, I, I, I, 0, 0 }, + { 0, 0, I, I, I, I, 0, 0 }, + { 0, 0, 0, I, 0, I, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-42, "Nautilus 79", Rarity.Common, "UpcomingNautilus79", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, S, 0, 0, 0 }, + { 0, 0, 0, 0, I, 0, 0, 0 }, + { 0, 0, 0, 0, I, 0, 0, 0 }, + { 0, 0, I, I, I, 0, 0, 0 }, + { 0, 0, I, I, I, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), + new(-43, "Glooga Dualies\nDeco", Rarity.Common, "UpcomingGloogaDualiesDeco", new Space[,] { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, S, 0, 0, 0, 0 }, + { 0, 0, I, I, I, I, 0, 0 }, + { 0, 0, 0, I, I, I, 0, 0 }, + { 0, 0, 0, I, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }), ]; private static readonly Dictionary byAltNumber; public static int LastOfficialCardNumber { get; } - public static Version Version { get; } = new(6, 1, 0, 0); - public static DateTime LastModified { get; } = new(2024, 2, 9, 6, 0, 0, DateTimeKind.Utc); + public static Version Version { get; } = new(7, 0, 0, 0); + public static DateTime LastModified { get; } = new(2024, 2, 21, 1, 0, 0, DateTimeKind.Utc); public static string JSON { get; } public static ReadOnlyCollection Cards { get; } diff --git a/TableturfBattleServer/StageDatabase.cs b/TableturfBattleServer/StageDatabase.cs index 1fd74aa..64b7053 100644 --- a/TableturfBattleServer/StageDatabase.cs +++ b/TableturfBattleServer/StageDatabase.cs @@ -3,7 +3,12 @@ namespace TableturfBattleServer; internal class StageDatabase { private const Space E = Space.Empty; + private const Space W = Space.Wall; private const Space o = Space.OutOfBounds; + private const Space a = Space.Ink1; + private const Space b = Space.Ink2; + private const Space A = Space.SpecialInactive1; + private const Space B = Space.SpecialInactive2; private static readonly Stage[] stages = [ new("Main Street", new Space[9, 26], [ @@ -116,10 +121,137 @@ internal class StageDatabase { [new(3, 21), new(13, 3), new(8, 16), new(8, 8)] ]), new("Box Seats", new Space[10, 10], [[new(2, 7), new(7, 2), new(7, 7), new(2, 2)]]), + new("Upcoming: Bases", new Space[,] { + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + { E, E, E, E, E, E, o, o, o, o, o, o, E, E, E, E, E, E }, + }, [ + [new(8, 17), new(8, 0), new(8, 9)], + [new(2, 17), new(14, 0), new(14, 17), new(2, 0)] + ]), + new("Upcoming: Walls", new Space[,] { + { o, o, o, E, E, E, E, E, E, E, E, E, E, E, o, o, o }, + { o, o, o, E, E, E, E, E, E, E, E, E, E, E, o, o, o }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, W, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, W, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, W, E, E, E, E, E, E, E, E }, + { E, E, E, E, W, E, E, E, E, E, E, E, W, E, E, E, E }, + { E, E, E, E, W, E, E, E, E, E, E, E, W, E, E, E, E }, + { E, E, E, E, W, E, E, E, E, E, E, E, W, E, E, E, E }, + { E, E, E, E, W, E, E, E, E, E, E, E, W, E, E, E, E }, + { E, E, E, E, W, E, E, E, E, E, E, E, W, E, E, E, E }, + { E, E, E, E, E, E, E, E, W, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, W, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, W, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { o, o, o, E, E, E, E, E, E, E, E, E, E, E, o, o, o }, + { o, o, o, E, E, E, E, E, E, E, E, E, E, E, o, o, o }, + }, [ + [new(8, 15), new(8, 1), new(8, 8)], + [new(3, 15), new(13, 1), new(13, 15), new(3, 1)] + ]), + new("Upcoming: Pillars", new Space[,] { + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, B, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, A, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, B, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, A, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, W, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + }, [ + [new(3, 20), new(3, 4)] + ]), + new("Upcoming: River", new Space[,] { + { o, o, o, o, o, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { o, o, o, o, o, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, o, o, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, o, o, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, o, o, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, o, o, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, o, o, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, o, o, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, o, o, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, o, o, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, o, o, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, o, o, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, o, o, o, o, o }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, o, o, o, o, o }, + }, [ + [new(2, 17), new(11, 2), new(7, 11)], + [new(9, 17), new(4, 2), new(11, 10), new(2, 9)] + ]), + new("Upcoming: Dual Streets", new Space[,] { + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, B, E, E, E, E, E, E, E, E, E, E, E, A, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o }, + { o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, B, E, E, E, E, E, E, E, E, E, E, E, A, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + }, [ + [new(3, 14), new(3, 2)] + ]), + new("Upcoming: Super", new Space[,] { + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, B, B, B, E, E, E, E, E, E, E, E, E, E, E, E, A, A, A, E, E, E }, + { E, E, E, B, B, B, E, E, E, E, E, E, E, E, E, E, E, E, A, A, A, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E }, + }, [ + [new(4, 19), new(4, 3)] + ]), + new("Upcoming: Back-to-Back", new Space[,] { + { E, E, E, E, E, E, E, E, E, E, b, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, A, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, A, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, B, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, B, a, E, E, E, E, E, E, E, E, E, E }, + { E, E, E, E, E, E, E, E, E, E, b, a, E, E, E, E, E, E, E, E, E, E }, + }, [ + [new(1, 11), new(8, 10)] + ]), ]; - public static Version Version { get; } = new(1, 2, 0, 1); - public static DateTime LastModified { get; } = new(2023, 4, 12, 23, 0, 0, DateTimeKind.Utc); + public static Version Version { get; } = new(2, 0, 0, 0); + public static DateTime LastModified { get; } = new(2024, 2, 21, 1, 0, 0, DateTimeKind.Utc); public static string JSON { get; } public static ReadOnlyCollection Stages { get; }