diff --git a/Chrono/Build/download_full_art.py b/Chrono/Build/download_full_art.py new file mode 100644 index 0000000..42cdd5d --- /dev/null +++ b/Chrono/Build/download_full_art.py @@ -0,0 +1,138 @@ +import os +import re +import requests +import time +from concurrent.futures import ThreadPoolExecutor + +# Configuration +DOCS_DIR = r"..\chrono.docs" +CLOUD_CARDS_DIR = r"Cloud\wwwroot\cards" +STANDALONE_CARDS_DIR = r"Standalone\wwwroot\cards" +USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" + +def get_card_names(): + card_names = [] + # Search for all .md files in chrono.docs + for root, dirs, files in os.walk(DOCS_DIR): + for file in files: + if file.endswith(".md"): + # Remove .md extension + card_names.append(file[:-3]) + return card_names + +def slugify(card_name): + # Manual overrides for slugs that don't follow the standard pattern + overrides = { + "APEX Starcruise": "apex-starcruiser", + "Consummate Conspirator": "consomme-conspirator", + "Librarian's Assistant": "librarian-assistant", + "Violet Inquisitioner": "violet-inquisitor", + "Breakdown": "break-down", + "Da'Kad, Heretic Crusher": "da-kad-heretic-crusher", + "Shae'Fan, Remembered": "shae-fan-remembered", + "Possessed Prawn": "possessed-prawn-card", + "P.O.G.O": "p-o-g-o", + "A'kon, Starry Diviner": "a-kon-starry-diviner", + "B.O.O.F.": "b-o-o-f", + "Raiz, Pacifist's Conclusion": "raiz-pacifists-conclusion", + "Spirit's Lament": "spirits-lament", + "Overmind's Guilt": "overminds-guilt", + "Entropy's End": "entropys-end", + "Vor’kon, Eternal Source": "vor-kon-eternal-source", + "Ta'kan the Tattle": "ta-kan-the-tattle", + } + + # Fix potential encoding issues in card_name (e.g. smart quotes) + # If the script is run in an environment where the filenames were read as mangled + # we want to ensure we use the correct name for the filename and slug lookup. + # Note: '’' is the UTF-8 bytes for '’' interpreted as Windows-1252 + if isinstance(card_name, str): + card_name = card_name.replace("’", "'").replace("’", "'") + + if card_name in overrides: + return overrides[card_name] + + # Convert to lowercase, replace spaces/special chars with hyphens + slug = card_name.lower() + slug = re.sub(r'[^a-z0-9]+', '-', slug) + slug = slug.strip('-') + return slug + +def download_full_art(card_name): + # Fix potential encoding issues in card_name (e.g. smart quotes) + if isinstance(card_name, str): + card_name = card_name.replace("’", "'").replace("’", "'") + + slug = slugify(card_name) + url = f"https://www.playchrono.com/card/{slug}" + + print(f"Processing {card_name} ({url})...") + + try: + response = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=10) + if response.status_code != 200: + print(f" [ERROR] Failed to fetch page for {card_name}: {response.status_code}") + return + + # Look for all data-lightbox-src and data-lightbox-alt pairs + # We want the ones that end with "Full Art" and match our card name + pattern = r'data-lightbox-src="([^"]+)"\s+data-lightbox-alt="([^"]+)"' + matches = re.findall(pattern, response.text) + + full_art_url = None + for src, alt in matches: + if "Full Art" in alt and (card_name.lower() in alt.lower()): + full_art_url = src + break + + # Fallback to the first "Full Art" if no exact match (sometimes names might slightly differ) + if not full_art_url: + for src, alt in matches: + if "Full Art" in alt: + full_art_url = src + break + + # Absolute fallback to any data-lightbox-src with the pattern if still nothing + if not full_art_url: + match = re.search(r'data-lightbox-src="(https://cdn\.playchrono\.com/latest/en_us/img/cards/set/1/[^"]+\.png)"', response.text) + if match: + full_art_url = match.group(1) + + if not full_art_url: + print(f" [INFO] No full art found for {card_name}") + return + + print(f" [FOUND] {full_art_url} for {card_name}") + + # Download image + img_response = requests.get(full_art_url, headers={"User-Agent": USER_AGENT}, timeout=10) + if img_response.status_code == 200: + filename = f"fa{card_name}.png" + + # Save to Cloud + os.makedirs(CLOUD_CARDS_DIR, exist_ok=True) + with open(os.path.join(CLOUD_CARDS_DIR, filename), "wb") as f: + f.write(img_response.content) + + # Save to Standalone + os.makedirs(STANDALONE_CARDS_DIR, exist_ok=True) + with open(os.path.join(STANDALONE_CARDS_DIR, filename), "wb") as f: + f.write(img_response.content) + + print(f" [SUCCESS] Saved {filename}") + else: + print(f" [ERROR] Failed to download image for {card_name}: {img_response.status_code}") + + except Exception as e: + print(f" [ERROR] Exception for {card_name}: {e}") + +def main(): + card_names = get_card_names() + print(f"Found {len(card_names)} cards to process.") + + # Use ThreadPoolExecutor for faster downloads + with ThreadPoolExecutor(max_workers=5) as executor: + executor.map(download_full_art, card_names) + +if __name__ == "__main__": + main() diff --git a/Chrono/Cloud/AppDbContext.cs b/Chrono/Cloud/AppDbContext.cs index f9015e9..baf78a2 100644 --- a/Chrono/Cloud/AppDbContext.cs +++ b/Chrono/Cloud/AppDbContext.cs @@ -1,6 +1,5 @@ -using Model; -using Microsoft.EntityFrameworkCore; using Cloud.Models; +using Microsoft.EntityFrameworkCore; using Model; namespace Cloud; diff --git a/Chrono/Cloud/AppDbContextFactory.cs b/Chrono/Cloud/AppDbContextFactory.cs index 78dafe0..e4417c2 100644 --- a/Chrono/Cloud/AppDbContextFactory.cs +++ b/Chrono/Cloud/AppDbContextFactory.cs @@ -12,4 +12,4 @@ public class AppDbContextFactory : IDesignTimeDbContextFactory .Options; return new AppDbContext(options); } -} +} \ No newline at end of file diff --git a/Chrono/Cloud/Cloud.csproj b/Chrono/Cloud/Cloud.csproj index f5d257e..35de9bf 100644 --- a/Chrono/Cloud/Cloud.csproj +++ b/Chrono/Cloud/Cloud.csproj @@ -16,13 +16,13 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + - - + + diff --git a/Chrono/Cloud/Components/CardDialog.razor b/Chrono/Cloud/Components/CardDialog.razor index 8f02f02..ea019cd 100644 --- a/Chrono/Cloud/Components/CardDialog.razor +++ b/Chrono/Cloud/Components/CardDialog.razor @@ -1,4 +1,3 @@ - @using System.Text.RegularExpressions @namespace Chrono.Components @@ -12,7 +11,7 @@ {
@Card.Name + onerror="this.src='@Card.SmallImagePath';this.onerror=null;"/>
}
diff --git a/Chrono/Cloud/Components/CardDialog.razor.css b/Chrono/Cloud/Components/CardDialog.razor.css index fa45919..7e2ead9 100644 --- a/Chrono/Cloud/Components/CardDialog.razor.css +++ b/Chrono/Cloud/Components/CardDialog.razor.css @@ -26,7 +26,7 @@ border: 1px solid var(--border); border-radius: 16px; padding: 0; - max-width: 720px; + max-width: 850px; width: 92vw; max-height: 88vh; overflow-y: auto; @@ -76,13 +76,15 @@ } .detail-image { - flex: 0 0 260px; + flex: 0 0 320px; } .detail-image img { width: 100%; border-radius: var(--radius); box-shadow: var(--shadow); + max-height: 80vh; + object-fit: contain; } /* ── No-image layout ── */ diff --git a/Chrono/Cloud/Components/Layout/NavMenu.razor b/Chrono/Cloud/Components/Layout/NavMenu.razor index 399d129..825133e 100644 --- a/Chrono/Cloud/Components/Layout/NavMenu.razor +++ b/Chrono/Cloud/Components/Layout/NavMenu.razor @@ -12,12 +12,12 @@ @code { - [Parameter][EditorRequired] public List<(int Cost, int Count)> Distribution { get; set; } = []; + [Parameter] [EditorRequired] public List<(int Cost, int Count)> Distribution { get; set; } = []; [Parameter] public int MaxCostLabel { get; set; } = 10; private int MaxCount => Distribution.Count > 0 ? Distribution.Max(x => x.Count) : 0; diff --git a/Chrono/Shared/Generated/Cards.g.cs b/Chrono/Shared/Generated/Cards.g.cs index 3ac3f31..f4b4f6d 100644 --- a/Chrono/Shared/Generated/Cards.g.cs +++ b/Chrono/Shared/Generated/Cards.g.cs @@ -7,6 +7,13 @@ public static class CardDatabase { public static readonly System.Collections.Generic.List Cards = [ + new() + { + Name = "Breakdown", + Category = "Notes", + Archetypes = [ + ], + }, new() { Name = "Core Charges", @@ -964,6 +971,26 @@ public static class CardDatabase Rarity = "Rare", }, new() + { + Name = "Consummate Conspirator", + Category = "Agent", + Cost = 3, + Attack = 2, + Health = 3, + Description = "When you heal a damaged ally, give it Evasive this round.", + Faction = "Phasetide", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + "Ta'kan the Tattle", + ], + ImmortalizeWhen = "I've seen allies or your Core heal 6+.", + ImageFile = "Consummate Conspirator.png", + Artist = "Paul Takahashi", + Rarity = "Lost", + }, + new() { Name = "Curious Acolyte", Category = "Agent", @@ -1084,7 +1111,7 @@ public static class CardDatabase "Rewound", ], ImmortalizeTo = [ - "Violent Inquisitioner", + "Violet Inquisitioner", ], ImmortalizeWhen = "You've Rewound 3+ times this game.", ImageFile = "Holy Cleaner.png", @@ -1283,7 +1310,7 @@ public static class CardDatabase { Name = "Death Jockey", Category = "Agent", - Cost = 5, + Cost = 6, Attack = 4, Health = 4, Description = "Activate: Refresh an ally. That ally cannot Refresh again this round.", @@ -1406,7 +1433,7 @@ public static class CardDatabase Name = "Nameless Spirit", Category = "Agent", Cost = 2, - Attack = 3, + Attack = 2, Health = 2, Description = "Temporary. Siphon.", Faction = "Silence", @@ -1444,6 +1471,26 @@ public static class CardDatabase Rarity = "Lost", }, new() + { + Name = "Possessed Prawn", + Category = "Agent", + Cost = 2, + Attack = 2, + Health = 1, + Description = "I have +3/+0 while I see Voiceless Sky.", + Faction = "Silence", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + "Cray, Reborn", + ], + ImmortalizeWhen = "I see Voiceless Sky.", + ImageFile = "Possessed Prawn.png", + Artist = "Paul Takahashi", + Rarity = "Lost", + }, + new() { Name = "Redactionist", Category = "Agent", @@ -1467,9 +1514,9 @@ public static class CardDatabase { Name = "Rotting Rocker", Category = "Agent", - Cost = 3, - Attack = 3, - Health = 1, + Cost = 4, + Attack = 2, + Health = 2, Description = "Activate: (C) Deal 2 to a random enemy.", Faction = "Silence", Set = "Core Set", @@ -1883,6 +1930,26 @@ public static class CardDatabase Rarity = "Common", }, new() + { + Name = "Springloaded Hopper", + Category = "Agent", + Cost = 1, + Attack = 1, + Health = 1, + Description = "Enter: Grant all allies +1|+0.", + Faction = "Singularity", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + "P.O.G.O", + ], + ImmortalizeWhen = "Allies have 10+ Strength.", + ImageFile = "Springloaded Hopper.png", + Artist = "Paul Takahashi", + Rarity = "Lost", + }, + new() { Name = "Traffic Conductor", Category = "Agent", @@ -2067,6 +2134,26 @@ public static class CardDatabase Rarity = "Rare", }, new() + { + Name = "Frenzied Hemomancer", + Category = "Agent", + Cost = 2, + Attack = 1, + Health = 3, + Description = "Activate: Discard a card to give an ally +1|+1.", + Faction = "Splintergleam", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + "Driven the Scarlet Storm", + ], + ImmortalizeWhen = "I've seen you discard 3+ cards.", + ImageFile = "Frenzied Hemomancer.png", + Artist = "Rhuan Gon", + Rarity = "Lost", + }, + new() { Name = "Frontline Juggernaut", Category = "Agent", @@ -2267,6 +2354,26 @@ public static class CardDatabase Rarity = "Common", }, new() + { + Name = "APEX Starcruise", + Category = "Agent", + Cost = 9, + Attack = 8, + Health = 8, + Description = "Enter: Erase the top 5 cards of your Graveyard to deal 1 to all enemies for each Action erased.", + Faction = "Sungrace", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + "The Sunbringer", + ], + ImmortalizeWhen = "You've spent 12+ Energy in one round.", + ImageFile = "APEX Starcruise.png", + Artist = "Julien Fenoglio", + Rarity = "Lost", + }, + new() { Name = "Brilliant Martyr", Category = "Agent", @@ -3276,6 +3383,25 @@ public static class CardDatabase Rarity = "Common", }, new() + { + Name = "Ta'kan the Tattle", + Category = "Immortalized", + Cost = 3, + Attack = 3, + Health = 4, + Description = "Activate: Deal 1 to an ally, then Heal it 1. When you heal a damaged ally, give it Evasive this round.", + Faction = "Phasetide", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + ], + ImmortalizeFrom = "Consummate Conspirator", + ImageFile = "Ta'kan the Tattle.png", + Artist = "Paul Takahashi", + Rarity = "Lost", + }, + new() { Name = "The 'Stache", Category = "Immortalized", @@ -3295,26 +3421,6 @@ public static class CardDatabase Rarity = "Divergent", }, new() - { - Name = "Violent Inquisitioner", - Category = "Immortalized", - Cost = 3, - Attack = 3, - Health = 4, - Description = "Play: Activate Rewind an Agent with equal or less Durability than me. The first time each round you Rewind an Agent, Draw 1.", - Faction = "Phasetide", - Set = "Core Set", - Archetypes = [ - "Rewound", - ], - ImmortalizeTo = [ - ], - ImmortalizeFrom = "Holy Cleaner", - ImageFile = "Violet Inquisitioner.png", - Artist = "Millena Ramos", - Rarity = "Common", - }, - new() { Name = "Violet Inquisitioner", Category = "Immortalized", @@ -3331,7 +3437,7 @@ public static class CardDatabase ImmortalizeTo = [ ], ImmortalizeFrom = "Holy Cleaner", - ImageFile = "Violent Inquisitioner.png", + ImageFile = "Violet Inquisitioner.png", Artist = "Millena Ramos", Rarity = "Common", }, @@ -3414,10 +3520,29 @@ public static class CardDatabase Rarity = "Rare", }, new() + { + Name = "Cray, Reborn", + Category = "Immortalized", + Cost = 2, + Attack = 3, + Health = 2, + Description = "I have +3/+0 while I see Voiceless Sky. Last Gasp: Grant the weakest ally my Strength.", + Faction = "Silence", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + ], + ImmortalizeFrom = "Possessed Prawn", + ImageFile = "Cray, Reborn.png", + Artist = "Paul Takahashi", + Rarity = "Lost", + }, + new() { Name = "Daville, the Star Song", Category = "Immortalized", - Cost = 5, + Cost = 6, Attack = 5, Health = 5, Description = "Activate: Refresh an ally. That ally cannot Refresh again this round. When an ally Deplete|Depletes, if I see Voiceless Sky, give it +3/+3 this round.", @@ -3495,7 +3620,7 @@ public static class CardDatabase Name = "Khaela, the Vanished", Category = "Immortalized", Cost = 2, - Attack = 3, + Attack = 2, Health = 2, Description = "Blitz. Siphon.", Faction = "Silence", @@ -3671,9 +3796,9 @@ public static class CardDatabase { Name = "Ylka, the Headliner", Category = "Immortalized", - Cost = 3, - Attack = 3, - Health = 1, + Cost = 4, + Attack = 2, + Health = 2, Description = "Activate: Rock out. When allies Deplete, (C) Deal 2 to a random enemy. If it's dead or gone, deal 1 to the enemy Core instead.", Faction = "Silence", Set = "Core Set", @@ -3702,7 +3827,7 @@ public static class CardDatabase ImmortalizeTo = [ ], ImmortalizeFrom = "Enhanced Retriever", - ImageFile = "B.O.O.F..png", + ImageFile = "B.O.O.F.png", Artist = "Bi Pi", Rarity = "Rare", }, @@ -3847,6 +3972,25 @@ public static class CardDatabase Rarity = "Rare", }, new() + { + Name = "P.O.G.O", + Category = "Immortalized", + Cost = 1, + Attack = 2, + Health = 2, + Description = "When I or an ally Strikes, give it +1|+0.", + Faction = "Singularity", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + ], + ImmortalizeFrom = "Springloaded Hopper", + ImageFile = "P.O.G.O.png", + Artist = "Paul Takahashi", + Rarity = "Lost", + }, + new() { Name = "Quicksilver Khaela", Category = "Immortalized", @@ -3954,7 +4098,7 @@ public static class CardDatabase Cost = 3, Attack = 6, Health = 1, - Description = "Overpower. Enter: Create a copy of me in hand.", + Description = "Overpower. Enter: Create a copy of me in hand at next Round Start.", Faction = "Singularity", Set = "Core Set", Archetypes = [ @@ -4044,6 +4188,25 @@ public static class CardDatabase Rarity = "Common", }, new() + { + Name = "Driven the Scarlet Storm", + Category = "Immortalized", + Cost = 2, + Attack = 2, + Health = 4, + Description = "When you discard a card, give an ally +1|+1. Activate: Create 3 Transient Bloodbolt in your hand.", + Faction = "Splintergleam", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + ], + ImmortalizeFrom = "Frenzied Hemomancer", + ImageFile = "Driven the Scarlet Storm.png", + Artist = "Rhuan Gon", + Rarity = "Lost", + }, + new() { Name = "Enlightened Survivor", Category = "Immortalized", @@ -4420,7 +4583,7 @@ public static class CardDatabase Cost = 8, Attack = 9, Health = 15, - Description = "Delay. Confront. If your opponent would Confront an Agent, they must Confront me if able. Allies and your Core take 1 less damage from all sources.", + Description = "Delay. Allies and your Core take 1 less damage from all sources.", Faction = "Sungrace", Set = "Core Set", Archetypes = [ @@ -4664,6 +4827,25 @@ public static class CardDatabase Rarity = "Divergent", }, new() + { + Name = "The Sunbringer", + Category = "Immortalized", + Cost = 9, + Attack = 9, + Health = 9, + Description = "Enter: Erase the top 5 cards of your Graveyard to deal 1 to all enemies for each Action erased. When you play an Action, deal 1 to the enemy Core.", + Faction = "Sungrace", + Set = "Core Set", + Archetypes = [ + ], + ImmortalizeTo = [ + ], + ImmortalizeFrom = "APEX Starcruise", + ImageFile = "The Sunbringer.png", + Artist = "Julien Fenoglio", + Rarity = "Lost", + }, + new() { Name = "Time Devourer Soval", Category = "Immortalized", @@ -4795,6 +4977,21 @@ public static class CardDatabase Rarity = "Common", }, new() + { + Name = "Pack Tactics", + Category = "Spell", + Cost = 3, + Description = "Summon two Wolf|Wolves. If you see Abundant Growth, ally Wolf|Wolves Flourish.", + Faction = "Lifeblood", + Set = "Core Set", + Speed = "Slow", + Archetypes = [ + ], + ImageFile = "Pack Tactics.png", + Artist = "Donnie Obina", + Rarity = "Lost", + }, + new() { Name = "Paradox Stimulator", Category = "Spell", @@ -4903,7 +5100,7 @@ public static class CardDatabase { Name = "Unstoppable Growth", Category = "Spell", - Cost = 4, + Cost = 5, Description = "An Agent destroys its allies and gains their Strength and Durability.", Faction = "Lifeblood", Set = "Core Set", @@ -5263,7 +5460,7 @@ public static class CardDatabase { Name = "Not so Fast", Category = "Spell", - Cost = 3, + Cost = 4, Description = "Revive the strongest ally that was destroyed this round.", Faction = "Silence", Set = "Core Set", @@ -5353,7 +5550,7 @@ public static class CardDatabase { Name = "Spread the Sickness", Category = "Spell", - Cost = 5, + Cost = 6, Description = "When an Agent is destroyed this round, Agents Decay. Agents Decay.", Faction = "Silence", Set = "Core Set", @@ -5593,7 +5790,7 @@ public static class CardDatabase { Name = "We Have Cookies", Category = "Spell", - Cost = 9, + Cost = 8, Description = "Take control of an enemy with a cost equal to or less than the number of Timelines in the Timeline Stack.", Faction = "Singularity", Set = "Core Set", @@ -5729,7 +5926,7 @@ public static class CardDatabase Name = "Go for the Heart", Category = "Spell", Cost = 5, - Description = "Deal 3 to the enemy Core. Breakdown 10: Instead, deal 4. Breakdown 1: Instead, deal 5.", + Description = "Deal 3 to the enemy Core. Breakdown 15: Instead, deal 4. Breakdown 5: Instead, deal 5.", Faction = "Splintergleam", Set = "Core Set", Speed = "Slow", @@ -5758,11 +5955,11 @@ public static class CardDatabase { Name = "Kintsu-Kai", Category = "Spell", - Cost = 2, + Cost = 1, Description = "Any amount of allies Bleed 1. Grant Bleed to a single enemy that many times.", Faction = "Splintergleam", Set = "Core Set", - Speed = "Immediate", + Speed = "Slow", Archetypes = [ ], ImageFile = "Kintsu-Kai.png", @@ -5773,11 +5970,11 @@ public static class CardDatabase { Name = "Magmatic Teachings", Category = "Spell", - Cost = 3, + Cost = 4, Description = "An Immortalized ally strikes an enemy. If that enemy is destroyed, Immortalize your weakest non-Immoralized ally.", Faction = "Splintergleam", Set = "Core Set", - Speed = "Slow", + Speed = "Fast", Archetypes = [ ], ImageFile = "Magmatic Teachings.png", diff --git a/Chrono/Shared/Generated/Decks.g.cs b/Chrono/Shared/Generated/Decks.g.cs index 9d54821..61face6 100644 --- a/Chrono/Shared/Generated/Decks.g.cs +++ b/Chrono/Shared/Generated/Decks.g.cs @@ -208,64 +208,6 @@ public static class DeckDatabase DeckType = "store", }, new() - { - Name = "Midrange", - Cards = [ - "Holder of the Instruments", - "Holder of the Instruments", - "Holder of the Instruments", - "Invigorating Balm", - "Invigorating Balm", - "Kinetic Absorber", - "Kinetic Absorber", - "Kinetic Absorber", - "Sunshock", - "Sunshock", - "Seeker of Truth", - "Seeker of Truth", - "Backhand", - "Backhand", - "Backhand", - "The Firm Hand", - "Chaos Control", - "Chaos Control", - "Paradox Flow", - "Paradox Flow", - "Paradox Flow", - "Set in Stone", - "Set in Stone", - "Lumbering Starseeker", - "Lumbering Starseeker", - "Lumbering Starseeker", - "Novathermal Mining", - "Novathermal Mining", - "Novathermal Mining", - "Curb the Anomalies", - "Curb the Anomalies", - "Curb the Anomalies", - "Lightsteel Colossus", - "Lightsteel Colossus", - "Unlocked Potential", - "Unlocked Potential", - "Devourer Spawn", - "Devourer Spawn", - ], - Keycards = [ - ], - Divers = [ - "Shattersmith", - "Gunnery Captain", - ], - Description = "", - Factions = [ - "Phasetide", - "Sungrace", - ], - IsVisible = true, - DeckCode = "", - DeckType = "precon", - }, - new() { Name = "Overflowing Security", Cards = [ @@ -328,6 +270,184 @@ public static class DeckDatabase DeckType = "custom", }, new() + { + Name = "Precon Midrange", + Cards = [ + "Holder of the Instruments", + "Holder of the Instruments", + "Holder of the Instruments", + "Invigorating Balm", + "Invigorating Balm", + "Kinetic Absorber", + "Kinetic Absorber", + "Kinetic Absorber", + "Sunshock", + "Sunshock", + "Seeker of Truth", + "Seeker of Truth", + "Backhand", + "Backhand", + "Backhand", + "The Firm Hand", + "Chaos Control", + "Chaos Control", + "Paradox Flow", + "Paradox Flow", + "Paradox Flow", + "Set in Stone", + "Set in Stone", + "Lumbering Starseeker", + "Lumbering Starseeker", + "Lumbering Starseeker", + "Novathermal Mining", + "Novathermal Mining", + "Novathermal Mining", + "Curb the Anomalies", + "Curb the Anomalies", + "Curb the Anomalies", + "Lightsteel Colossus", + "Lightsteel Colossus", + "Unlocked Potential", + "Unlocked Potential", + "Devourer Spawn", + "Devourer Spawn", + ], + Keycards = [ + ], + Divers = [ + "Shattersmith", + "Gunnery Captain", + ], + Description = "", + Factions = [ + "Phasetide", + "Sungrace", + ], + IsVisible = true, + DeckCode = "AUHVA4TFMNXW4ICNNFSHEYLOM5SQWY3PNZZXI4TVMN2GKZCPAABACAMVAIEVGAQCAEEJOAIHCMDQONYDCIBREA4YAEBSAAYEAMCAG", + DeckType = "precon", + }, + new() + { + Name = "Precon Sprouts", + Cards = [ + "Fervent Mycologist", + "Fervent Mycologist", + "Gardener Apprentice", + "Gardener Apprentice", + "Gardener Apprentice", + "Aardvark Precinct Captain", + "Aardvark Precinct Captain", + "Glade Grazers", + "Glade Grazers", + "Glade Grazers", + "Bloom", + "Bloom", + "Bloom", + "Scattered Helpers", + "Scattered Helpers", + "Scattered Helpers", + "Aggressive Recycling", + "Aggressive Recycling", + "Conscientious Overwrite", + "Conscientious Overwrite", + "Conscientious Overwrite", + "Pocket Dimension", + "Pocket Dimension", + "Pocket Dimension", + "Sap Sapper", + "Strength of the Grove", + "Strength of the Grove", + "Enthusiastic Bot-Poke", + "Enthusiastic Bot-Poke", + "Enthusiastic Bot-Poke", + "Overclock", + "Spark of Bounty", + "Spark of Bounty", + "Spark of Bounty", + "Uninhibited Expansion", + "Uninhibited Expansion", + "Uninhibited Expansion", + "Stability Control", + "Stability Control", + "Stability Control", + ], + Keycards = [ + ], + Divers = [ + "Efficient Scrapbot", + "Sapling Dryad", + ], + Description = "", + Factions = [ + "Lifeblood", + "Sapling Dryad", + ], + IsVisible = true, + DeckCode = "AUHFA4TFMNXW4ICTOBZG65LUOMFWG33OON2HE5LDORSWIDAASAAAEGM6AECAKBBBQUAQUBYDBIBQYAYHAMEQG3YDAQBRCAYEAMCQG", + DeckType = "precon", + }, + new() + { + Name = "Precon Telekinetic Burn", + Cards = [ + "Braindead Bouncer", + "Braindead Bouncer", + "Denizen of Flames", + "Denizen of Flames", + "Denizen of Flames", + "Rebuild", + "Rebuild", + "Rebuild", + "Nameless Spirit", + "Nameless Spirit", + "Nameless Spirit", + "Telepathic Conduit", + "Telepathic Conduit", + "Telepathic Conduit", + "Gnosis", + "Gnosis", + "Gnosis", + "Pressure Spike", + "Pressure Spike", + "Pressure Spike", + "Bathe in Flames", + "Bathe in Flames", + "Bathe in Flames", + "Rotting Rocker", + "Rotting Rocker", + "Rotting Rocker", + "Cascading Serenity", + "Cascading Serenity", + "Bloodbolt", + "Bloodbolt", + "Bloodbolt", + "Ironblood Elixir", + "Ironblood Elixir", + "Ironblood Elixir", + "Destiny Ripper", + "Destiny Ripper", + "Go for the Heart", + "Go for the Heart", + "Brutal Reveler", + "Brutal Reveler", + ], + Keycards = [ + ], + Divers = [ + "Somber Astronomer", + "Bloodline Tracker", + ], + Description = "", + Factions = [ + "Silence", + "Splintergleam", + ], + IsVisible = true, + DeckCode = "AULFA4TFMNXW4ICUMVWGK4DBORUGSYZAIJ2XE3QLMNXW443UOJ2WG5DFMRSABPIAAACWECQ3KYHAU2ADAIBQQAYRAMBAGOQDEIBQCAYHAMAQG", + DeckType = "precon", + }, + new() { Name = "Rewind Me", Cards = [ @@ -538,66 +658,6 @@ public static class DeckDatabase DeckType = "store", }, new() - { - Name = "Sprouts", - Cards = [ - "Fervent Mycologist", - "Fervent Mycologist", - "Gardener Apprentice", - "Gardener Apprentice", - "Gardener Apprentice", - "Aardvark Precinct Captain", - "Aardvark Precinct Captain", - "Glade Grazers", - "Glade Grazers", - "Glade Grazers", - "Bloom", - "Bloom", - "Bloom", - "Scattered Helpers", - "Scattered Helpers", - "Scattered Helpers", - "Aggressive Recycling", - "Aggressive Recycling", - "Conscientious Overwrite", - "Conscientious Overwrite", - "Conscientious Overwrite", - "Pocket Dimension", - "Pocket Dimension", - "Pocket Dimension", - "Sap Sapper", - "Strength of the Grove", - "Strength of the Grove", - "Enthusiastic Bot-Poke", - "Enthusiastic Bot-Poke", - "Enthusiastic Bot-Poke", - "Overclock", - "Spark of Bounty", - "Spark of Bounty", - "Spark of Bounty", - "Uninhibited Expansion", - "Uninhibited Expansion", - "Uninhibited Expansion", - "Stability Control", - "Stability Control", - "Stability Control", - ], - Keycards = [ - ], - Divers = [ - "Efficient Scrapbot", - "Sapling Dryad", - ], - Description = "", - Factions = [ - "Lifeblood", - "Sapling Dryad", - ], - IsVisible = true, - DeckCode = "", - DeckType = "precon", - }, - new() { Name = "Sudden Wolves", Cards = [ @@ -721,66 +781,6 @@ public static class DeckDatabase DeckType = "store", }, new() - { - Name = "Telekinetic Burn", - Cards = [ - "Braindead Bouncer", - "Braindead Bouncer", - "Denizen of Flames", - "Denizen of Flames", - "Denizen of Flames", - "Rebuild", - "Rebuild", - "Rebuild", - "Nameless Spirit", - "Nameless Spirit", - "Nameless Spirit", - "Telepathic Conduit", - "Telepathic Conduit", - "Telepathic Conduit", - "Gnosis", - "Gnosis", - "Gnosis", - "Pressure Spike", - "Pressure Spike", - "Pressure Spike", - "Bathe in Flames", - "Bathe in Flames", - "Bathe in Flames", - "Rotting Rocker", - "Rotting Rocker", - "Rotting Rocker", - "Cascading Serenity", - "Cascading Serenity", - "Bloodbolt", - "Bloodbolt", - "Bloodbolt", - "Ironblood Elixir", - "Ironblood Elixir", - "Ironblood Elixir", - "Destiny Ripper", - "Destiny Ripper", - "Go for the Heart", - "Go for the Heart", - "Brutal Reveler", - "Brutal Reveler", - ], - Keycards = [ - ], - Divers = [ - "Somber Astronomer", - "Bloodline Tracker", - ], - Description = "", - Factions = [ - "Silence", - "Splintergleam", - ], - IsVisible = true, - DeckCode = "", - DeckType = "precon", - }, - new() { Name = "Tempo Deplete", Cards = [ diff --git a/Chrono/Shared/Generated/Docs.g.cs b/Chrono/Shared/Generated/Docs.g.cs index a6f3d79..9cb6f3d 100644 --- a/Chrono/Shared/Generated/Docs.g.cs +++ b/Chrono/Shared/Generated/Docs.g.cs @@ -7,6 +7,16 @@ public static class DocDatabase { public static readonly System.Collections.Generic.List Docs = [ + new() + { + Title = "Breakdown", + Category = "Notes", + Content = "| | Lifeblood | Phasetide | Silence | Singularity | Splittergleam | Sungrace |\n|---------------|-----------|-----------|---------|-------------|---------------|----------|\n| Lifeblood | X | Shift | Sprout | Sprouts | Mid Range | Flourish |\n| Phasetide | | X | Rewind | Rewind | Bleed | Overload |\n| Silence | | | X | Deplete | Burn | Control |\n| Singularity | | | | X | Aggro | Disarm |\n| Splittergleam | | | | | X | Fevor |\n| Sungrace | | | | | | X |\n\nCombinations: 15", + Frontmatter = new() + { + { "category", "Notes" }, + }, + }, new() { Title = "Core Charges", @@ -194,7 +204,7 @@ public static class DocDatabase { Title = "Splintergleam", Category = "Faction", - Content = "# Self Damage\r\n\r\nCan hurt it's own units for power. Has [[Bleed]] to make reoccurring damage on units very easy.\r\n\r\n# Core Damage\r\n\r\nCan hurt both cores easily. Has [[Breakdown]] to take advantage of having an injured core for more damage.", + Content = "# Self Damage\r\n\r\nCan hurt it's own units for power. Has [[Bleed]] to make reoccurring damage on units very easy.\r\n\r\n# Core Damage\r\n\r\nCan hurt both cores easily. Has [[Keyword/Breakdown]] to take advantage of having an injured core for more damage.", Frontmatter = new() { { "category", "Faction" }, diff --git a/Chrono/Shared/Pages/DeckDetail.razor b/Chrono/Shared/Pages/DeckDetail.razor index 55fcaac..5dfe095 100644 --- a/Chrono/Shared/Pages/DeckDetail.razor +++ b/Chrono/Shared/Pages/DeckDetail.razor @@ -1,7 +1,6 @@ @namespace Shared.Pages @inject CardRenderingService CardRenderer @page "/decks/{Name}" -@using Model Chrono CCG - @(deck?.Name ?? "Deck Details") diff --git a/Chrono/Shared/Pages/Decks.razor b/Chrono/Shared/Pages/Decks.razor index 7c285d9..0b855d2 100644 --- a/Chrono/Shared/Pages/Decks.razor +++ b/Chrono/Shared/Pages/Decks.razor @@ -1,6 +1,5 @@ @namespace Shared.Pages @page "/decks" -@using Model Chrono CCG - Decks diff --git a/Chrono/Shared/Pages/Docs.razor b/Chrono/Shared/Pages/Docs.razor index 1aae3aa..764f217 100644 --- a/Chrono/Shared/Pages/Docs.razor +++ b/Chrono/Shared/Pages/Docs.razor @@ -1,6 +1,5 @@ @namespace Shared.Pages @page "/docs" -@using Model Docs diff --git a/Chrono/Shared/Pages/Home.razor b/Chrono/Shared/Pages/Home.razor index e37be39..c768429 100644 --- a/Chrono/Shared/Pages/Home.razor +++ b/Chrono/Shared/Pages/Home.razor @@ -1,5 +1,5 @@ @namespace Shared.Pages -@page "/" +@page "/home" Slop Game Reference - Chrono CCG @@ -11,7 +11,7 @@ AI generated website for reference notes on playing Chrono CCG.

- + Browse Cards diff --git a/Chrono/Shared/Services/CardRenderingService.cs b/Chrono/Shared/Services/CardRenderingService.cs index c47c96f..0a4c7e5 100644 --- a/Chrono/Shared/Services/CardRenderingService.cs +++ b/Chrono/Shared/Services/CardRenderingService.cs @@ -1,6 +1,6 @@ using System.Text.RegularExpressions; -using Model; using Microsoft.AspNetCore.Components; +using Model; namespace Shared.Services; diff --git a/Chrono/Shared/Shared.csproj b/Chrono/Shared/Shared.csproj index f5c2c70..7019671 100644 --- a/Chrono/Shared/Shared.csproj +++ b/Chrono/Shared/Shared.csproj @@ -21,8 +21,8 @@ - - + + diff --git a/Chrono/Standalone/Components/CardDialog.razor b/Chrono/Standalone/Components/CardDialog.razor index c53b7a9..0e0eb78 100644 --- a/Chrono/Standalone/Components/CardDialog.razor +++ b/Chrono/Standalone/Components/CardDialog.razor @@ -1,5 +1,4 @@ @using System.Text.RegularExpressions -@using global::Model @namespace Chrono.Components @if (Card != null) @@ -12,7 +11,7 @@ {
@Card.Name + onerror="this.src='@Card.SmallImagePath';this.onerror=null;"/>
}
@@ -42,7 +41,7 @@ @if (Card.Faction != null) {
- Faction + Syndicate @Card.Faction
} diff --git a/Chrono/Standalone/Components/CardDialog.razor.css b/Chrono/Standalone/Components/CardDialog.razor.css index fa45919..7e2ead9 100644 --- a/Chrono/Standalone/Components/CardDialog.razor.css +++ b/Chrono/Standalone/Components/CardDialog.razor.css @@ -26,7 +26,7 @@ border: 1px solid var(--border); border-radius: 16px; padding: 0; - max-width: 720px; + max-width: 850px; width: 92vw; max-height: 88vh; overflow-y: auto; @@ -76,13 +76,15 @@ } .detail-image { - flex: 0 0 260px; + flex: 0 0 320px; } .detail-image img { width: 100%; border-radius: var(--radius); box-shadow: var(--shadow); + max-height: 80vh; + object-fit: contain; } /* ── No-image layout ── */ diff --git a/Chrono/Standalone/Components/Layout/NavMenu.razor b/Chrono/Standalone/Components/Layout/NavMenu.razor index 694ccff..6dd9ed5 100644 --- a/Chrono/Standalone/Components/Layout/NavMenu.razor +++ b/Chrono/Standalone/Components/Layout/NavMenu.razor @@ -1,4 +1,3 @@ -