Add NuGet configuration and project assets for NewGame.UI

- Created new NuGet dependency specification files for NewGame.UI and NewGame projects.
- Added project.assets.json to manage package dependencies and versions.
- Included .props and .targets files for NuGet integration.
- Configured project references and restore settings for .NET 9.0 Windows target framework.
- Established package folders and cache for NuGet packages.
This commit is contained in:
alexandriaa
2026-04-05 16:07:06 -04:00
parent d5073c68dc
commit ceaf3cca1f
477 changed files with 5731 additions and 3543 deletions
+29
View File
@@ -0,0 +1,29 @@
{
"version": "0.2.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "dotnet build",
"args": ["${workspaceFolder}"],
"group": "build",
"presentation": {
"reveal": "always",
"panel": "shared"
}
}
],
"configurations": [
{
"name": "Run WPF UI",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "dotnet",
"args": ["run", "--project", "NewGame.UI"],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
}
]
}
+20
View File
@@ -0,0 +1,20 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "dotnet build",
"args": [],
"problemMatcher": ["$msCompile"],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "shared"
}
}
]
}
@@ -17,14 +17,14 @@ public static class PlaceholderGenerator
// Element colors
private static readonly Dictionary<ElementType, Color> ElementColors = new()
{
{ ElementType.Fire, Color.FromArgb(255, 80, 30) },
{ ElementType.Water, Color.FromArgb(30, 100, 200) },
{ ElementType.Earth, Color.FromArgb(100, 70, 40) },
{ ElementType.Air, Color.FromArgb(180, 220, 255) },
{ ElementType.Light, Color.FromArgb(255, 240, 180) },
{ ElementType.Dark, Color.FromArgb(40, 20, 50) },
{ ElementType.Arcane, Color.FromArgb(150, 50, 200) },
{ ElementType.Nature, Color.FromArgb(60, 140, 60) }
{ ElementType.Radioactivity, Color.FromArgb(0, 255, 100) }, // Radioactive green glow
{ ElementType.Flesh, Color.FromArgb(200, 100, 100) }, // Fleshy red
{ ElementType.Toxin, Color.FromArgb(150, 200, 0) }, // Toxic yellow-green
{ ElementType.Fungus, Color.FromArgb(100, 150, 100) }, // Mushroom green
{ ElementType.Thermodynamics, Color.FromArgb(255, 100, 50) }, // Heat orange-red
{ ElementType.Time, Color.FromArgb(150, 100, 200) }, // Time purple
{ ElementType.Food, Color.FromArgb(200, 150, 100) }, // Food brown
{ ElementType.Eldritch, Color.FromArgb(100, 0, 150) } // Eldritch purple-black
};
// Card type colors
@@ -123,11 +123,11 @@ public static class PlaceholderGenerator
generated++;
}
// Generate type-only placeholders (generic element - Fire)
// Generate type-only placeholders (generic element - Radioactivity)
foreach (var type in cardTypes)
{
using var bitmap = GenerateCardPlaceholder(ElementType.Fire, type, type.ToString());
var filename = Path.Combine(outputDirectory, $"{type}_fire.png");
using var bitmap = GenerateCardPlaceholder(ElementType.Radioactivity, type, type.ToString());
var filename = Path.Combine(outputDirectory, $"{type}_radioactivity.png");
bitmap.Save(filename, ImageFormat.Png);
generated++;
}
@@ -63,14 +63,14 @@ public enum TargetType
/// </summary>
public enum ElementType
{
Fire,
Water,
Earth,
Air,
Light,
Dark,
Arcane,
Nature
Radioactivity,
Flesh,
Toxin,
Fungus,
Thermodynamics,
Time,
Food,
Eldritch
}
/// <summary>
@@ -37,20 +37,23 @@ public class CardCombiner
{
private readonly Random _random = new();
// Elemental synergy bonuses
// Elemental synergy bonuses - new elements have thematic relationships
private static readonly Dictionary<(ElementType, ElementType), string> ElementSynergies = new()
{
{ (ElementType.Fire, ElementType.Air), "Explosive" },
{ (ElementType.Fire, ElementType.Water), "Steam" },
{ (ElementType.Fire, ElementType.Earth), "Magma" },
{ (ElementType.Water, ElementType.Earth), "Nature" },
{ (ElementType.Water, ElementType.Air), "Storm" },
{ (ElementType.Earth, ElementType.Air), "Dust" },
{ (ElementType.Light, ElementType.Dark), "Twilight" },
{ (ElementType.Light, ElementType.Arcane), "Cosmic" },
{ (ElementType.Dark, ElementType.Arcane), "Void" },
{ (ElementType.Nature, ElementType.Water), "Life" },
{ (ElementType.Nature, ElementType.Fire), "Wildfire" },
{ (ElementType.Radioactivity, ElementType.Toxin), "Contaminated" },
{ (ElementType.Radioactivity, ElementType.Flesh), "Mutated" },
{ (ElementType.Radioactivity, ElementType.Fungus), "Irradiated Growth" },
{ (ElementType.Flesh, ElementType.Fungus), "Necrotic" },
{ (ElementType.Flesh, ElementType.Toxin), "Virulent" },
{ (ElementType.Toxin, ElementType.Fungus), "Bioluminescent" },
{ (ElementType.Thermodynamics, ElementType.Radioactivity), "Fusion" },
{ (ElementType.Thermodynamics, ElementType.Time), "Entropy" },
{ (ElementType.Time, ElementType.Eldritch), "Cosmic" },
{ (ElementType.Food, ElementType.Flesh), "Sustenance" },
{ (ElementType.Food, ElementType.Fungus), "Fermented" },
{ (ElementType.Eldritch, ElementType.Flesh), "Abominable" },
{ (ElementType.Eldritch, ElementType.Time), "Beyond Time" },
{ (ElementType.Eldritch, ElementType.Radioactivity), "Void Radiation" },
};
// Combination efficiency - results are better than either card alone but not 100% of both
@@ -630,32 +633,26 @@ public class CardCombiner
{
var result = new CombinationResult();
// Create enhanced version of the normal card
var enhancedCard = normalCard.Clone();
enhancedCard.Name = $"Enhanced {normalCard.Name}";
enhancedCard.Description = $"{normalCard.Description} Infused with extra power from blank essence!";
// Add random bonus based on blank's element (using efficiency)
var bonus = _random.Next(1, 3);
if (enhancedCard.Type == CardType.Creature)
{
// Creature gets power and health boost
enhancedCard.Power += bonus;
enhancedCard.Health += bonus;
}
else if (enhancedCard.Type == CardType.Spell)
{
// Spell gets power boost
enhancedCard.Power += bonus + 1;
}
else if (enhancedCard.Type == CardType.Artifact)
{
// Artifact gets power boost
enhancedCard.Power += bonus + 1;
}
// Add blank's infusion effect as extra
enhancedCard.Effects.Add(new CardEffect
{
Name = "Blank Infusion",
@@ -739,18 +736,21 @@ public class CardCombiner
{
return synergy switch
{
"Explosive" => ElementType.Fire,
"Steam" => ElementType.Water,
"Magma" => ElementType.Fire,
"Nature" => ElementType.Nature,
"Storm" => ElementType.Water,
"Dust" => ElementType.Earth,
"Twilight" => ElementType.Dark,
"Cosmic" => ElementType.Arcane,
"Void" => ElementType.Dark,
"Life" => ElementType.Nature,
"Wildfire" => ElementType.Fire,
_ => ElementType.Arcane
"Contaminated" => ElementType.Radioactivity,
"Mutated" => ElementType.Flesh,
"Irradiated Growth" => ElementType.Fungus,
"Necrotic" => ElementType.Fungus,
"Virulent" => ElementType.Toxin,
"Bioluminescent" => ElementType.Fungus,
"Fusion" => ElementType.Thermodynamics,
"Entropy" => ElementType.Time,
"Cosmic" => ElementType.Eldritch,
"Sustenance" => ElementType.Food,
"Fermented" => ElementType.Food,
"Abominable" => ElementType.Eldritch,
"Beyond Time" => ElementType.Eldritch,
"Void Radiation" => ElementType.Radioactivity,
_ => ElementType.Eldritch
};
}
@@ -0,0 +1,668 @@
using Card = MagicalDeckbuilder.Cards.Card;
using CardType = MagicalDeckbuilder.Cards.CardType;
using ElementType = MagicalDeckbuilder.Cards.ElementType;
using EffectType = MagicalDeckbuilder.Cards.EffectType;
using TargetType = MagicalDeckbuilder.Cards.TargetType;
using MagicalDeckbuilder.Cards;
namespace MagicalDeckbuilder.Game;
/// <summary>
/// Factory for creating game cards
/// </summary>
public static class CardFactory
{
/// <summary>
/// Create a starter deck with a variety of cards from all elements
/// </summary>
public static List<Card> CreateStarterDeck()
{
var deck = new List<Card>();
// Add 15 cards per element
deck.AddRange(CreateRadioactivityDeck());
deck.AddRange(CreateFleshDeck());
deck.AddRange(CreateToxinDeck());
deck.AddRange(CreateFungusDeck());
deck.AddRange(CreateThermodynamicsDeck());
deck.AddRange(CreateTimeDeck());
deck.AddRange(CreateFoodDeck());
deck.AddRange(CreateEldritchDeck());
return deck;
}
// ============ RADIOACTIVITY (15 cards) ============
private static List<Card> CreateRadioactivityDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Radiated Cockroach", "A mutated insect that thrives in radiation",
ElementType.Radioactivity, 1, 1, 2, 1));
deck.Add(CreateCreature("Glowing Slime", "A luminescent puddle of radioactive ooze",
ElementType.Radioactivity, 2, 2, 3, 1));
deck.Add(CreateCreature("Nuclear Hulk", "A massive creature fused with radioactive material",
ElementType.Radioactivity, 5, 6, 8, 3));
// 2 Spells
deck.Add(CreateSpell("Radiation Burst", "Unleash a wave of harmful radiation",
ElementType.Radioactivity, 3, 4, EffectType.Damage, TargetType.Enemy));
deck.Add(CreateSpell("Contamination", "Spread radioactive toxins",
ElementType.Radioactivity, 4, 3, EffectType.Debuff, TargetType.Enemy));
// 2 Artifacts
deck.Add(CreateArtifact("Uranium Core", "A glowing chunk of enriched uranium",
ElementType.Radioactivity, 3));
deck.Add(CreateArtifact("Radiation Shield", "Protection from harmful radiation",
ElementType.Radioactivity, 2));
// 1 Event
deck.Add(CreateEvent("Meltdown", "A catastrophic nuclear event",
ElementType.Radioactivity, 5, 8));
// 1 Blank
deck.Add(CreateBlank("Raw Isotope", "Unrefined radioactive material",
ElementType.Radioactivity, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Glowing Aura", "An eerie glow surrounds creatures",
ElementType.Radioactivity, 2));
deck.Add(CreateEnchantment("Mutation Seed", "Plants absorb radiation and mutate",
ElementType.Radioactivity, 3));
deck.Add(CreateEnchantment("Nuclear Winter", "Fallout spreads across the land",
ElementType.Radioactivity, 4));
// 3 Weapons
deck.Add(CreateWeapon("Plutonium Dagger", "A blade laced with radioactive material",
ElementType.Radioactivity, 2, 3));
deck.Add(CreateWeapon("Gamma Ray Gun", "Fires concentrated gamma radiation",
ElementType.Radioactivity, 4, 5));
deck.Add(CreateWeapon("Atomic Hammer", "Channels nuclear energy into devastating strikes",
ElementType.Radioactivity, 6, 7));
return deck;
}
// ============ FLESH (15 cards) ============
private static List<Card> CreateFleshDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Living Corpse", "A reanimated body without a soul",
ElementType.Flesh, 2, 2, 4, 1));
deck.Add(CreateCreature("Horror Maw", "A massive mouth with countless teeth",
ElementType.Flesh, 4, 5, 5, 2));
deck.Add(CreateCreature("Bone Titan", "A giant assembled from countless bones",
ElementType.Flesh, 6, 7, 7, 3));
// 2 Spells
deck.Add(CreateSpell("Cannibalize", "Consume flesh to restore health",
ElementType.Flesh, 2, 4, EffectType.Heal, TargetType.Self));
deck.Add(CreateSpell("Flay", "Tear flesh from bone",
ElementType.Flesh, 3, 5, EffectType.Damage, TargetType.Enemy));
// 2 Artifacts
deck.Add(CreateArtifact("Preserved Heart", "A still-beating heart that never stops",
ElementType.Flesh, 3));
deck.Add(CreateArtifact("Skin Cloak", "A cloak made from living skin",
ElementType.Flesh, 2));
// 1 Event
deck.Add(CreateEvent("Epidemic", "A plague spreads through the land",
ElementType.Flesh, 4, 6));
// 1 Blank
deck.Add(CreateBlank("Meat Chunk", "A lump of undifferentiated flesh",
ElementType.Flesh, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Regeneration", "Flesh knits itself back together",
ElementType.Flesh, 2));
deck.Add(CreateEnchantment("Parasitic Bond", "A parasite feeds off the host",
ElementType.Flesh, 3));
deck.Add(CreateEnchantment("Body Horror", "Transform into a nightmare form",
ElementType.Flesh, 4));
// 3 Weapons
deck.Add(CreateWeapon("Bone Blade", "A sword crafted from sharpened bones",
ElementType.Flesh, 2, 3));
deck.Add(CreateWeapon("Flesh Ripper", "Hooks designed to tear flesh",
ElementType.Flesh, 3, 4));
deck.Add(CreateWeapon("Skull Crusher", "A massive hammer topped with skulls",
ElementType.Flesh, 5, 6));
return deck;
}
// ============ TOXIN (15 cards) ============
private static List<Card> CreateToxinDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Poison Dart Frog", "A small amphibian with deadly toxins",
ElementType.Toxin, 1, 1, 1, 1));
deck.Add(CreateCreature("Venomous Snake", "A serpent with potent venom",
ElementType.Toxin, 2, 3, 2, 1));
deck.Add(CreateCreature("Toxic Elemental", "A being made entirely of poison",
ElementType.Toxin, 4, 4, 4, 2));
// 2 Spells
deck.Add(CreateSpell("Poison Cloud", "Release a deadly miasma",
ElementType.Toxin, 3, 3, EffectType.Damage, TargetType.AllEnemies));
deck.Add(CreateSpell("Neurotoxin", "Attack the nervous system",
ElementType.Toxin, 4, 6, EffectType.Debuff, TargetType.Enemy));
// 2 Artifacts
deck.Add(CreateArtifact("Venom Vial", "A small bottle of concentrated toxin",
ElementType.Toxin, 2));
deck.Add(CreateArtifact("Antidote Charm", "Protects against poison effects",
ElementType.Toxin, 2));
// 1 Event
deck.Add(CreateEvent("Plague Outbreak", "A devastating sickness spreads",
ElementType.Toxin, 5, 7));
// 1 Blank
deck.Add(CreateBlank("Toxic Slime", "An unrefined toxic substance",
ElementType.Toxin, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Toxic Aura", "Poison seeps from the skin",
ElementType.Toxin, 2));
deck.Add(CreateEnchantment("Blighted Weapon", "Coat weapons in poison",
ElementType.Toxin, 3));
deck.Add(CreateEnchantment("Corrosive Mist", "Acid-like vapors fill the air",
ElementType.Toxin, 4));
// 3 Weapons
deck.Add(CreateWeapon("Poisoned Dagger", "A blade coated with toxin",
ElementType.Toxin, 1, 2));
deck.Add(CreateWeapon("Viper Fangs", "Fangs that inject venom",
ElementType.Toxin, 3, 3));
deck.Add(CreateWeapon("Toxic Cannon", "Fires globules of acid",
ElementType.Toxin, 5, 6));
return deck;
}
// ============ FUNGUS (15 cards) ============
private static List<Card> CreateFungusDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Spore Crawler", "A creature covered in fungus",
ElementType.Fungus, 2, 2, 3, 1));
deck.Add(CreateCreature("Mushroom Giant", "A massive fungal growth given life",
ElementType.Fungus, 4, 3, 6, 2));
deck.Add(CreateCreature("Mycotyx", "An ancient fungal horror",
ElementType.Fungus, 5, 4, 7, 3));
// 2 Spells
deck.Add(CreateSpell("Spore Burst", "Release a cloud of fungal spores",
ElementType.Fungus, 3, 4, EffectType.Damage, TargetType.Enemy));
deck.Add(CreateSpell("Fungal Growth", "Accelerate fungal development",
ElementType.Fungus, 2, 3, EffectType.Heal, TargetType.Self));
// 2 Artifacts
deck.Add(CreateArtifact("Glowing Mushroom", "A bioluminescent fungus",
ElementType.Fungus, 2));
deck.Add(CreateArtifact("Fungal Network", "Connects to a vast fungal mind",
ElementType.Fungus, 3));
// 1 Event
deck.Add(CreateEvent("Bloom", "Fungi spread rapidly",
ElementType.Fungus, 3, 5));
// 1 Blank
deck.Add(CreateBlank("Fungal Spore", "A single, undifferentiated spore",
ElementType.Fungus, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Mycological Bond", "Connected through the fungal network",
ElementType.Fungus, 2));
deck.Add(CreateEnchantment("Hallucinogenic Aura", "Spores cause vivid hallucinations",
ElementType.Fungus, 3));
deck.Add(CreateEnchantment("Decomposition", "Breaking down organic matter",
ElementType.Fungus, 4));
// 3 Weapons
deck.Add(CreateWeapon("Mushroom Staff", "A staff topped with fungal growth",
ElementType.Fungus, 2, 2));
deck.Add(CreateWeapon("Spore Launcher", "Fires concentrated fungal projectiles",
ElementType.Fungus, 3, 4));
deck.Add(CreateWeapon("Fungal Scythe", "A blade that spreads infection",
ElementType.Fungus, 4, 5));
return deck;
}
// ============ THERMODYNAMICS (15 cards) ============
private static List<Card> CreateThermodynamicsDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Flame Imp", "A small being of pure heat",
ElementType.Thermodynamics, 1, 2, 1, 1));
deck.Add(CreateCreature("Ice Elemental", "A frozen construct of ice",
ElementType.Thermodynamics, 3, 3, 4, 1));
deck.Add(CreateCreature("Heat Monster", "A creature that feeds on fire",
ElementType.Thermodynamics, 4, 5, 5, 2));
// 2 Spells
deck.Add(CreateSpell("Absolute Zero", "Freeze to near absolute zero",
ElementType.Thermodynamics, 4, 7, EffectType.Damage, TargetType.Enemy));
deck.Add(CreateSpell("Heat Wave", "Unleash scorching temperatures",
ElementType.Thermodynamics, 3, 5, EffectType.Damage, TargetType.Enemy));
// 2 Artifacts
deck.Add(CreateArtifact("Thermal Core", "A reactor that generates heat",
ElementType.Thermodynamics, 3));
deck.Add(CreateArtifact("Heat Sink", "Absorbs and dissipates thermal energy",
ElementType.Thermodynamics, 2));
// 1 Event
deck.Add(CreateEvent("Supernova", "A stellar explosion",
ElementType.Thermodynamics, 6, 10));
// 1 Blank
deck.Add(CreateBlank("Thermal Mass", "Raw thermal energy",
ElementType.Thermodynamics, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Temperature Control", "Manipulate ambient temperature",
ElementType.Thermodynamics, 2));
deck.Add(CreateEnchantment("Heat Absorption", "Drawing heat from surroundings",
ElementType.Thermodynamics, 3));
deck.Add(CreateEnchantment("Entropy Field", "Increased entropy in the area",
ElementType.Thermodynamics, 4));
// 3 Weapons
deck.Add(CreateWeapon("Plasma Torch", "A weapon that burns with plasma",
ElementType.Thermodynamics, 2, 4));
deck.Add(CreateWeapon("Cryo Cannon", "Freezes targets with extreme cold",
ElementType.Thermodynamics, 4, 4));
deck.Add(CreateWeapon("Thermal Lance", "Channels focused thermal energy",
ElementType.Thermodynamics, 5, 7));
return deck;
}
// ============ TIME (15 cards) ============
private static List<Card> CreateTimeDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Temporal Wisp", "A ghostly being out of time",
ElementType.Time, 2, 2, 2, 1));
deck.Add(CreateCreature("Elder Chronos", "An ancient being of time",
ElementType.Time, 5, 4, 5, 3));
deck.Add(CreateCreature("Time Loop", "A creature trapped in recursion",
ElementType.Time, 3, 3, 4, 2));
// 2 Spells
deck.Add(CreateSpell("Time Stop", "Freeze time for all but the caster",
ElementType.Time, 5, 0, EffectType.Debuff, TargetType.AllEnemies));
deck.Add(CreateSpell("Accelerate", "Speed up the target",
ElementType.Time, 2, 3, EffectType.Buff, TargetType.Self));
// 2 Artifacts
deck.Add(CreateArtifact("Hourglass of Eternity", "An artifact that controls time",
ElementType.Time, 4));
deck.Add(CreateArtifact("Temporal Anchor", "Keeps the bearer in the present",
ElementType.Time, 3));
// 1 Event
deck.Add(CreateEvent("Temporal Rift", "A rupture in the time stream",
ElementType.Time, 5, 8));
// 1 Blank
deck.Add(CreateBlank("Temporal Shard", "A fragment of frozen time",
ElementType.Time, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Time Dilation", "Time moves slower for the enchanted",
ElementType.Time, 2));
deck.Add(CreateEnchantment("Precognition", "See slightly into the future",
ElementType.Time, 3));
deck.Add(CreateEnchantment("Age Acceleration", "Rapidly age the target",
ElementType.Time, 4));
// 3 Weapons
deck.Add(CreateWeapon("Chrono Blade", "A sword that cuts through time",
ElementType.Time, 3, 4));
deck.Add(CreateWeapon("Temporal Bow", "Arrows that skip through time",
ElementType.Time, 3, 5));
deck.Add(CreateWeapon("Minute Glass", "A weapon that ages enemies",
ElementType.Time, 4, 4));
return deck;
}
// ============ FOOD (15 cards) ============
private static List<Card> CreateFoodDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Gorging Goblin", "A gluttonous creature",
ElementType.Food, 2, 3, 3, 1));
deck.Add(CreateCreature("Living Kitchen", "A sentient cooking apparatus",
ElementType.Food, 3, 2, 5, 1));
deck.Add(CreateCreature("Famine Beast", "A horror that devours all",
ElementType.Food, 5, 6, 6, 3));
// 2 Spells
deck.Add(CreateSpell("Feast", "A bountiful meal restores health",
ElementType.Food, 2, 5, EffectType.Heal, TargetType.Self));
deck.Add(CreateSpell("Starve", "Deprive the target of food",
ElementType.Food, 3, 4, EffectType.Debuff, TargetType.Enemy));
// 2 Artifacts
deck.Add(CreateArtifact("Endless Pantry", "Never runs out of food",
ElementType.Food, 3));
deck.Add(CreateArtifact("Cursed Cauldron", "A pot that cooks up misfortune",
ElementType.Food, 2));
// 1 Event
deck.Add(CreateEvent("Banquet", "A grand feast for all",
ElementType.Food, 3, 6));
// 1 Blank
deck.Add(CreateBlank("Raw Ingredient", "An unprocessed food item",
ElementType.Food, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Rotting Touch", "Food spoils at your command",
ElementType.Food, 2));
deck.Add(CreateEnchantment("Sugar Rush", "Temporary energy from sweets",
ElementType.Food, 2));
deck.Add(CreateEnchantment("Satisfaction", "Well-fed creatures fight harder",
ElementType.Food, 3));
// 3 Weapons
deck.Add(CreateWeapon("Cooking Knife", "Sharp enough to slice anything",
ElementType.Food, 1, 3));
deck.Add(CreateWeapon("Cleaver", "A massive blade for chopping",
ElementType.Food, 3, 4));
deck.Add(CreateWeapon("Spear of Sustenance", "A weapon that nourishes the wielder",
ElementType.Food, 4, 5));
return deck;
}
// ============ ELDRITCH (15 cards) ============
private static List<Card> CreateEldritchDeck()
{
var deck = new List<Card>();
// 3 Creatures
deck.Add(CreateCreature("Cultist", "A follower of ancient horrors",
ElementType.Eldritch, 1, 1, 2, 1));
deck.Add(CreateCreature("Void Spawn", "A creature from beyond the veil",
ElementType.Eldritch, 3, 4, 3, 2));
deck.Add(CreateCreature("Eldritch Horror", "A being of incomprehensible power",
ElementType.Eldritch, 6, 8, 8, 4, true));
// 2 Spells
deck.Add(CreateSpell("Unspeakable Pact", "A contract with entities unknown",
ElementType.Eldritch, 4, 5, EffectType.Damage, TargetType.Enemy));
deck.Add(CreateSpell("Sanity Erosion", "Slowly break down mental defenses",
ElementType.Eldritch, 3, 4, EffectType.Debuff, TargetType.Enemy));
// 2 Artifacts
deck.Add(CreateArtifact("Madness Tome", "A book of forbidden knowledge",
ElementType.Eldritch, 3));
deck.Add(CreateArtifact("Eldritch Sigil", "A symbol of cosmic horror",
ElementType.Eldritch, 2));
// 1 Event
deck.Add(CreateEvent("The Stars Align", "Cosmic alignment triggers apocalypse",
ElementType.Eldritch, 6, 9));
// 1 Blank
deck.Add(CreateBlank("Chaos Shard", "A fragment of pure chaos",
ElementType.Eldritch, 1));
// 3 Enchantments
deck.Add(CreateEnchantment("Dark Whispers", "Voices from beyond",
ElementType.Eldritch, 2));
deck.Add(CreateEnchantment("Eye of Madness", "See through the veil of reality",
ElementType.Eldritch, 3));
deck.Add(CreateEnchantment("Void Touched", "Marked by the void",
ElementType.Eldritch, 4));
// 3 Weapons
deck.Add(CreateWeapon("Tentacle Whip", "A writhing appendage of flesh",
ElementType.Eldritch, 2, 3));
deck.Add(CreateWeapon("Starfire Staff", "Channels eldritch energies",
ElementType.Eldritch, 4, 5));
deck.Add(CreateWeapon("Cosmic Blade", "A sword of stellar matter",
ElementType.Eldritch, 5, 7));
return deck;
}
// ============ CARD CREATION HELPERS ============
private static Card CreateCreature(string name, string description,
ElementType element, int manaCost, int power, int health, int rarity = 1, bool isLegendary = false)
{
return new CreatureCard
{
Name = name,
Description = description,
Element = element,
ManaCost = manaCost,
Power = power,
Health = health,
Rarity = rarity,
IsLegendary = isLegendary,
Effects = new List<CardEffect>
{
new CardEffect
{
Name = "Attack",
Description = "Can attack each turn",
Type = EffectType.Damage,
Value = power,
Target = TargetType.Enemy
}
}
};
}
private static Card CreateSpell(string name, string description,
ElementType element, int manaCost, int power, EffectType effectType, TargetType target)
{
var spell = new SpellCard
{
Name = name,
Description = description,
Element = element,
ManaCost = manaCost,
Power = power,
Rarity = 1
};
if (power > 0)
{
spell.Effects.Add(new CardEffect
{
Name = effectType.ToString(),
Description = description,
Type = effectType,
Value = power,
Target = target
});
}
else
{
spell.Effects.Add(new CardEffect
{
Name = "Effect",
Description = description,
Type = effectType,
Value = 1,
Target = target
});
}
return spell;
}
private static Card CreateArtifact(string name, string description,
ElementType element, int manaCost)
{
return new ArtifactCard
{
Name = name,
Description = description,
Element = element,
ManaCost = manaCost,
Rarity = 1
};
}
private static Card CreateEnchantment(string name, string description,
ElementType element, int manaCost)
{
return new Card
{
Name = name,
Description = description,
Type = CardType.Enchantment,
Element = element,
ManaCost = manaCost,
Rarity = 1,
Power = 0,
Effects = new List<CardEffect>
{
new CardEffect
{
Name = "Enchant",
Description = description,
Type = EffectType.Buff,
Value = 1,
Target = TargetType.Self
}
}
};
}
private static Card CreateWeapon(string name, string description,
ElementType element, int manaCost, int power)
{
return new Card
{
Name = name,
Description = description,
Type = CardType.Weapon,
Element = element,
ManaCost = manaCost,
Power = power,
Rarity = 1,
Effects = new List<CardEffect>
{
new CardEffect
{
Name = "Strike",
Description = description,
Type = EffectType.Damage,
Value = power,
Target = TargetType.Enemy
}
}
};
}
private static Card CreateEvent(string name, string description,
ElementType element, int manaCost, int effectValue)
{
var eventCard = new EventCard
{
Name = name,
Description = description,
Element = element,
ManaCost = manaCost,
Rarity = 1,
Power = effectValue
};
if (name.Contains("Meltdown") || name.Contains("Supernova"))
{
eventCard.Effects.Add(new CardEffect
{
Name = "Destruction",
Description = "Massive damage to all",
Type = EffectType.Damage,
Value = effectValue,
Target = TargetType.AllEnemies
});
}
else
{
eventCard.Effects.Add(new CardEffect
{
Name = "Event",
Description = description,
Type = EffectType.Damage,
Value = effectValue,
Target = TargetType.Any
});
}
return eventCard;
}
private static Card CreateBlank(string name, string description,
ElementType element, int manaCost)
{
var blank = new BlankCard
{
Name = name,
Description = description,
Element = element,
ManaCost = manaCost,
Rarity = 1,
Power = 1
};
blank.Effects.Add(new CardEffect
{
Name = "Infusion",
Description = "Can be used to enhance other cards",
Type = EffectType.Buff,
Value = 1,
Target = TargetType.Self
});
return blank;
}
/// <summary>
/// Generate a random deck of cards
/// </summary>
public static List<Card> GenerateRandomDeck()
{
var random = new Random();
var deck = new List<Card>();
int deckSize = random.Next(11, 20);
var allCards = CreateStarterDeck();
for (int i = 0; i < deckSize; i++)
{
int cardIndex = random.Next(allCards.Count);
deck.Add(allCards[cardIndex].Clone());
}
return deck;
}
}
@@ -109,13 +109,13 @@ public class Game
Console.WriteLine();
// Initialize player deck
var playerDeck = CardFactory.CreateSimpleDeck();
var playerDeck = CardFactory.CreateStarterDeck();
_player.Deck.InitializeDeck(playerDeck);
_player.MaxMana = 1;
_player.Mana = _player.MaxMana;
// Initialize opponent deck (slightly different for variety)
var opponentDeck = CardFactory.CreateSimpleDeck();
var opponentDeck = CardFactory.CreateStarterDeck();
_opponent.Deck.InitializeDeck(opponentDeck);
_opponent.MaxMana = 1;
_opponent.Mana = _opponent.MaxMana;
@@ -1,11 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<OutputType>Library</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
@@ -6,12 +6,12 @@
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v9.0": {
"NewGame/1.0.0": {
"MagicalDeckbuilder.Shared/1.0.0": {
"dependencies": {
"System.Drawing.Common": "8.0.0"
},
"runtime": {
"NewGame.dll": {}
"MagicalDeckbuilder.Shared.dll": {}
}
},
"Microsoft.Win32.SystemEvents/8.0.0": {
@@ -44,7 +44,7 @@
}
},
"libraries": {
"NewGame/1.0.0": {
"MagicalDeckbuilder.Shared/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
@@ -0,0 +1,24 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("MagicalDeckbuilder.Shared")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d5073c68dcd5981e22422ad7275ef44dc903062a")]
[assembly: System.Reflection.AssemblyProductAttribute("MagicalDeckbuilder.Shared")]
[assembly: System.Reflection.AssemblyTitleAttribute("MagicalDeckbuilder.Shared")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
1bbc97d5cfd5c17cb873a2ade8253ae30cda79087561d7a203001675eb2934c1
@@ -1,10 +1,4 @@
is_global = true
build_property.ApplicationManifest =
build_property.StartupObject =
build_property.ApplicationDefaultFont =
build_property.ApplicationHighDpiMode =
build_property.ApplicationUseCompatibleTextRendering =
build_property.ApplicationVisualStyles =
build_property.TargetFramework = net9.0-windows
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
@@ -13,8 +7,8 @@ build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = NewGame
build_property.ProjectDir = C:\Users\atw61\OneDrive\Desktop\new\NewGame\
build_property.RootNamespace = MagicalDeckbuilder.Shared
build_property.ProjectDir = C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
@@ -0,0 +1 @@
3ccf4ba1804fdf912b12f1ab652c52eb68725958a9fd8dd99a1ae306782e960a
@@ -0,0 +1,13 @@
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\bin\Debug\net9.0-windows\MagicalDeckbuilder.Shared.deps.json
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\bin\Debug\net9.0-windows\MagicalDeckbuilder.Shared.dll
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\bin\Debug\net9.0-windows\MagicalDeckbuilder.Shared.pdb
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.csproj.AssemblyReference.cache
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.GeneratedMSBuildEditorConfig.editorconfig
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.AssemblyInfoInputs.cache
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.AssemblyInfo.cs
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.csproj.CoreCompileInputs.cache
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.sourcelink.json
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.dll
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\refint\MagicalDeckbuilder.Shared.dll
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\MagicalDeckbuilder.Shared.pdb
C:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\obj\Debug\net9.0-windows\ref\MagicalDeckbuilder.Shared.dll
@@ -0,0 +1 @@
{"documents":{"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\*":"https://raw.githubusercontent.com/alexandria121/new/d5073c68dcd5981e22422ad7275ef44dc903062a/*"}}
@@ -1,17 +1,17 @@
{
"format": 1,
"restore": {
"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\NewGame.csproj": {}
"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\MagicalDeckbuilder.Shared.csproj": {}
},
"projects": {
"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\NewGame.csproj": {
"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\MagicalDeckbuilder.Shared.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\NewGame.csproj",
"projectName": "NewGame",
"projectPath": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\NewGame.csproj",
"projectUniqueName": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\MagicalDeckbuilder.Shared.csproj",
"projectName": "MagicalDeckbuilder.Shared",
"projectPath": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\MagicalDeckbuilder.Shared.csproj",
"packagesPath": "C:\\Users\\atw61\\.nuget\\packages\\",
"outputPath": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\obj\\",
"outputPath": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\atw61\\AppData\\Roaming\\NuGet\\NuGet.Config"
@@ -63,9 +63,6 @@
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
},
"Microsoft.WindowsDesktop.App.WindowsForms": {
"privateAssets": "none"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.312/PortableRuntimeIdentifierGraph.json"
@@ -133,11 +133,11 @@
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "c:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\NewGame.csproj",
"projectName": "NewGame",
"projectPath": "c:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\NewGame.csproj",
"projectUniqueName": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\MagicalDeckbuilder.Shared.csproj",
"projectName": "MagicalDeckbuilder.Shared",
"projectPath": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\MagicalDeckbuilder.Shared.csproj",
"packagesPath": "C:\\Users\\atw61\\.nuget\\packages\\",
"outputPath": "c:\\Users\\atw61\\OneDrive\\Desktop\\new\\NewGame\\obj\\",
"outputPath": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\atw61\\AppData\\Roaming\\NuGet\\NuGet.Config"
@@ -189,9 +189,6 @@
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
},
"Microsoft.WindowsDesktop.App.WindowsForms": {
"privateAssets": "none"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.312/PortableRuntimeIdentifierGraph.json"
@@ -0,0 +1,11 @@
{
"version": 2,
"dgSpecHash": "hoVgv1ibtF4=",
"success": true,
"projectFilePath": "C:\\Users\\atw61\\OneDrive\\Desktop\\new\\MagicalDeckbuilder.Shared\\MagicalDeckbuilder.Shared.csproj",
"expectedPackageFiles": [
"C:\\Users\\atw61\\.nuget\\packages\\microsoft.win32.systemevents\\8.0.0\\microsoft.win32.systemevents.8.0.0.nupkg.sha512",
"C:\\Users\\atw61\\.nuget\\packages\\system.drawing.common\\8.0.0\\system.drawing.common.8.0.0.nupkg.sha512"
],
"logs": []
}
+26
View File
@@ -0,0 +1,26 @@
<Application x:Class="NewGame.UI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NewGame.UI"
xmlns:Converters="clr-namespace:NewGame.UI.Converters">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/BaseStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<Converters:InverseBoolToVisibilityConverter x:Key="InverseBoolToVisibilityConverter"/>
<Converters:NotMenuToVisibilityConverter x:Key="NotMenuToVisibilityConverter"/>
<Converters:TypeToColorConverter x:Key="TypeToColorConverter"/>
<Converters:ElementToColorConverter x:Key="ElementToColorConverter"/>
<Converters:RarityToColorConverter x:Key="RarityToColorConverter"/>
<Converters:IsCreatureConverter x:Key="IsCreatureConverter"/>
<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
<Converters:EmptyToVisibilityConverter x:Key="EmptyToVisibilityConverter"/>
<Converters:BoolToTurnTextConverter x:Key="BoolToTurnTextConverter"/>
<Converters:BoolToTurnColorConverter x:Key="BoolToTurnColorConverter"/>
<Converters:StringEqualityToVisibilityConverter x:Key="StringEqualityToVisibilityConverter"/>
</ResourceDictionary>
</Application.Resources>
</Application>
+12 -20
View File
@@ -1,32 +1,25 @@
using System.Windows.Forms;
using System.IO;
using System.Windows;
using MagicalDeckbuilder.Assets;
using MagicalDeckbuilder.Cards;
using MagicalDeckbuilder.Game;
using MagicalDeckbuilder.UI;
using Card = MagicalDeckbuilder.Cards.Card;
namespace MagicalDeckbuilder;
namespace NewGame.UI;
public static class Program
public partial class App : Application
{
[STAThread]
public static void Main()
protected override void OnStartup(StartupEventArgs e)
{
// First, generate placeholder images if they don't exist
base.OnStartup(e);
// Generate placeholder images if they don't exist
var baseDir = AppContext.BaseDirectory;
// Save to bin directory for easier access from WinForms
var placeholdersDir = Path.Combine(baseDir, "Assets", "Placeholders");
if (!Directory.Exists(placeholdersDir) || !Directory.GetFiles(placeholdersDir, "*.png").Any())
{
Console.WriteLine("=== GENERATING PLACEHOLDER GRAPHICS ===\n");
// Ensure directory exists
Directory.CreateDirectory(placeholdersDir);
PlaceholderGenerator.GenerateAllPlaceholders(placeholdersDir);
var squaresDir = Path.Combine(placeholdersDir, "Squares");
PlaceholderGenerator.GenerateSimpleSquares(squaresDir);
Console.WriteLine();
@@ -34,11 +27,10 @@ public static class Program
}
// Generate some sample cards for display
var newCards = CardFactory.GenerateNewCards();
var newCards = CardFactory.CreateStarterDeck();
Console.WriteLine($"Generated {newCards.Count} sample cards\n");
// Run the WinForms application - start with the menu
ApplicationConfiguration.Initialize();
Application.Run(new MenuForm());
var mainWindow = new MainWindow();
mainWindow.Show();
}
}
+10
View File
@@ -0,0 +1,10 @@
using System.Windows;
[assembly:ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
+125
View File
@@ -0,0 +1,125 @@
<UserControl x:Class="NewGame.UI.Controls.CardControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Converters="clr-namespace:NewGame.UI.Converters"
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="140"
MouseLeftButtonDown="OnCardClick"
MouseMove="OnCardMouseMove"
MouseLeftButtonUp="OnCardMouseUp"
Tag="{Binding}">
<Border x:Name="CardBorder"
Background="{Binding Type, Converter={StaticResource TypeToColorConverter}}"
BorderThickness="3"
CornerRadius="8"
Padding="6"
Cursor="Hand">
<Border.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="2" Opacity="0.5"/>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Name & Mana Cost -->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"
FontSize="11"
FontWeight="Bold"
Foreground="White"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center"
Margin="0,0,4,0"/>
<Border Grid.Column="1"
Background="#1E64C8"
CornerRadius="10"
Padding="6,2"
VerticalAlignment="Center">
<TextBlock Text="{Binding ManaCost}"
FontSize="12"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
</Border>
</Grid>
<!-- Card Art Area -->
<Border Grid.Row="1"
Background="{Binding Element, Converter={StaticResource ElementToColorConverter}}"
CornerRadius="4"
Margin="0,6,0,6"
Height="70">
<TextBlock Text="{Binding Type}"
FontSize="12"
FontStyle="Italic"
Foreground="#80FFFFFF"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<!-- Stats -->
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
Visibility="{Binding Type, Converter={StaticResource IsCreatureConverter}}">
<TextBlock Text="PWR:" Foreground="#FF9632" FontSize="10"/>
<TextBlock Text="{Binding Power}" Foreground="#FF9632" FontSize="10" FontWeight="Bold"/>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
HorizontalAlignment="Right"
Visibility="{Binding Type, Converter={StaticResource IsCreatureConverter}}">
<TextBlock Text="HP:" Foreground="#64FF64" FontSize="10"/>
<TextBlock Text="{Binding Health}" Foreground="#64FF64" FontSize="10" FontWeight="Bold"/>
</StackPanel>
</Grid>
<!-- Element & Rarity -->
<Grid Grid.Row="3" Margin="0,4,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Element}"
FontSize="9"
Foreground="#B0B0B0"/>
<TextBlock Grid.Column="1"
Text="{Binding RarityText}"
FontSize="9"
Foreground="{Binding Rarity, Converter={StaticResource RarityToColorConverter}}"
FontWeight="Bold"/>
</Grid>
</Grid>
</Border>
<UserControl.Resources>
<Converters:TypeToColorConverter x:Key="TypeToColorConverter"/>
<Converters:ElementToColorConverter x:Key="ElementToColorConverter"/>
<Converters:RarityToColorConverter x:Key="RarityToColorConverter"/>
<Converters:IsCreatureConverter x:Key="IsCreatureConverter"/>
</UserControl.Resources>
</UserControl>
+79
View File
@@ -0,0 +1,79 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using NewGame.UI.ViewModels;
namespace NewGame.UI.Controls;
public partial class CardControl : UserControl
{
public static readonly RoutedEvent CardDroppedEvent = EventManager.RegisterRoutedEvent(
"CardDropped", RoutingStrategy.Bubble, typeof(EventHandler<CardDroppedEventArgs>), typeof(CardControl));
public event EventHandler<CardDroppedEventArgs> CardDropped
{
add { AddHandler(CardDroppedEvent, value); }
remove { RemoveHandler(CardDroppedEvent, value); }
}
private Point _startPoint;
private bool _isDragging;
public CardControl()
{
InitializeComponent();
}
private void OnCardClick(object sender, MouseButtonEventArgs e)
{
if (DataContext is CardViewModel card)
{
card.IsSelected = !card.IsSelected;
}
}
private void OnCardMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed && !_isDragging)
{
var diff = e.GetPosition(this) - _startPoint;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
_isDragging = true;
if (DataContext is CardViewModel card)
{
card.IsDragging = true;
var data = new DataObject("CardViewModel", card);
DragDrop.DoDragDrop(this, data, DragDropEffects.Move);
card.IsDragging = false;
}
_isDragging = false;
}
}
}
private void OnCardMouseUp(object sender, MouseButtonEventArgs e)
{
_isDragging = false;
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
_startPoint = e.GetPosition(this);
base.OnMouseLeftButtonDown(e);
}
}
public class CardDroppedEventArgs : RoutedEventArgs
{
public CardViewModel Card { get; }
public int SlotIndex { get; }
public CardDroppedEventArgs(RoutedEvent routedEvent, CardViewModel card, int slotIndex)
: base(routedEvent)
{
Card = card;
SlotIndex = slotIndex;
}
}
+239
View File
@@ -0,0 +1,239 @@
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using CardType = MagicalDeckbuilder.Cards.CardType;
using ElementType = MagicalDeckbuilder.Cards.ElementType;
namespace NewGame.UI.Converters;
public class TypeToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is CardType type)
{
return type switch
{
CardType.Spell => new SolidColorBrush(Color.FromRgb(255, 100, 100)),
CardType.Creature => new SolidColorBrush(Color.FromRgb(100, 255, 100)),
CardType.Artifact => new SolidColorBrush(Color.FromRgb(200, 200, 100)),
CardType.Enchantment => new SolidColorBrush(Color.FromRgb(150, 100, 200)),
CardType.Weapon => new SolidColorBrush(Color.FromRgb(255, 150, 50)),
CardType.Armor => new SolidColorBrush(Color.FromRgb(100, 150, 200)),
CardType.Event => new SolidColorBrush(Color.FromRgb(255, 200, 100)),
CardType.Blank => new SolidColorBrush(Color.FromRgb(200, 200, 200)),
_ => new SolidColorBrush(Color.FromRgb(128, 128, 128))
};
}
return new SolidColorBrush(Color.FromRgb(128, 128, 128));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class ElementToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ElementType element)
{
return element switch
{
ElementType.Radioactivity => new SolidColorBrush(Color.FromRgb(0, 255, 100)),
ElementType.Flesh => new SolidColorBrush(Color.FromRgb(200, 100, 100)),
ElementType.Toxin => new SolidColorBrush(Color.FromRgb(150, 200, 0)),
ElementType.Fungus => new SolidColorBrush(Color.FromRgb(100, 150, 100)),
ElementType.Thermodynamics => new SolidColorBrush(Color.FromRgb(255, 100, 50)),
ElementType.Time => new SolidColorBrush(Color.FromRgb(150, 100, 200)),
ElementType.Food => new SolidColorBrush(Color.FromRgb(200, 150, 100)),
ElementType.Eldritch => new SolidColorBrush(Color.FromRgb(100, 0, 150)),
_ => new SolidColorBrush(Color.FromRgb(128, 128, 128))
};
}
return new SolidColorBrush(Color.FromRgb(128, 128, 128));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class RarityToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int rarity)
{
return rarity switch
{
1 => new SolidColorBrush(Color.FromRgb(180, 180, 180)),
2 => new SolidColorBrush(Color.FromRgb(100, 200, 100)),
3 => new SolidColorBrush(Color.FromRgb(50, 100, 200)),
4 => new SolidColorBrush(Color.FromRgb(200, 150, 50)),
_ => new SolidColorBrush(Color.FromRgb(128, 128, 128))
};
}
return new SolidColorBrush(Color.FromRgb(128, 128, 128));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class IsCreatureConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is CardType type)
{
return type == CardType.Creature ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool b)
{
return b ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class InverseBoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool b)
{
return b ? Visibility.Collapsed : Visibility.Visible;
}
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class BoolToTurnTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool isPlayerTurn)
{
return isPlayerTurn ? "Your Turn" : "Enemy Turn";
}
return "Unknown";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class BoolToTurnColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool isPlayerTurn)
{
return isPlayerTurn
? new SolidColorBrush(Color.FromRgb(76, 175, 80))
: new SolidColorBrush(Color.FromRgb(244, 67, 54));
}
return new SolidColorBrush(Color.FromRgb(128, 128, 128));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class NullToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value != null ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class EmptyToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int count)
{
return count == 0 ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class NotMenuToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string view)
{
return view == "Menu" ? Visibility.Collapsed : Visibility.Visible;
}
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class StringEqualityToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string str && parameter is string param)
{
return str == param ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
+113
View File
@@ -0,0 +1,113 @@
<Window x:Class="NewGame.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NewGame.UI"
xmlns:views="clr-namespace:NewGame.UI.Views"
xmlns:vm="clr-namespace:NewGame.UI.ViewModels"
xmlns:Converters="clr-namespace:NewGame.UI.Converters"
mc:Ignorable="d"
Title="Magical Deckbuilder"
Height="800" Width="1200"
MinHeight="600" MinWidth="900"
WindowStartupLocation="CenterScreen"
Background="{StaticResource BackgroundBrush}">
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Navigation Bar -->
<Border Grid.Row="0"
Background="{StaticResource SurfaceBrush}"
Padding="15,8"
Visibility="{Binding CurrentView, Converter={StaticResource NotMenuToVisibilityConverter}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<Button Content="Menu"
Style="{StaticResource BaseButtonStyle}"
Command="{Binding NavigateCommand}"
CommandParameter="Menu"
Padding="15,6"/>
<Button Content="Game"
Style="{StaticResource BaseButtonStyle}"
Command="{Binding NavigateCommand}"
CommandParameter="Game"
Margin="10,0,0,0"
Padding="15,6"/>
<Button Content="Cards"
Style="{StaticResource BaseButtonStyle}"
Command="{Binding NavigateCommand}"
CommandParameter="Browser"
Margin="10,0,0,0"
Padding="15,6"/>
</StackPanel>
<TextBlock Grid.Column="2"
Text="Magical Deckbuilder"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="12"
VerticalAlignment="Center"/>
</Grid>
</Border>
<!-- Main Content Area -->
<ContentControl Grid.Row="1">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding CurrentView}" Value="Menu">
<Setter Property="Content">
<Setter.Value>
<views:MenuView/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CurrentView}" Value="Game">
<Setter Property="Content">
<Setter.Value>
<views:GameView/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CurrentView}" Value="Browser">
<Setter Property="Content">
<Setter.Value>
<views:BrowserView/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CurrentView}" Value="DeckBuilder">
<Setter Property="Content">
<Setter.Value>
<views:DeckBuilderView/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CurrentView}" Value="Gallery">
<Setter Property="Content">
<Setter.Value>
<views:GalleryView/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
</Window>
+23
View File
@@ -0,0 +1,23 @@
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace NewGame.UI;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
+15
View File
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MagicalDeckbuilder.Shared\MagicalDeckbuilder.Shared.csproj" />
</ItemGroup>
</Project>
+153
View File
@@ -0,0 +1,153 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Dark Theme Colors -->
<Color x:Key="BackgroundColor">#1E1E28</Color>
<Color x:Key="SurfaceColor">#282830</Color>
<Color x:Key="SurfaceLightColor">#32323C</Color>
<Color x:Key="PrimaryColor">#4A9EFF</Color>
<Color x:Key="SecondaryColor">#2D2D3A</Color>
<Color x:Key="AccentColor">#FF6B35</Color>
<Color x:Key="TextPrimaryColor">#FFFFFF</Color>
<Color x:Key="TextSecondaryColor">#B0B0B0</Color>
<Color x:Key="SuccessColor">#4CAF50</Color>
<Color x:Key="WarningColor">#FF9800</Color>
<Color x:Key="DangerColor">#F44336</Color>
<Color x:Key="ManaColor">#00BCD4</Color>
<Color x:Key="HealthColor">#4CAF50</Color>
<SolidColorBrush x:Key="BackgroundBrush" Color="{StaticResource BackgroundColor}"/>
<SolidColorBrush x:Key="SurfaceBrush" Color="{StaticResource SurfaceColor}"/>
<SolidColorBrush x:Key="SurfaceLightBrush" Color="{StaticResource SurfaceLightColor}"/>
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource PrimaryColor}"/>
<SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource SecondaryColor}"/>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource AccentColor}"/>
<SolidColorBrush x:Key="TextPrimaryBrush" Color="{StaticResource TextPrimaryColor}"/>
<SolidColorBrush x:Key="TextSecondaryBrush" Color="{StaticResource TextSecondaryColor}"/>
<SolidColorBrush x:Key="SuccessBrush" Color="{StaticResource SuccessColor}"/>
<SolidColorBrush x:Key="WarningBrush" Color="{StaticResource WarningColor}"/>
<SolidColorBrush x:Key="DangerBrush" Color="{StaticResource DangerColor}"/>
<SolidColorBrush x:Key="ManaBrush" Color="{StaticResource ManaColor}"/>
<SolidColorBrush x:Key="HealthBrush" Color="{StaticResource HealthColor}"/>
<!-- Card Type Colors -->
<SolidColorBrush x:Key="SpellBrush" Color="#FF6464"/>
<SolidColorBrush x:Key="CreatureBrush" Color="#64FF64"/>
<SolidColorBrush x:Key="ArtifactBrush" Color="#C8C864"/>
<SolidColorBrush x:Key="EnchantmentBrush" Color="#9664C8"/>
<SolidColorBrush x:Key="WeaponBrush" Color="#FF9632"/>
<SolidColorBrush x:Key="ArmorBrush" Color="#6496C8"/>
<SolidColorBrush x:Key="EventBrush" Color="#FFC864"/>
<SolidColorBrush x:Key="BlankBrush" Color="#C8C8C8"/>
<!-- Element Colors -->
<SolidColorBrush x:Key="FireBrush" Color="#FF501E"/>
<SolidColorBrush x:Key="WaterBrush" Color="#1E64C8"/>
<SolidColorBrush x:Key="EarthBrush" Color="#644628"/>
<SolidColorBrush x:Key="AirBrush" Color="#B4DCFF"/>
<SolidColorBrush x:Key="LightBrush" Color="#FFF0B4"/>
<SolidColorBrush x:Key="DarkBrush" Color="#281432"/>
<SolidColorBrush x:Key="ArcaneBrush" Color="#9632C8"/>
<SolidColorBrush x:Key="NatureBrush" Color="#3CB43C"/>
<!-- Rarity Colors -->
<SolidColorBrush x:Key="CommonBrush" Color="#B4B4B4"/>
<SolidColorBrush x:Key="UncommonBrush" Color="#64C864"/>
<SolidColorBrush x:Key="RareBrush" Color="#3264C8"/>
<SolidColorBrush x:Key="LegendaryBrush" Color="#C89632"/>
<!-- Base Button Style -->
<Style x:Key="BaseButtonStyle" TargetType="Button">
<Setter Property="Background" Value="{StaticResource SecondaryBrush}"/>
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="16,8"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource PrimaryBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource AccentBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Primary Button Style -->
<Style x:Key="PrimaryButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="{StaticResource PrimaryBrush}"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<!-- Accent Button Style -->
<Style x:Key="AccentButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="{StaticResource AccentBrush}"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<!-- Danger Button Style -->
<Style x:Key="DangerButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="{StaticResource DangerBrush}"/>
</Style>
<!-- Card Container Style -->
<Style x:Key="CardContainerStyle" TargetType="Border">
<Setter Property="Background" Value="{StaticResource SurfaceBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource SurfaceLightBrush}"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="Width" Value="140"/>
<Setter Property="Height" Value="200"/>
</Style>
<!-- Title Text Style -->
<Style x:Key="TitleStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}"/>
<Setter Property="FontSize" Value="28"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontFamily" Value="Arial"/>
</Style>
<!-- Subtitle Text Style -->
<Style x:Key="SubtitleStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource TextSecondaryBrush}"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="Arial"/>
</Style>
<!-- Body Text Style -->
<Style x:Key="BodyStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
<!-- Mana Cost Style -->
<Style x:Key="ManaCostStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource ManaBrush}"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontFamily" Value="Arial"/>
</Style>
</ResourceDictionary>
+90
View File
@@ -0,0 +1,90 @@
using MagicalDeckbuilder.Cards;
using CardType = MagicalDeckbuilder.Cards.CardType;
using ElementType = MagicalDeckbuilder.Cards.ElementType;
using EffectType = MagicalDeckbuilder.Cards.EffectType;
using TargetType = MagicalDeckbuilder.Cards.TargetType;
namespace NewGame.UI.ViewModels;
public class CardViewModel : ViewModelBase
{
private readonly Card _card;
private bool _isSelected;
private bool _isDragging;
public CardViewModel(Card card)
{
_card = card ?? throw new ArgumentNullException(nameof(card));
}
public Card Card => _card;
public string Id => _card.Id;
public string Name => _card.Name;
public string Description => _card.Description;
public CardType Type => _card.Type;
public ElementType Element => _card.Element;
public int ManaCost => _card.ManaCost;
public int Power => _card.Power;
public int Health => _card.Health;
public bool IsLegendary => _card.IsLegendary;
public int Rarity => _card.Rarity;
public IReadOnlyList<CardEffect> Effects => _card.Effects;
public bool IsSelected
{
get => _isSelected;
set => SetProperty(ref _isSelected, value);
}
public bool IsDragging
{
get => _isDragging;
set => SetProperty(ref _isDragging, value);
}
public string TypeColor => Type switch
{
CardType.Spell => "#FF6464",
CardType.Creature => "#64FF64",
CardType.Artifact => "#C8C864",
CardType.Enchantment => "#9664C8",
CardType.Weapon => "#FF9632",
CardType.Armor => "#6496C8",
CardType.Event => "#FFC864",
CardType.Blank => "#C8C8C8",
_ => "#808080"
};
public string ElementColor => Element switch
{
ElementType.Radioactivity => "#00FF64",
ElementType.Flesh => "#C86464",
ElementType.Toxin => "#96C800",
ElementType.Fungus => "#649664",
ElementType.Thermodynamics => "#FF6432",
ElementType.Time => "#9664C8",
ElementType.Food => "#C89664",
ElementType.Eldritch => "#6400C8",
_ => "#808080"
};
public string RarityText => Rarity switch
{
1 => "Common",
2 => "Uncommon",
3 => "Rare",
4 => "Legendary",
_ => "Unknown"
};
public string RarityColor => Rarity switch
{
1 => "#B4B4B4",
2 => "#64C864",
3 => "#3264C8",
4 => "#C89632",
_ => "#808080"
};
public CardViewModel Clone() => new(_card.Clone());
}
+354
View File
@@ -0,0 +1,354 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
using MagicalDeckbuilder.Cards;
using MagicalDeckbuilder.Combining;
using MagicalDeckbuilder.Decks;
using MagicalDeckbuilder.Game;
using Card = MagicalDeckbuilder.Cards.Card;
using CardType = MagicalDeckbuilder.Cards.CardType;
using PileType = MagicalDeckbuilder.Decks.PileType;
namespace NewGame.UI.ViewModels;
public class MainViewModel : ViewModelBase
{
private readonly CardCombiner _cardCombiner = new();
private string _currentView = "Menu";
private CardViewModel? _selectedCard;
private CardViewModel? _comboCard1;
private CardViewModel? _comboCard2;
private CardViewModel? _comboResult;
private string _statusMessage = "";
private bool _canCombine;
private int _playerHealth = 30;
private int _playerMaxHealth = 30;
private int _playerMana = 2;
private int _playerMaxMana = 10;
private int _opponentHealth = 30;
private int _turnCount = 1;
private bool _isPlayerTurn = true;
public MainViewModel()
{
PlayerDeck = new DeckManager();
OpponentDeck = new DeckManager();
InitializeGameCommand = new RelayCommand(InitializeGame);
StartGameCommand = new RelayCommand(StartGame);
EndTurnCommand = new RelayCommand(EndTurn, () => _isPlayerTurn);
CombineCardsCommand = new RelayCommand(ExecuteCombine, () => _canCombine);
ClearComboCommand = new RelayCommand(ClearCombo);
PlayCardCommand = new RelayCommand<CardViewModel>(PlayCard);
NavigateCommand = new RelayCommand<string>(Navigate);
RemoveCardFromDeckCommand = new RelayCommand<CardViewModel>(RemoveCardFromDeck);
ClearDeckCommand = new RelayCommand(ClearDeck);
var allCards = CardFactory.CreateStarterDeck();
AvailableCards = new ObservableCollection<CardViewModel>(
allCards.Select(c => new CardViewModel(c)));
MenuCards = new ObservableCollection<CardViewModel>(
CardFactory.CreateStarterDeck().Select(c => new CardViewModel(c)));
}
public ObservableCollection<CardViewModel> AvailableCards { get; }
public ObservableCollection<CardViewModel> MenuCards { get; }
public ObservableCollection<CardViewModel> PlayerHand { get; } = new();
public ObservableCollection<CardViewModel> CustomCards { get; } = new();
public ObservableCollection<CardViewModel> PlayerDeckCards { get; } = new();
public DeckManager PlayerDeck { get; }
public DeckManager OpponentDeck { get; }
public int PlayerDeckCardCount => PlayerDeckCards.Count;
public CardViewModel?[] FieldSlots { get; } = new CardViewModel?[12];
public string CurrentView
{
get => _currentView;
set => SetProperty(ref _currentView, value);
}
public CardViewModel? SelectedCard
{
get => _selectedCard;
set => SetProperty(ref _selectedCard, value);
}
public CardViewModel? ComboCard1
{
get => _comboCard1;
set => SetProperty(ref _comboCard1, value);
}
public CardViewModel? ComboCard2
{
get => _comboCard2;
set => SetProperty(ref _comboCard2, value);
}
public CardViewModel? ComboResult
{
get => _comboResult;
set => SetProperty(ref _comboResult, value);
}
public bool CanCombine
{
get => _canCombine;
set => SetProperty(ref _canCombine, value);
}
public string StatusMessage
{
get => _statusMessage;
set => SetProperty(ref _statusMessage, value);
}
public int PlayerHealth
{
get => _playerHealth;
set => SetProperty(ref _playerHealth, value);
}
public int PlayerMaxHealth
{
get => _playerMaxHealth;
set => SetProperty(ref _playerMaxHealth, value);
}
public int PlayerMana
{
get => _playerMana;
set => SetProperty(ref _playerMana, value);
}
public int PlayerMaxMana
{
get => _playerMaxMana;
set => SetProperty(ref _playerMaxMana, value);
}
public int OpponentHealth
{
get => _opponentHealth;
set => SetProperty(ref _opponentHealth, value);
}
public int TurnCount
{
get => _turnCount;
set => SetProperty(ref _turnCount, value);
}
public bool IsPlayerTurn
{
get => _isPlayerTurn;
set => SetProperty(ref _isPlayerTurn, value);
}
public ICommand InitializeGameCommand { get; }
public ICommand StartGameCommand { get; }
public ICommand EndTurnCommand { get; }
public ICommand CombineCardsCommand { get; }
public ICommand ClearComboCommand { get; }
public ICommand PlayCardCommand { get; }
public ICommand NavigateCommand { get; }
public ICommand RemoveCardFromDeckCommand { get; }
public ICommand ClearDeckCommand { get; }
private void InitializeGame()
{
var playerCards = CardFactory.GenerateRandomDeck();
PlayerDeck.InitializeDeck(playerCards);
var opponentCards = CardFactory.GenerateRandomDeck();
OpponentDeck.InitializeDeck(opponentCards);
PlayerDeck.DrawCards(4);
PlayerHealth = 30;
PlayerMaxHealth = 30;
PlayerMana = 2;
PlayerMaxMana = 10;
OpponentHealth = 30;
TurnCount = 1;
IsPlayerTurn = true;
RefreshHand();
CurrentView = "Game";
}
public void AddCardToDeck(CardViewModel card)
{
if (card == null) return;
PlayerDeckCards.Add(card);
OnPropertyChanged(nameof(PlayerDeckCardCount));
OnPropertyChanged(nameof(DeckCountText));
}
public void RemoveCardFromDeck(CardViewModel card)
{
if (card == null) return;
PlayerDeckCards.Remove(card);
OnPropertyChanged(nameof(PlayerDeckCardCount));
OnPropertyChanged(nameof(DeckCountText));
}
public void ClearDeck()
{
PlayerDeckCards.Clear();
OnPropertyChanged(nameof(PlayerDeckCardCount));
OnPropertyChanged(nameof(DeckCountText));
}
public string DeckCountText => $"{PlayerDeckCards.Count} cards";
private void StartGame()
{
CurrentView = "Game";
}
private void RefreshHand()
{
PlayerHand.Clear();
foreach (var card in PlayerDeck.Hand)
{
PlayerHand.Add(new CardViewModel(card));
}
}
private void EndTurn()
{
if (!IsPlayerTurn) return;
ResolveCombat();
IsPlayerTurn = false;
PlayerDeck.DrawCards(1);
RefreshHand();
TurnCount++;
PlayerMana = Math.Min(_turnCount, 10);
}
private void ResolveCombat()
{
for (int i = 0; i < 6; i++)
{
var playerCreature = FieldSlots[i + 6]?.Card;
var opponentCreature = FieldSlots[i]?.Card;
if (playerCreature != null && playerCreature.Power > 0)
{
if (opponentCreature != null)
{
opponentCreature.Health -= playerCreature.Power;
if (opponentCreature.Health <= 0)
{
FieldSlots[i] = null;
OpponentHealth -= playerCreature.Power;
}
}
else
{
OpponentHealth -= playerCreature.Power;
}
}
}
}
private void ExecuteCombine()
{
if (ComboCard1 == null || ComboCard2 == null) return;
var result = _cardCombiner.Combine(ComboCard1.Card, ComboCard2.Card);
if (!result.Success || result.ResultCard == null)
{
StatusMessage = result.Message;
return;
}
PlayerDeck.PlayCard(ComboCard1.Id);
PlayerDeck.PlayCard(ComboCard2.Id);
var newCard = new CardViewModel(result.ResultCard);
PlayerDeck.Hand.Add(result.ResultCard);
PlayerHand.Add(newCard);
CustomCards.Add(newCard);
StatusMessage = $"Created {result.ResultCard.Name}!";
ClearCombo();
OnPropertyChanged(nameof(PlayerHand));
}
private void ClearCombo()
{
ComboCard1 = null;
ComboCard2 = null;
ComboResult = null;
CanCombine = false;
}
public void SetComboCard(CardViewModel card, int slot)
{
if (slot == 1)
ComboCard1 = card;
else
ComboCard2 = card;
UpdateComboPreview();
}
private void UpdateComboPreview()
{
if (ComboCard1 == null || ComboCard2 == null)
{
ComboResult = null;
CanCombine = false;
return;
}
var result = _cardCombiner.Combine(ComboCard1.Card, ComboCard2.Card);
if (result.Success && result.ResultCard != null)
{
ComboResult = new CardViewModel(result.ResultCard);
CanCombine = true;
}
else
{
ComboResult = null;
CanCombine = false;
}
}
public void PlayCardToSlot(CardViewModel card, int slotIndex)
{
if (slotIndex < 6 || slotIndex > 11) return;
if (card.Card.Type != CardType.Creature) return;
if (card.Card.ManaCost > PlayerMana) return;
if (FieldSlots[slotIndex] != null) return;
PlayerMana -= card.Card.ManaCost;
PlayerDeck.PlayCard(card.Id);
FieldSlots[slotIndex] = card;
PlayerHand.Remove(card);
OnPropertyChanged(nameof(FieldSlots));
OnPropertyChanged(nameof(PlayerHand));
}
private void PlayCard(CardViewModel? card)
{
if (card == null) return;
SelectedCard = card;
}
private void Navigate(string? view)
{
if (string.IsNullOrEmpty(view)) return;
CurrentView = view;
}
}
+52
View File
@@ -0,0 +1,52 @@
using System.Windows.Input;
namespace NewGame.UI.ViewModels;
public class RelayCommand : ICommand
{
private readonly Action<object?> _execute;
private readonly Func<object?, bool>? _canExecute;
public RelayCommand(Action<object?> execute, Func<object?, bool>? canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public RelayCommand(Action execute, Func<bool>? canExecute = null)
: this(_ => execute(), canExecute != null ? _ => canExecute() : null)
{
}
public event EventHandler? CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object? parameter) => _canExecute?.Invoke(parameter) ?? true;
public void Execute(object? parameter) => _execute(parameter);
}
public class RelayCommand<T> : ICommand
{
private readonly Action<T?> _execute;
private readonly Func<T?, bool>? _canExecute;
public RelayCommand(Action<T?> execute, Func<T?, bool>? canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public event EventHandler? CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object? parameter) => _canExecute?.Invoke((T?)parameter) ?? true;
public void Execute(object? parameter) => _execute((T?)parameter);
}
+23
View File
@@ -0,0 +1,23 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace NewGame.UI.ViewModels;
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
+111
View File
@@ -0,0 +1,111 @@
<UserControl x:Class="NewGame.UI.Views.BrowserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Converters="clr-namespace:NewGame.UI.Converters"
mc:Ignorable="d"
Background="{StaticResource BackgroundBrush}">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Card Browser"
Style="{StaticResource TitleStyle}"
Margin="0,0,0,20"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding AvailableCards}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{StaticResource SurfaceBrush}"
BorderBrush="{StaticResource SurfaceLightBrush}"
BorderThickness="2"
CornerRadius="8"
Padding="10"
Margin="6"
Width="150"
Height="210"
Cursor="Hand">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"
Foreground="White"
FontSize="11"
FontWeight="Bold"
TextTrimming="CharacterEllipsis"/>
<Border Grid.Column="1"
Background="{StaticResource ManaBrush}"
CornerRadius="8"
Padding="5,2">
<TextBlock Text="{Binding ManaCost}"
Foreground="White"
FontSize="10"
FontWeight="Bold"/>
</Border>
</Grid>
<Border Grid.Row="1"
Background="{Binding Element, Converter={StaticResource ElementToColorConverter}}"
CornerRadius="4"
Margin="0,8"
Height="70">
<TextBlock Text="{Binding Type}"
Foreground="#80FFFFFF"
FontSize="11"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<TextBlock Text="{Binding Type}"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="9"/>
<TextBlock Text=" | " Foreground="{StaticResource TextSecondaryBrush}" FontSize="9"/>
<TextBlock Text="{Binding Element}"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="9"/>
</StackPanel>
<TextBlock Grid.Row="3"
Text="{Binding RarityText}"
Foreground="{Binding Rarity, Converter={StaticResource RarityToColorConverter}}"
FontSize="9"
FontWeight="Bold"
Margin="0,4,0,0"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<UserControl.Resources>
<Converters:ElementToColorConverter x:Key="ElementToColorConverter"/>
<Converters:RarityToColorConverter x:Key="RarityToColorConverter"/>
</UserControl.Resources>
</UserControl>
+11
View File
@@ -0,0 +1,11 @@
using System.Windows.Controls;
namespace NewGame.UI.Views;
public partial class BrowserView : UserControl
{
public BrowserView()
{
InitializeComponent();
}
}
+210
View File
@@ -0,0 +1,210 @@
<UserControl x:Class="NewGame.UI.Views.DeckBuilderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Converters="clr-namespace:NewGame.UI.Converters"
xmlns:vm="clr-namespace:NewGame.UI.ViewModels"
mc:Ignorable="d"
Background="{StaticResource BackgroundBrush}">
<UserControl.Resources>
<Converters:TypeToColorConverter x:Key="TypeToColorConverter"/>
<Converters:ElementToColorConverter x:Key="ElementToColorConverter"/>
</UserControl.Resources>
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,20">
<TextBlock Text="Deck Builder" Style="{StaticResource TitleStyle}"/>
<Button Content="Clear Deck"
Style="{StaticResource BaseButtonStyle}"
Command="{Binding ClearDeckCommand}"
Margin="30,0,0,0"
Padding="15,6"/>
<Button Content="Start Game"
Style="{StaticResource PrimaryButtonStyle}"
Command="{Binding InitializeGameCommand}"
Margin="10,0,0,0"
Padding="15,6"/>
</StackPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Available Cards -->
<Border Grid.Column="0"
Background="{StaticResource SurfaceBrush}"
CornerRadius="8"
Padding="15"
Margin="0,0,10,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Available Cards"
Foreground="{StaticResource TextPrimaryBrush}"
FontSize="14"
FontWeight="Bold"
Margin="0,0,0,10"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding AvailableCards}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{StaticResource SurfaceLightBrush}"
BorderBrush="{Binding Type, Converter={StaticResource TypeToColorConverter}}"
BorderThickness="2"
CornerRadius="6"
Padding="8"
Margin="4"
Width="130"
Height="180"
Cursor="Hand"
MouseLeftButtonDown="Card_MouseLeftButtonDown"
MouseMove="Card_MouseMove">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock Text="{Binding Name}"
Foreground="White"
FontSize="10"
FontWeight="Bold"
TextTrimming="CharacterEllipsis"/>
<Border HorizontalAlignment="Right"
Background="{StaticResource ManaBrush}"
CornerRadius="6"
Padding="4,1">
<TextBlock Text="{Binding ManaCost}"
Foreground="White"
FontSize="9"/>
</Border>
</Grid>
<Border Grid.Row="1"
Background="{Binding Element, Converter={StaticResource ElementToColorConverter}}"
Margin="0,6"
CornerRadius="3">
<TextBlock Text="{Binding Type}"
Foreground="#80FFFFFF"
FontSize="9"
HorizontalAlignment="Center"/>
</Border>
<TextBlock Grid.Row="2"
Text="{Binding Element}"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="8"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Border>
<!-- Deck Preview -->
<Border Grid.Column="1"
Background="{StaticResource SurfaceBrush}"
CornerRadius="8"
Padding="15"
AllowDrop="True"
Drop="Deck_Drop"
DragOver="Deck_DragOver">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Your Deck"
Foreground="{StaticResource TextPrimaryBrush}"
FontSize="14"
FontWeight="Bold"/>
<TextBlock Grid.Row="1"
Text="{Binding DeckCountText}"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="12"
Margin="0,5,0,10"/>
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding PlayerDeckCards}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{StaticResource SurfaceLightBrush}"
BorderBrush="{Binding Type, Converter={StaticResource TypeToColorConverter}}"
BorderThickness="1"
CornerRadius="4"
Padding="6"
Margin="0,0,0,4"
Width="Auto"
MouseRightButtonDown="DeckCard_RightClick">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="{Binding Name}"
Foreground="White"
FontSize="10"
FontWeight="Bold"/>
<TextBlock Text="{Binding Element}"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="8"/>
</StackPanel>
<Border Grid.Column="1"
Background="{StaticResource ManaBrush}"
CornerRadius="4"
Padding="4,2"
VerticalAlignment="Center">
<TextBlock Text="{Binding ManaCost}"
Foreground="White"
FontSize="9"/>
</Border>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<TextBlock Grid.Row="3"
Text="Drag cards here to add to deck"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="12"
FontStyle="Italic"
Visibility="{Binding PlayerDeckCards.Count, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverse}"
Margin="0,10,0,0"/>
</Grid>
</Border>
</Grid>
</Grid>
</UserControl>
+80
View File
@@ -0,0 +1,80 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using NewGame.UI.ViewModels;
namespace NewGame.UI.Views;
public partial class DeckBuilderView : UserControl
{
private Point _startPoint;
private CardViewModel? _draggedCard;
public DeckBuilderView()
{
InitializeComponent();
}
private void Card_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_startPoint = e.GetPosition(null);
}
private void Card_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed) return;
var currentPosition = e.GetPosition(null);
var diff = _startPoint - currentPosition;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
var border = sender as Border;
var card = border?.DataContext as CardViewModel;
if (card != null)
{
_draggedCard = card;
var data = new DataObject("CardViewModel", card);
DragDrop.DoDragDrop(border!, data, DragDropEffects.Copy);
}
}
}
private void Deck_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("CardViewModel"))
{
e.Effects = DragDropEffects.Copy;
}
else
{
e.Effects = DragDropEffects.None;
}
e.Handled = true;
}
private void Deck_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("CardViewModel"))
{
var card = e.Data.GetData("CardViewModel") as CardViewModel;
if (card != null && DataContext is MainViewModel vm)
{
vm.AddCardToDeck(card);
}
}
}
private void DeckCard_RightClick(object sender, MouseButtonEventArgs e)
{
var border = sender as Border;
var card = border?.DataContext as CardViewModel;
if (card != null && DataContext is MainViewModel vm)
{
vm.RemoveCardFromDeck(card);
}
}
}
+105
View File
@@ -0,0 +1,105 @@
<UserControl x:Class="NewGame.UI.Views.GalleryView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Converters="clr-namespace:NewGame.UI.Converters"
mc:Ignorable="d"
Background="{StaticResource BackgroundBrush}">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Card Gallery"
Style="{StaticResource TitleStyle}"
Margin="0,0,0,20"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding MenuCards}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{Binding Element, Converter={StaticResource ElementToColorConverter}}"
BorderBrush="{Binding Type, Converter={StaticResource TypeToColorConverter}}"
BorderThickness="3"
CornerRadius="8"
Padding="12"
Margin="8"
Width="160"
Height="220">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock Text="{Binding Name}"
Foreground="White"
FontSize="12"
FontWeight="Bold"
TextWrapping="Wrap"/>
<Border HorizontalAlignment="Right"
Background="{StaticResource ManaBrush}"
CornerRadius="10"
Padding="6,2">
<TextBlock Text="{Binding ManaCost}"
Foreground="White"
FontSize="11"
FontWeight="Bold"/>
</Border>
</Grid>
<Border Grid.Row="1"
Background="#40000000"
Margin="0,10,0,10"
CornerRadius="4">
<TextBlock Text="{Binding Description}"
Foreground="#C0FFFFFF"
FontSize="9"
TextWrapping="Wrap"
VerticalAlignment="Center"
Padding="5"/>
</Border>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<TextBlock Text="{Binding Type}"
Foreground="#B0B0B0"
FontSize="10"/>
<TextBlock Text=" | " Foreground="#606060"/>
<TextBlock Text="{Binding RarityText}"
Foreground="{Binding Rarity, Converter={StaticResource RarityToColorConverter}}"
FontSize="10"/>
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Horizontal" Margin="0,5,0,0">
<TextBlock Text="PWR:" Foreground="#FF9632" FontSize="10"/>
<TextBlock Text="{Binding Power}" Foreground="#FF9632" FontSize="10" FontWeight="Bold"/>
<TextBlock Text=" HP:" Foreground="#64FF64" FontSize="10" Margin="10,0,0,0"/>
<TextBlock Text="{Binding Health}" Foreground="#64FF64" FontSize="10" FontWeight="Bold"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<UserControl.Resources>
<Converters:TypeToColorConverter x:Key="TypeToColorConverter"/>
<Converters:ElementToColorConverter x:Key="ElementToColorConverter"/>
<Converters:RarityToColorConverter x:Key="RarityToColorConverter"/>
</UserControl.Resources>
</UserControl>
+11
View File
@@ -0,0 +1,11 @@
using System.Windows.Controls;
namespace NewGame.UI.Views;
public partial class GalleryView : UserControl
{
public GalleryView()
{
InitializeComponent();
}
}
+309
View File
@@ -0,0 +1,309 @@
<UserControl x:Class="NewGame.UI.Views.GameView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:NewGame.UI.ViewModels"
xmlns:controls="clr-namespace:NewGame.UI.Controls"
xmlns:Converters="clr-namespace:NewGame.UI.Converters"
mc:Ignorable="d"
Background="{StaticResource BackgroundBrush}">
<UserControl.Resources>
<Converters:BoolToTurnTextConverter x:Key="BoolToTurnTextConverter"/>
<Converters:BoolToTurnColorConverter x:Key="BoolToTurnColorConverter"/>
<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
</UserControl.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Top Bar: Turn Info & Status -->
<Border Grid.Row="0"
Background="{StaticResource SurfaceBrush}"
CornerRadius="6"
Padding="15,10"
Margin="0,0,0,10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0">
<TextBlock Text="Turn " Foreground="{StaticResource TextPrimaryBrush}" FontSize="14"/>
<TextBlock Text="{Binding TurnCount}" Foreground="{StaticResource TextPrimaryBrush}" FontSize="14" FontWeight="Bold"/>
<TextBlock Text=" | " Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBlock Text="{Binding IsPlayerTurn, Converter={StaticResource BoolToTurnTextConverter}}"
Foreground="{Binding IsPlayerTurn, Converter={StaticResource BoolToTurnColorConverter}}"
FontSize="14" FontWeight="Bold"/>
</StackPanel>
<TextBlock Grid.Column="1"
Text="{Binding StatusMessage}"
Foreground="{StaticResource AccentBrush}"
FontSize="13"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="20,0">
<TextBlock Text="HP: " Foreground="{StaticResource HealthBrush}" FontSize="14"/>
<TextBlock Text="{Binding PlayerHealth}" Foreground="{StaticResource HealthBrush}" FontSize="14" FontWeight="Bold"/>
<TextBlock Text="/" Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBlock Text="{Binding PlayerMaxHealth}" Foreground="{StaticResource TextSecondaryBrush}" FontSize="14"/>
</StackPanel>
<StackPanel Grid.Column="3" Orientation="Horizontal" Margin="20,0">
<TextBlock Text="Mana: " Foreground="{StaticResource ManaBrush}" FontSize="14"/>
<TextBlock Text="{Binding PlayerMana}" Foreground="{StaticResource ManaBrush}" FontSize="14" FontWeight="Bold"/>
<TextBlock Text="/" Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBlock Text="{Binding PlayerMaxMana}" Foreground="{StaticResource TextSecondaryBrush}" FontSize="14"/>
</StackPanel>
<Button Grid.Column="4"
Content="End Turn"
Style="{StaticResource AccentButtonStyle}"
Command="{Binding EndTurnCommand}"
Padding="20,8"/>
</Grid>
</Border>
<!-- Opponent Area -->
<Border Grid.Row="1"
Background="{StaticResource SurfaceBrush}"
CornerRadius="6"
Padding="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Opponent"
Foreground="{StaticResource DangerBrush}"
FontSize="14" FontWeight="Bold" Margin="0,0,0,10"/>
<UniformGrid Grid.Row="1" Rows="1" Columns="6">
<Border Background="#503232" BorderBrush="#604040" BorderThickness="1" Margin="3" CornerRadius="4">
<TextBlock Text="O1" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border Background="#503232" BorderBrush="#604040" BorderThickness="1" Margin="3" CornerRadius="4">
<TextBlock Text="O2" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border Background="#503232" BorderBrush="#604040" BorderThickness="1" Margin="3" CornerRadius="4">
<TextBlock Text="O3" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border Background="#503232" BorderBrush="#604040" BorderThickness="1" Margin="3" CornerRadius="4">
<TextBlock Text="O4" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border Background="#503232" BorderBrush="#604040" BorderThickness="1" Margin="3" CornerRadius="4">
<TextBlock Text="O5" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border Background="#503232" BorderBrush="#604040" BorderThickness="1" Margin="3" CornerRadius="4">
<TextBlock Text="O6" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</UniformGrid>
</Grid>
</Border>
<!-- Playing Field Label -->
<TextBlock Grid.Row="2"
Text="Playing Field"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="12"
Margin="0,10"
HorizontalAlignment="Center"/>
<!-- Player Field Area -->
<Border Grid.Row="3"
Background="#324632"
CornerRadius="6"
Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="280"/>
</Grid.ColumnDefinitions>
<!-- Player Field Slots -->
<UniformGrid Grid.Column="0" Rows="1" Columns="6" VerticalAlignment="Center">
<Border x:Name="Slot0"
Background="#465046"
BorderBrush="#506050"
BorderThickness="2"
Margin="4"
CornerRadius="6"
AllowDrop="True"
Drop="OnSlotDrop"
DragEnter="OnSlotDragEnter"
DragLeave="OnSlotDragLeave"
Tag="6">
<TextBlock Text="P1" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="12"/>
</Border>
<Border x:Name="Slot1"
Background="#465046"
BorderBrush="#506050"
BorderThickness="2"
Margin="4"
CornerRadius="6"
AllowDrop="True"
Drop="OnSlotDrop"
DragEnter="OnSlotDragEnter"
DragLeave="OnSlotDragLeave"
Tag="7">
<TextBlock Text="P2" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="12"/>
</Border>
<Border x:Name="Slot2"
Background="#465046"
BorderBrush="#506050"
BorderThickness="2"
Margin="4"
CornerRadius="6"
AllowDrop="True"
Drop="OnSlotDrop"
DragEnter="OnSlotDragEnter"
DragLeave="OnSlotDragLeave"
Tag="8">
<TextBlock Text="P3" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="12"/>
</Border>
<Border x:Name="Slot3"
Background="#465046"
BorderBrush="#506050"
BorderThickness="2"
Margin="4"
CornerRadius="6"
AllowDrop="True"
Drop="OnSlotDrop"
DragEnter="OnSlotDragEnter"
DragLeave="OnSlotDragLeave"
Tag="9">
<TextBlock Text="P4" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="12"/>
</Border>
<Border x:Name="Slot4"
Background="#465046"
BorderBrush="#506050"
BorderThickness="2"
Margin="4"
CornerRadius="6"
AllowDrop="True"
Drop="OnSlotDrop"
DragEnter="OnSlotDragEnter"
DragLeave="OnSlotDragLeave"
Tag="10">
<TextBlock Text="P5" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="12"/>
</Border>
<Border x:Name="Slot5"
Background="#465046"
BorderBrush="#506050"
BorderThickness="2"
Margin="4"
CornerRadius="6"
AllowDrop="True"
Drop="OnSlotDrop"
DragEnter="OnSlotDragEnter"
DragLeave="OnSlotDragLeave"
Tag="11">
<TextBlock Text="P6" Foreground="#808080" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="12"/>
</Border>
</UniformGrid>
<!-- Combo Area -->
<Border Grid.Column="1"
Background="{StaticResource SurfaceBrush}"
CornerRadius="6"
Padding="10"
Margin="10,0,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Card Combine"
Foreground="{StaticResource TextPrimaryBrush}"
FontSize="14" FontWeight="Bold"
HorizontalAlignment="Center"/>
<Grid Grid.Row="1" Margin="0,15,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="ComboSlot1"
Grid.Column="0"
Background="#464646"
BorderBrush="#505050"
BorderThickness="2"
Margin="5"
CornerRadius="6"
Height="80"
AllowDrop="True"
Drop="OnComboSlot1Drop"
DragEnter="OnComboSlotDragEnter"
DragLeave="OnComboSlotDragLeave">
<TextBlock Text="1" Foreground="#606060" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20"/>
</Border>
<Border x:Name="ComboSlot2"
Grid.Column="1"
Background="#464646"
BorderBrush="#505050"
BorderThickness="2"
Margin="5"
CornerRadius="6"
Height="80"
AllowDrop="True"
Drop="OnComboSlot2Drop"
DragEnter="OnComboSlotDragEnter"
DragLeave="OnComboSlotDragLeave">
<TextBlock Text="2" Foreground="#606060" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20"/>
</Border>
</Grid>
<Border Grid.Row="2"
Background="{StaticResource SurfaceLightBrush}"
BorderBrush="{StaticResource SecondaryBrush}"
BorderThickness="1"
Margin="5,10"
CornerRadius="6"
Height="60"
Visibility="{Binding ComboResult, Converter={StaticResource NullToVisibilityConverter}}">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="{Binding ComboResult.Name}"
Foreground="{StaticResource AccentBrush}"
FontSize="12" FontWeight="Bold"
HorizontalAlignment="Center"/>
<TextBlock Text="Preview"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="10"
HorizontalAlignment="Center"/>
</StackPanel>
</Border>
<Button Grid.Row="3"
Content="Combine!"
Style="{StaticResource AccentButtonStyle}"
Command="{Binding CombineCardsCommand}"
IsEnabled="{Binding CanCombine}"
Height="50"
FontSize="16"
Margin="5,10"/>
</Grid>
</Border>
</Grid>
</Border>
</Grid>
</UserControl>
+104
View File
@@ -0,0 +1,104 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using NewGame.UI.ViewModels;
namespace NewGame.UI.Views;
public partial class GameView : UserControl
{
public GameView()
{
InitializeComponent();
}
private MainViewModel? ViewModel => DataContext as MainViewModel;
private void OnSlotDragEnter(object sender, DragEventArgs e)
{
if (sender is Border slot)
{
var slotIndex = (int)(slot.Tag ?? -1);
if (slotIndex >= 6 && slotIndex <= 11 && ViewModel?.FieldSlots[slotIndex] == null)
{
slot.Background = new SolidColorBrush(Color.FromRgb(80, 120, 80));
e.Effects = DragDropEffects.Move;
}
else
{
e.Effects = DragDropEffects.None;
}
}
e.Handled = true;
}
private void OnSlotDragLeave(object sender, DragEventArgs e)
{
if (sender is Border slot)
{
slot.Background = new SolidColorBrush(Color.FromRgb(70, 80, 70));
}
e.Handled = true;
}
private void OnSlotDrop(object sender, DragEventArgs e)
{
if (sender is Border slot && e.Data.GetDataPresent("CardViewModel"))
{
var card = e.Data.GetData("CardViewModel") as CardViewModel;
var slotIndex = (int)(slot.Tag ?? -1);
slot.Background = new SolidColorBrush(Color.FromRgb(70, 80, 70));
if (card != null && slotIndex >= 6 && slotIndex <= 11)
{
ViewModel?.PlayCardToSlot(card, slotIndex);
}
}
e.Handled = true;
}
private void OnComboSlotDragEnter(object sender, DragEventArgs e)
{
if (sender is Border slot)
{
slot.Background = new SolidColorBrush(Color.FromRgb(70, 70, 90));
}
e.Handled = true;
}
private void OnComboSlotDragLeave(object sender, DragEventArgs e)
{
if (sender is Border slot)
{
slot.Background = new SolidColorBrush(Color.FromRgb(70, 70, 70));
}
e.Handled = true;
}
private void OnComboSlot1Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("CardViewModel"))
{
var card = e.Data.GetData("CardViewModel") as CardViewModel;
if (card != null)
{
ViewModel?.SetComboCard(card, 1);
}
}
e.Handled = true;
}
private void OnComboSlot2Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("CardViewModel"))
{
var card = e.Data.GetData("CardViewModel") as CardViewModel;
if (card != null)
{
ViewModel?.SetComboCard(card, 2);
}
}
e.Handled = true;
}
}
+151
View File
@@ -0,0 +1,151 @@
<UserControl x:Class="NewGame.UI.Views.MenuView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Converters="clr-namespace:NewGame.UI.Converters"
mc:Ignorable="d"
Background="{StaticResource BackgroundBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Title Area -->
<StackPanel Grid.Row="0"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Margin="0,0,0,20">
<TextBlock Text="MAGICAL DECKBUILDER"
Style="{StaticResource TitleStyle}"
HorizontalAlignment="Center"/>
<TextBlock Text="Combine Cards, Build Your Deck, Win!"
Style="{StaticResource SubtitleStyle}"
HorizontalAlignment="Center"
Margin="0,10,0,0"/>
</StackPanel>
<!-- Menu Buttons -->
<StackPanel Grid.Row="1"
VerticalAlignment="Top"
HorizontalAlignment="Center"
MinWidth="300">
<Button Content="Play Game"
Style="{StaticResource PrimaryButtonStyle}"
Command="{Binding NavigateCommand}"
CommandParameter="Game"
Height="60"
Margin="0,10,0,0"
FontSize="18"/>
<Button Content="Card Browser"
Style="{StaticResource AccentButtonStyle}"
Command="{Binding NavigateCommand}"
CommandParameter="Browser"
Height="60"
Margin="0,10,0,0"
FontSize="18"/>
<Button Content="Deck Builder"
Style="{StaticResource BaseButtonStyle}"
Command="{Binding NavigateCommand}"
CommandParameter="DeckBuilder"
Height="60"
Margin="0,10,0,0"
FontSize="18"/>
<Button Content="Card Gallery"
Style="{StaticResource BaseButtonStyle}"
Command="{Binding NavigateCommand}"
CommandParameter="Gallery"
Height="60"
Margin="0,10,0,0"
FontSize="18"/>
</StackPanel>
<!-- Featured Cards Preview -->
<Border Grid.Row="2"
Background="{StaticResource SurfaceBrush}"
Margin="20,20,20,20"
CornerRadius="8"
Padding="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Featured Cards"
Foreground="{StaticResource TextPrimaryBrush}"
FontSize="16"
FontWeight="Bold"
Margin="0,0,0,10"/>
<ItemsControl Grid.Row="1" ItemsSource="{Binding MenuCards}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{StaticResource SurfaceLightBrush}"
BorderBrush="{StaticResource SecondaryBrush}"
BorderThickness="1"
CornerRadius="6"
Padding="8"
Margin="4"
Width="120"
Height="160">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}"
Foreground="White"
FontSize="10"
FontWeight="Bold"
TextTrimming="CharacterEllipsis"/>
<Border Grid.Row="1"
Background="{Binding Element, Converter={StaticResource ElementToColorConverter}}"
Margin="0,4,0,4"
CornerRadius="3">
<TextBlock Text="{Binding Type}"
Foreground="#80FFFFFF"
FontSize="9"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<TextBlock Text="{Binding ManaCost}"
Foreground="{StaticResource ManaBrush}"
FontSize="10"
FontWeight="Bold"/>
<TextBlock Text=" Mana"
Foreground="{StaticResource TextSecondaryBrush}"
FontSize="9"
Margin="2,0,0,0"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</Grid>
<UserControl.Resources>
<Converters:ElementToColorConverter x:Key="ElementToColorConverter"/>
</UserControl.Resources>
</UserControl>
+11
View File
@@ -0,0 +1,11 @@
using System.Windows.Controls;
namespace NewGame.UI.Views;
public partial class MenuView : UserControl
{
public MenuView()
{
InitializeComponent();
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Some files were not shown because too many files have changed in this diff Show More