diff --git a/MagicalDeckbuilder.Shared/CardDatabase.json b/MagicalDeckbuilder.Shared/CardDatabase.json
new file mode 100644
index 0000000..d2f0b8b
--- /dev/null
+++ b/MagicalDeckbuilder.Shared/CardDatabase.json
@@ -0,0 +1,54 @@
+{
+ "description": "Card Database - Documents all cards in the game with their Template IDs",
+ "notes": "IDs 1-200 are base/combinable creature cards, IDs 10000+ are combo/created cards",
+ "lastUpdated": "2025-01-13",
+ "idRanges": {
+ "baseCards": "1-200",
+ "comboCards": "10000+"
+ },
+ "combiningFormula": "comboTemplateId = 10000 + (minId * 1000) + maxId",
+ "combinableTypes": ["Creature", "Blank"],
+ "nonCombinableTypes": ["Spell", "Weapon", "Armor", "Artifact", "Event", "Enchantment"],
+ "baseCards": [
+ { "id": 1, "name": "Irradiated Blob", "element": "Radioactivity", "type": "Creature", "manaCost": 1, "health": 6, "power": 1, "rarity": "Common", "combinable": true },
+ { "id": 2, "name": "Confused Predator", "element": "Radioactivity", "type": "Creature", "manaCost": 1, "health": 3, "power": 3, "rarity": "Common", "combinable": true },
+ { "id": 3, "name": "Geiger Giant", "element": "Radioactivity", "type": "Creature", "manaCost": 5, "health": 10, "power": 4, "rarity": "Rare", "combinable": true },
+ { "id": 4, "name": "Fruiting Body", "element": "Fungus", "type": "Creature", "manaCost": 4, "health": 3, "power": 4, "rarity": "Common", "combinable": true },
+ { "id": 5, "name": "Mycelium Spore", "element": "Fungus", "type": "Creature", "manaCost": 2, "health": 1, "power": 1, "rarity": "Common", "combinable": true },
+ { "id": 6, "name": "Refuse Slinger", "element": "Toxin", "type": "Creature", "manaCost": 1, "health": 1, "power": 2, "rarity": "Common", "combinable": true },
+ { "id": 7, "name": "Pupae Patroller", "element": "Toxin", "type": "Creature", "manaCost": 3, "health": 2, "power": 3, "rarity": "Uncommon", "combinable": true },
+ { "id": 8, "name": "Brood Monarch", "element": "Toxin", "type": "Creature", "manaCost": 6, "health": 4, "power": 3, "rarity": "Rare", "combinable": true },
+ { "id": 9, "name": "Undead Stump", "element": "Fungus", "type": "Creature", "manaCost": 5, "health": 4, "power": 4, "rarity": "Uncommon", "combinable": true },
+ { "id": 10, "name": "Amalgamation", "element": "Flesh", "type": "Creature", "manaCost": 2, "health": 3, "power": 5, "rarity": "Common", "combinable": true },
+ { "id": 11, "name": "Heat Mote", "element": "Thermodynamics", "type": "Creature", "manaCost": 1, "health": 1, "power": 2, "rarity": "Common", "combinable": true },
+ { "id": 12, "name": "Cold Mote", "element": "Thermodynamics", "type": "Creature", "manaCost": 1, "health": 2, "power": 1, "rarity": "Common", "combinable": true },
+ { "id": 13, "name": "Anthropomorphized Meat", "element": "Food", "type": "Creature", "manaCost": 1, "health": 8, "power": 0, "rarity": "Common", "combinable": true },
+ { "id": 14, "name": "Jubilee Jester", "element": "Food", "type": "Creature", "manaCost": 5, "health": 6, "power": 6, "rarity": "Rare", "combinable": true },
+ { "id": 15, "name": "Questing Tendril", "element": "Eldritch", "type": "Creature", "manaCost": 1, "health": 2, "power": 1, "rarity": "Common", "combinable": true },
+ { "id": 16, "name": "Occult Dabbler", "element": "Eldritch", "type": "Creature", "manaCost": 2, "health": 2, "power": 2, "rarity": "Common", "combinable": true },
+ { "id": 17, "name": "Dwarf Star Spawn", "element": "Eldritch", "type": "Creature", "manaCost": 2, "health": 1, "power": 3, "rarity": "Common", "combinable": true },
+ { "id": 18, "name": "Malformed Summon", "element": "Eldritch", "type": "Creature", "manaCost": 3, "health": 2, "power": 3, "rarity": "Common", "combinable": true },
+ { "id": 19, "name": "Eater of Hope", "element": "Eldritch", "type": "Creature", "manaCost": 5, "health": 3, "power": 8, "rarity": "Uncommon", "combinable": true },
+ { "id": 20, "name": "Greater Star Spawn", "element": "Eldritch", "type": "Creature", "manaCost": 5, "health": 3, "power": 4, "rarity": "Uncommon", "combinable": true },
+ { "id": 21, "name": "Herald of Jaa'aird'thuun", "element": "Eldritch", "type": "Creature", "manaCost": 4, "health": 4, "power": 4, "rarity": "Rare", "combinable": true },
+ { "id": 22, "name": "Jaa'aird'thuun", "element": "Eldritch", "type": "Creature", "manaCost": 7, "health": 8, "power": 8, "rarity": "Legendary", "combinable": true }
+ ],
+ "comboCards": [
+ { "id": 11013, "name": "Slightly Glowing Sponge Cakes", "combo": "Irradiated Blob(1) + Anthropomorphized Meat(13)", "element": "Radioactivity", "type": "Creature", "combinable": true, "comboOnly": true, "formula": "10000 + (1*1000) + 13 = 11013" },
+ { "id": 12012, "name": "Tempature Mote", "combo": "Heat Mote(11) + Cold Mote(12)", "element": "Thermodynamics", "type": "Creature", "combinable": true, "comboOnly": true, "formula": "10000 + (11*1000) + 12 = 12012" }
+ ],
+ "comboExamples": [
+ { "cards": "Irradiated Blob + Heat Mote", "formula": "10000 + (1*1000) + 11", "resultId": 11011 },
+ { "cards": "Irradiated Blob + Cold Mote", "formula": "10000 + (1*1000) + 12", "resultId": 11012 },
+ { "cards": "Heat Mote + Cold Mote", "formula": "10000 + (11*1000) + 12", "resultId": 12012 },
+ { "cards": "Fruiting Body + Mycelium Spore", "formula": "10000 + (4*1000) + 5", "resultId": 5004 }
+ ],
+ "notes": [
+ "Base cards (1-200) are combinable creatures and blanks only",
+ "Combo cards use IDs 10000+ and are created via combining two base cards",
+ "Combo formula: 10000 + (minBaseId * 1000) + maxBaseId",
+ "Only Creature and Blank card types can be combined",
+ "Spells, Weapons, Armor, Artifacts, Events, and Enchantments cannot be combined",
+ "Quest table cards (Dwarf Star Spawn, Malformed Summon, etc.) are obtained via quest tokens, not combining"
+ ]
+}
\ No newline at end of file
diff --git a/MagicalDeckbuilder.Shared/Cards/Card.cs b/MagicalDeckbuilder.Shared/Cards/Card.cs
index a76a5c2..789a2f1 100644
--- a/MagicalDeckbuilder.Shared/Cards/Card.cs
+++ b/MagicalDeckbuilder.Shared/Cards/Card.cs
@@ -129,6 +129,12 @@ public enum WeaponTargetType
public class Card
{
public string Id { get; set; } = Guid.NewGuid().ToString();
+
+ ///
+ /// Template ID for lookups: 1-200 for base cards, 1000-2000 for combo cards
+ ///
+ public int TemplateId { get; set; }
+
public string Name { get; set; } = "";
public string Description { get; set; } = "";
public CardType Type { get; set; }
@@ -146,7 +152,7 @@ public class Card
public bool IsLegendary { get; set; }
public int Rarity { get; set; } // 1 = common, 2 = uncommon, 3 = rare, 4 = legendary
- public bool IsCombinable { get; set; } // true if this card can be used in the combine system
+ public bool IsCombinable { get; set; } = true; // true if this card can be used in the combine system
public bool IsComboOnly { get; set; } // true if this card can only be obtained via combining, not added to decks
///
@@ -159,6 +165,7 @@ public class Card
return new Card
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
@@ -219,6 +226,7 @@ public class CreatureCard : Card
var clone = new CreatureCard
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
@@ -277,6 +285,7 @@ public class SpellCard : Card
return new SpellCard
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
@@ -328,6 +337,7 @@ public class ArtifactCard : Card
var clone = new ArtifactCard
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
@@ -380,6 +390,7 @@ public class EventCard : Card
return new EventCard
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
@@ -431,6 +442,7 @@ public class BlankCard : Card
return new BlankCard
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
@@ -482,6 +494,7 @@ public class WeaponCard : Card
return new WeaponCard
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
@@ -604,6 +617,7 @@ public class ArmorCard : Card
return new ArmorCard
{
Id = Guid.NewGuid().ToString(),
+ TemplateId = this.TemplateId,
Name = this.Name,
Description = this.Description,
Type = this.Type,
diff --git a/MagicalDeckbuilder.Shared/Combining/CardRecipeRegistry.cs b/MagicalDeckbuilder.Shared/Combining/CardRecipeRegistry.cs
new file mode 100644
index 0000000..6e9d785
--- /dev/null
+++ b/MagicalDeckbuilder.Shared/Combining/CardRecipeRegistry.cs
@@ -0,0 +1,185 @@
+using Card = MagicalDeckbuilder.Cards.Card;
+using MagicalDeckbuilder.Logging;
+
+namespace MagicalDeckbuilder.Combining;
+
+///
+/// Central registry for card combination recipes.
+/// Defines all valid combinations between base cards.
+/// Formula: combo_template_id = 10000 + (min_id * 1000) + max_id
+///
+public class CardRecipeRegistry
+{
+ private static CardRecipeRegistry? _instance;
+ private static readonly object _lock = new();
+
+ ///
+ /// Singleton instance
+ ///
+ public static CardRecipeRegistry Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ lock (_lock)
+ {
+ _instance ??= new CardRecipeRegistry();
+ }
+ }
+ return _instance;
+ }
+ }
+
+ ///
+ /// Maps combo template ID to the source card template IDs
+ /// Key: comboTemplateId (int), Value: Tuple of (card1TemplateId, card2TemplateId)
+ ///
+ private readonly Dictionary _recipes = new();
+
+ ///
+ /// Reverse lookup: maps source card pair to combo template ID
+ ///
+ private readonly Dictionary<(int, int), int> _reverseLookup = new();
+
+ private CardRecipeRegistry()
+ {
+ InitializeDefaultRecipes();
+ }
+
+ ///
+ /// Calculate the combo template ID for two card template IDs
+ /// Formula: 10000 + (minId * 1000) + maxId
+ ///
+ public static int CalculateComboTemplateId(int templateId1, int templateId2)
+ {
+ var minId = Math.Min(templateId1, templateId2);
+ var maxId = Math.Max(templateId1, templateId2);
+ return 10000 + (minId * 1000) + maxId;
+ }
+
+ ///
+ /// Calculate the combo template ID for two cards
+ ///
+ public static int CalculateComboTemplateId(Card card1, Card card2)
+ {
+ return CalculateComboTemplateId(card1.TemplateId, card2.TemplateId);
+ }
+
+ ///
+ /// Check if a combo recipe exists for two cards
+ ///
+ public bool HasRecipe(int templateId1, int templateId2)
+ {
+ var key = (Math.Min(templateId1, templateId2), Math.Max(templateId1, templateId2));
+ return _reverseLookup.ContainsKey(key);
+ }
+
+ ///
+ /// Check if a combo recipe exists for two cards
+ ///
+ public bool HasRecipe(Card card1, Card card2)
+ {
+ return HasRecipe(card1.TemplateId, card2.TemplateId);
+ }
+
+ ///
+ /// Get the combo template ID for two cards, if a recipe exists
+ ///
+ public int? GetComboTemplateId(int templateId1, int templateId2)
+ {
+ var key = (Math.Min(templateId1, templateId2), Math.Max(templateId1, templateId2));
+ return _reverseLookup.TryGetValue(key, out var comboId) ? comboId : null;
+ }
+
+ ///
+ /// Get the source card IDs for a combo template ID
+ ///
+ public (int Card1Id, int Card2Id)? GetSourceCards(int comboTemplateId)
+ {
+ return _recipes.TryGetValue(comboTemplateId, out var recipe) ? recipe : null;
+ }
+
+ ///
+ /// Get all registered combo template IDs
+ ///
+ public IEnumerable GetAllComboTemplateIds()
+ {
+ return _recipes.Keys;
+ }
+
+ ///
+ /// Register a new combination recipe
+ ///
+ public void RegisterRecipe(int card1TemplateId, int card2TemplateId, int comboTemplateId)
+ {
+ var sortedCards = (Math.Min(card1TemplateId, card2TemplateId), Math.Max(card1TemplateId, card2TemplateId));
+
+ _recipes[comboTemplateId] = (sortedCards.Item1, sortedCards.Item2);
+ _reverseLookup[sortedCards] = comboTemplateId;
+
+ ErrorLogger.Instance.Debug("CardRecipeRegistry",
+ $"Registered recipe: {card1TemplateId} + {card2TemplateId} = {comboTemplateId}");
+ }
+
+ ///
+ /// Validate that a combo card's template ID matches its recipe
+ ///
+ public bool ValidateComboCard(int card1TemplateId, int card2TemplateId, int comboTemplateId)
+ {
+ var expectedComboId = CalculateComboTemplateId(card1TemplateId, card2TemplateId);
+ return expectedComboId == comboTemplateId;
+ }
+
+ ///
+ /// Initialize default combination recipes
+ /// Only creature and blank cards can be combined.
+ /// Formula: comboId = 10000 + (minId * 1000) + maxId
+ ///
+ private void InitializeDefaultRecipes()
+ {
+ // Radioactive combinations
+ RegisterRecipe(1, 11, CalculateComboTemplateId(1, 11)); // Irradiated Blob + Heat Mote = 11011
+ RegisterRecipe(1, 12, CalculateComboTemplateId(1, 12)); // Irradiated Blob + Cold Mote = 11012
+ RegisterRecipe(1, 13, CalculateComboTemplateId(1, 13)); // Irradiated Blob + Anthropomorphized Meat = 11013
+
+ // Thermodynamics combinations
+ RegisterRecipe(11, 12, CalculateComboTemplateId(11, 12)); // Heat Mote + Cold Mote = 12012
+ RegisterRecipe(11, 11, CalculateComboTemplateId(11, 11)); // Heat Mote + Heat Mote = 12011
+ RegisterRecipe(12, 12, CalculateComboTemplateId(12, 12)); // Cold Mote + Cold Mote = 12012 (same as above, but different source)
+
+ // Food combinations
+ RegisterRecipe(13, 1, CalculateComboTemplateId(1, 13)); // Anthropomorphized Meat + Irradiated Blob = 11013 (same as radioactive meat)
+
+ // Flesh combinations
+ RegisterRecipe(10, 13, CalculateComboTemplateId(10, 13)); // Amalgamation + Anthropomorphized Meat = 13010
+
+ // Fungus combinations
+ RegisterRecipe(4, 5, CalculateComboTemplateId(4, 5)); // Fruiting Body + Mycelium Spore = 5004
+ RegisterRecipe(5, 9, CalculateComboTemplateId(5, 9)); // Mycelium Spore + Undead Stump = 9005
+
+ // Toxin combinations
+ RegisterRecipe(6, 8, CalculateComboTemplateId(6, 8)); // Refuse Slinger + Brood Monarch = 8006
+
+ // Eldritch combinations
+ RegisterRecipe(15, 16, CalculateComboTemplateId(15, 16)); // Questing Tendril + Occult Dabbler = 16015
+ RegisterRecipe(17, 18, CalculateComboTemplateId(17, 18)); // Dwarf Star Spawn + Malformed Summon = 18017
+ RegisterRecipe(19, 20, CalculateComboTemplateId(19, 20)); // Eater of Hope + Greater Star Spawn = 20019
+ RegisterRecipe(21, 22, CalculateComboTemplateId(21, 22)); // Herald + Jaa'aird'thuun = 22021
+
+ ErrorLogger.Instance.Info("CardRecipeRegistry", $"Initialized {_recipes.Count} default combination recipes");
+ }
+
+ ///
+ /// Debug: Print all registered recipes
+ ///
+ public void DebugPrintRecipes()
+ {
+ ErrorLogger.Instance.Info("CardRecipeRegistry", "=== All Combination Recipes ===");
+ foreach (var kvp in _recipes.OrderBy(x => x.Key))
+ {
+ ErrorLogger.Instance.Info("CardRecipeRegistry",
+ $" {kvp.Value.Card1Id} + {kvp.Value.Card2Id} = {kvp.Key}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/MagicalDeckbuilder.Shared/Combining/CombinationLookup.cs b/MagicalDeckbuilder.Shared/Combining/CombinationLookup.cs
index 0fa9cb7..1ffc8d6 100644
--- a/MagicalDeckbuilder.Shared/Combining/CombinationLookup.cs
+++ b/MagicalDeckbuilder.Shared/Combining/CombinationLookup.cs
@@ -3,29 +3,32 @@ using Card = MagicalDeckbuilder.Cards.Card;
namespace MagicalDeckbuilder.Combining;
///
-/// Looks up pre-made combination cards based on two input cards.
-/// Format: combine_{sorted_id1}_{sorted_id2}
+/// Looks up pre-made combination cards based on two input cards' TemplateIds.
+/// Base cards use IDs 1-200, combo cards use IDs 10000+.
+/// Formula: combo_template_id = 10000 + (min_id * 1000) + max_id
+/// This ensures unique, collision-free IDs for all combinations.
+/// Example: Card 1 + Card 2 = 10000 + 1000 + 2 = 11002
+/// Example: Card 10 + Card 20 = 10000 + 10000 + 20 = 20020
///
public class CombinationLookup
{
- private readonly Dictionary _combinationCards = new();
-
+ private readonly Dictionary _comboCardsByTemplateId = new();
+
///
/// Initialize with a collection of pre-made combination cards
///
public void LoadCombinationCards(IEnumerable cards)
{
- _combinationCards.Clear();
+ _comboCardsByTemplateId.Clear();
foreach (var card in cards)
{
// Pre-made combo-only cards are stored in the deck
// They have IsComboOnly = true and IsCombinable = true
- if (card.IsComboOnly && card.IsCombinable)
+ // They should have TemplateId in range 1000-2000
+ if (card.IsComboOnly && card.IsCombinable && card.TemplateId >= 1000)
{
- // Create a key from the card name in lowercase with underscores
- var key = card.Name.ToLowerInvariant().Replace(" ", "_").Replace("'", "");
- _combinationCards[key] = card;
+ _comboCardsByTemplateId[card.TemplateId] = card;
}
}
}
@@ -36,44 +39,74 @@ public class CombinationLookup
///
public Card? FindCombination(Card card1, Card card2)
{
- // Sort IDs so order doesn't matter (combine_a_b == combine_b_a)
- var ids = new[] { card1.Id, card2.Id }.OrderBy(x => x).ToArray();
- var key = $"combine_{ids[0]}_{ids[1]}";
+ if (card1.TemplateId <= 0 || card2.TemplateId <= 0)
+ {
+ // Fallback to name-based lookup if template IDs not set
+ return FindCombinationByName(card1, card2);
+ }
- if (_combinationCards.TryGetValue(key, out var result))
+ // Calculate combo template ID: 10000 + (minId * 1000) + maxId
+ // Example: Card 1 + Card 2 = 10000 + 1000 + 2 = 11002
+ // Example: Card 10 + Card 20 = 10000 + 10000 + 20 = 20020
+ var ids = new[] { card1.TemplateId, card2.TemplateId }.OrderBy(x => x).ToArray();
+ var comboTemplateId = 10000 + (ids[0] * 1000) + ids[1];
+
+ if (_comboCardsByTemplateId.TryGetValue(comboTemplateId, out var result))
{
return result;
}
-
- // Try matching by checking combo card descriptions for the two base card names
- // The combo card description contains "(combo X + Y)" format
+
+ // Fallback to name-based lookup
+ return FindCombinationByName(card1, card2);
+ }
+
+ ///
+ /// Fallback: find combination by matching card names in combo card names
+ ///
+ private Card? FindCombinationByName(Card card1, Card card2)
+ {
+ if (card1.Name == card2.Name)
+ {
+ var cardName = card1.Name.ToLowerInvariant();
+ foreach (var kvp in _comboCardsByTemplateId.Values)
+ {
+ var comboName = kvp.Name.ToLowerInvariant();
+ if (comboName.Contains(cardName) && comboName != cardName)
+ {
+ return kvp;
+ }
+ }
+ return null;
+ }
+
var name1 = card1.Name.ToLowerInvariant();
var name2 = card2.Name.ToLowerInvariant();
- foreach (var kvp in _combinationCards)
+ foreach (var kvp in _comboCardsByTemplateId.Values)
{
- var desc = kvp.Value.Description.ToLowerInvariant();
- // Check if description contains both card names (with "combo" keyword)
- if (desc.Contains("combo") &&
- (desc.Contains(name1) || desc.Contains(name1.Replace(" ", ""))) &&
- (desc.Contains(name2) || desc.Contains(name2.Replace(" ", ""))))
+ var comboName = kvp.Name.ToLowerInvariant();
+ var desc = kvp.Description.ToLowerInvariant();
+
+ if (comboName == name1 || comboName == name2)
+ continue;
+
+ bool name1InCombo = comboName.Contains(name1);
+ bool name2InCombo = comboName.Contains(name2);
+
+ if (name1InCombo && name2InCombo)
{
- return kvp.Value;
+ return kvp;
+ }
+
+ if (desc.Contains("combo") && desc.Contains(name1) && desc.Contains(name2))
+ {
+ return kvp;
}
}
-
+
return null;
}
- ///
- /// Sanitize card name for use in lookup key
- ///
- private static string SanitizeName(string name)
- {
- // Remove spaces and special characters, keep only alphanumeric
- return new string(name.Where(char.IsLetterOrDigit).ToArray()).ToLowerInvariant();
- }
-
///
/// Check if two cards have a pre-made combination available
///
diff --git a/MagicalDeckbuilder.Shared/Game/CardDatabase.cs b/MagicalDeckbuilder.Shared/Game/CardDatabase.cs
new file mode 100644
index 0000000..35103c1
--- /dev/null
+++ b/MagicalDeckbuilder.Shared/Game/CardDatabase.cs
@@ -0,0 +1,234 @@
+using System.Collections.Generic;
+
+namespace MagicalDeckbuilder.Game;
+
+///
+/// Static database of all cards in the game with their Template IDs.
+/// IDs 1-200: Base/Combinable cards
+/// IDs 1000-2000: Combo/Created cards
+///
+public static class CardDatabase
+{
+ ///
+ /// All base cards that can be combined (IDs 1-22)
+ ///
+ public static readonly Dictionary BaseCards = new()
+ {
+ { 1, new CardInfo { Id = 1, Name = "Irradiated Blob", Element = "Radioactivity", Type = "Creature", ManaCost = 1, Health = 6, Power = 1, Rarity = "Common" } },
+ { 2, new CardInfo { Id = 2, Name = "Confused Predator", Element = "Radioactivity", Type = "Creature", ManaCost = 1, Health = 3, Power = 3, Rarity = "Common" } },
+ { 3, new CardInfo { Id = 3, Name = "Geiger Giant", Element = "Radioactivity", Type = "Creature", ManaCost = 5, Health = 10, Power = 4, Rarity = "Rare" } },
+ { 4, new CardInfo { Id = 4, Name = "Fruiting Body", Element = "Fungus", Type = "Creature", ManaCost = 4, Health = 3, Power = 4, Rarity = "Common" } },
+ { 5, new CardInfo { Id = 5, Name = "Mycelium Spore", Element = "Fungus", Type = "Creature", ManaCost = 2, Health = 1, Power = 1, Rarity = "Common" } },
+ { 6, new CardInfo { Id = 6, Name = "Refuse Slinger", Element = "Toxin", Type = "Creature", ManaCost = 1, Health = 1, Power = 2, Rarity = "Common" } },
+ { 7, new CardInfo { Id = 7, Name = "Pupae Patroller", Element = "Toxin", Type = "Creature", ManaCost = 3, Health = 2, Power = 3, Rarity = "Uncommon" } },
+ { 8, new CardInfo { Id = 8, Name = "Brood Monarch", Element = "Toxin", Type = "Creature", ManaCost = 6, Health = 4, Power = 3, Rarity = "Rare" } },
+ { 9, new CardInfo { Id = 9, Name = "Undead Stump", Element = "Fungus", Type = "Creature", ManaCost = 5, Health = 4, Power = 4, Rarity = "Uncommon" } },
+ { 10, new CardInfo { Id = 10, Name = "Amalgamation", Element = "Flesh", Type = "Creature", ManaCost = 2, Health = 3, Power = 5, Rarity = "Common" } },
+ { 11, new CardInfo { Id = 11, Name = "Heat Mote", Element = "Thermodynamics", Type = "Creature", ManaCost = 1, Health = 1, Power = 2, Rarity = "Common" } },
+ { 12, new CardInfo { Id = 12, Name = "Cold Mote", Element = "Thermodynamics", Type = "Creature", ManaCost = 1, Health = 2, Power = 1, Rarity = "Common" } },
+ { 13, new CardInfo { Id = 13, Name = "Anthropomorphized Meat", Element = "Food", Type = "Creature", ManaCost = 1, Health = 8, Power = 0, Rarity = "Common" } },
+ { 14, new CardInfo { Id = 14, Name = "Jubilee Jester", Element = "Food", Type = "Creature", ManaCost = 5, Health = 6, Power = 6, Rarity = "Rare" } },
+ { 15, new CardInfo { Id = 15, Name = "Questing Tendril", Element = "Eldritch", Type = "Creature", ManaCost = 1, Health = 2, Power = 1, Rarity = "Common" } },
+ { 16, new CardInfo { Id = 16, Name = "Occult Dabbler", Element = "Eldritch", Type = "Creature", ManaCost = 2, Health = 2, Power = 2, Rarity = "Common" } },
+ { 17, new CardInfo { Id = 17, Name = "Dwarf Star Spawn", Element = "Eldritch", Type = "Creature", ManaCost = 2, Health = 1, Power = 3, Rarity = "Common", IsQuestCard = true } },
+ { 18, new CardInfo { Id = 18, Name = "Malformed Summon", Element = "Eldritch", Type = "Creature", ManaCost = 3, Health = 2, Power = 3, Rarity = "Common", IsQuestCard = true } },
+ { 19, new CardInfo { Id = 19, Name = "Eater of Hope", Element = "Eldritch", Type = "Creature", ManaCost = 5, Health = 3, Power = 8, Rarity = "Uncommon", IsQuestCard = true } },
+ { 20, new CardInfo { Id = 20, Name = "Greater Star Spawn", Element = "Eldritch", Type = "Creature", ManaCost = 5, Health = 3, Power = 4, Rarity = "Uncommon", IsQuestCard = true } },
+ { 21, new CardInfo { Id = 21, Name = "Herald of Jaa'aird'thuun", Element = "Eldritch", Type = "Creature", ManaCost = 4, Health = 4, Power = 4, Rarity = "Rare", IsQuestCard = true } },
+ { 22, new CardInfo { Id = 22, Name = "Jaa'aird'thuun", Element = "Eldritch", Type = "Creature", ManaCost = 7, Health = 8, Power = 8, Rarity = "Legendary", IsQuestCard = true } }
+ };
+
+ ///
+ /// All combo cards created by combining base cards (IDs 1000+)
+ ///
+ public static readonly Dictionary ComboCards = new()
+ {
+ // Original 8 combo cards
+ { 1010, new ComboCardInfo { Id = 1010, Name = "Radioactive Heat", Recipe = "Irradiated Blob (1) + Heat Mote (11)", Element = "Radioactivity" } },
+ { 1011, new ComboCardInfo { Id = 1011, Name = "Frozen Blob", Recipe = "Irradiated Blob (1) + Cold Mote (12)", Element = "Radioactivity" } },
+ { 1012, new ComboCardInfo { Id = 1012, Name = "Thermal Balance", Recipe = "Heat Mote (11) + Cold Mote (12)", Element = "Thermodynamics" } },
+ { 1013, new ComboCardInfo { Id = 1013, Name = "Double Heat", Recipe = "Heat Mote (11) + Heat Mote (11)", Element = "Thermodynamics" } },
+ { 1014, new ComboCardInfo { Id = 1014, Name = "Double Cold", Recipe = "Cold Mote (12) + Cold Mote (12)", Element = "Thermodynamics" } },
+ { 1015, new ComboCardInfo { Id = 1015, Name = "Radioactive Meat", Recipe = "Irradiated Blob (1) + Anthropomorphized Meat (13)", Element = "Flesh" } },
+ { 1022, new ComboCardInfo { Id = 1022, Name = "Slightly Glowing Sponge Cakes", Recipe = "Anthropomorphized Meat (13) + Irradiated Blob (1)", Element = "Food" } },
+ { 1111, new ComboCardInfo { Id = 1111, Name = "Tempature Mote", Recipe = "Heat Mote (11) + Cold Mote (12)", Element = "Thermodynamics" } },
+ // New combo cards from list
+ { 1106, new ComboCardInfo { Id = 1106, Name = "Frozen Blob", Recipe = "Irradiated Blob (1) + Cold Mote (12)", Element = "Radioactivity" } },
+ { 1107, new ComboCardInfo { Id = 1107, Name = "Fire Stump", Recipe = "Undead Stump (9) + Heat Mote (11)", Element = "Thermodynamics" } },
+ { 1108, new ComboCardInfo { Id = 1108, Name = "Toxic Oracle", Recipe = "Occult Dabbler (16) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1109, new ComboCardInfo { Id = 1109, Name = "Star Eater", Recipe = "Eater of Hope (19) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1110, new ComboCardInfo { Id = 1110, Name = "Void Consumer", Recipe = "Eater of Hope (19) + Malformed Summon (18)", Element = "Eldritch" } },
+ { 1112, new ComboCardInfo { Id = 1112, Name = "Royal Toxin", Recipe = "Brood Monarch (8) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1113, new ComboCardInfo { Id = 1113, Name = "Cold Meat", Recipe = "Anthropomorphized Meat (13) + Cold Mote (12)", Element = "Flesh" } },
+ { 1114, new ComboCardInfo { Id = 1114, Name = "Fire Meat", Recipe = "Anthropomorphized Meat (13) + Heat Mote (11)", Element = "Flesh" } },
+ { 1115, new ComboCardInfo { Id = 1115, Name = "Eldritch Meat", Recipe = "Anthropomorphized Meat (13) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1116, new ComboCardInfo { Id = 1116, Name = "Fire Mote", Recipe = "Heat Mote (11) + Heat Mote (11)", Element = "Thermodynamics" } },
+ { 1117, new ComboCardInfo { Id = 1117, Name = "Cold Mote", Recipe = "Cold Mote (12) + Cold Mote (12)", Element = "Thermodynamics" } },
+ { 1119, new ComboCardInfo { Id = 1119, Name = "Toxic Mote", Recipe = "Refuse Slinger (6) + Heat Mote (11)", Element = "Toxin" } },
+ { 1120, new ComboCardInfo { Id = 1120, Name = "Radioactive Mote", Recipe = "Irradiated Blob (1) + Heat Mote (11)", Element = "Radioactivity" } },
+ { 1121, new ComboCardInfo { Id = 1121, Name = "Fungal Mote", Recipe = "Mycelium Spore (5) + Heat Mote (11)", Element = "Fungus" } },
+ { 1122, new ComboCardInfo { Id = 1122, Name = "Flesh Mote", Recipe = "Anthropomorphized Meat (13) + Heat Mote (11)", Element = "Flesh" } },
+ { 1123, new ComboCardInfo { Id = 1123, Name = "Thermo Mote", Recipe = "Heat Mote (11) + Heat Mote (11)", Element = "Thermodynamics" } },
+ { 1124, new ComboCardInfo { Id = 1124, Name = "Frost Jester", Recipe = "Jubilee Jester (14) + Cold Mote (12)", Element = "Food" } },
+ { 1125, new ComboCardInfo { Id = 1125, Name = "Fire Jester", Recipe = "Jubilee Jester (14) + Heat Mote (11)", Element = "Food" } },
+ { 1126, new ComboCardInfo { Id = 1126, Name = "Toxic Jester", Recipe = "Jubilee Jester (14) + Refuse Slinger (6)", Element = "Food" } },
+ { 1127, new ComboCardInfo { Id = 1127, Name = "Radiant Jester", Recipe = "Jubilee Jester (14) + Irradiated Blob (1)", Element = "Food" } },
+ { 1128, new ComboCardInfo { Id = 1128, Name = "Fire Tendril", Recipe = "Questing Tendril (15) + Heat Mote (11)", Element = "Eldritch" } },
+ { 1129, new ComboCardInfo { Id = 1129, Name = "Cold Tendril", Recipe = "Questing Tendril (15) + Cold Mote (12)", Element = "Eldritch" } },
+ { 1130, new ComboCardInfo { Id = 1130, Name = "Toxic Tendril", Recipe = "Questing Tendril (15) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1131, new ComboCardInfo { Id = 1131, Name = "Star Tendril", Recipe = "Questing Tendril (15) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1132, new ComboCardInfo { Id = 1132, Name = "Abyssal Tendril", Recipe = "Questing Tendril (15) + Jaaaird'thuun (22)", Element = "Eldritch" } },
+ { 1133, new ComboCardInfo { Id = 1133, Name = "Fire Oracle", Recipe = "Occult Dabbler (16) + Heat Mote (11)", Element = "Eldritch" } },
+ { 1135, new ComboCardInfo { Id = 1135, Name = "Star Mote", Recipe = "Heat Mote (11) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1136, new ComboCardInfo { Id = 1136, Name = "Cold Star Spawn", Recipe = "Cold Mote (12) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1137, new ComboCardInfo { Id = 1137, Name = "Fire Giant", Recipe = "Geiger Giant (3) + Heat Mote (11)", Element = "Thermodynamics" } },
+ { 1139, new ComboCardInfo { Id = 1139, Name = "Toxic Blob", Recipe = "Irradiated Blob (1) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1140, new ComboCardInfo { Id = 1140, Name = "Fungal Blob", Recipe = "Irradiated Blob (1) + Mycelium Spore (5)", Element = "Fungus" } },
+ { 1141, new ComboCardInfo { Id = 1141, Name = "Flesh Blob", Recipe = "Irradiated Blob (1) + Anthropomorphized Meat (13)", Element = "Flesh" } },
+ { 1142, new ComboCardInfo { Id = 1142, Name = "Fire Predator", Recipe = "Confused Predator (2) + Heat Mote (11)", Element = "Thermodynamics" } },
+ { 1143, new ComboCardInfo { Id = 1143, Name = "Cold Predator", Recipe = "Confused Predator (2) + Cold Mote (12)", Element = "Flesh" } },
+ { 1145, new ComboCardInfo { Id = 1145, Name = "Royal Stump", Recipe = "Undead Stump (9) + Brood Monarch (8)", Element = "Fungus" } },
+ // Batch 2 combo cards (1080-1105)
+ { 1080, new ComboCardInfo { Id = 1080, Name = "Glacial Beast", Recipe = "Geiger Giant (3) + Cold Mote (12)", Element = "Thermodynamics" } },
+ { 1081, new ComboCardInfo { Id = 1081, Name = "Heat Hive", Recipe = "Brood Monarch (8) + Heat Mote (11)", Element = "Toxin" } },
+ { 1082, new ComboCardInfo { Id = 1082, Name = "Void Mushroom", Recipe = "Mycelium Spore (5) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1083, new ComboCardInfo { Id = 1083, Name = "Radiant Stump", Recipe = "Undead Stump (9) + Heat Mote (11)", Element = "Fungus" } },
+ { 1084, new ComboCardInfo { Id = 1084, Name = "Toxic Tendril", Recipe = "Questing Tendril (15) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1085, new ComboCardInfo { Id = 1085, Name = "Cold Tendril", Recipe = "Questing Tendril (15) + Cold Mote (12)", Element = "Eldritch" } },
+ { 1086, new ComboCardInfo { Id = 1086, Name = "Star Monarch", Recipe = "Brood Monarch (8) + Malformed Summon (18)", Element = "Eldritch" } },
+ { 1087, new ComboCardInfo { Id = 1087, Name = "Cold Hive", Recipe = "Pupae Patroller (7) + Cold Mote (12)", Element = "Toxin" } },
+ { 1088, new ComboCardInfo { Id = 1088, Name = "Fungal Stoker", Recipe = "Mycelium Spore (5) + Heat Mote (11)", Element = "Fungus" } },
+ { 1089, new ComboCardInfo { Id = 1089, Name = "Cold Refuse", Recipe = "Refuse Slinger (6) + Cold Mote (12)", Element = "Toxin" } },
+ { 1090, new ComboCardInfo { Id = 1090, Name = "Abyssal Spawn", Recipe = "Dwarf Star Spawn (17) + Jaaaird'thuun (22)", Element = "Eldritch" } },
+ { 1092, new ComboCardInfo { Id = 1092, Name = "Frost Jester", Recipe = "Jubilee Jester (14) + Geiger Giant (3)", Element = "Food" } },
+ { 1093, new ComboCardInfo { Id = 1093, Name = "Plasma Jester", Recipe = "Jubilee Jester (14) + Heat Mote (11)", Element = "Food" } },
+ { 1094, new ComboCardInfo { Id = 1094, Name = "Radiant Jester", Recipe = "Jubilee Jester (14) + Irradiated Blob (1)", Element = "Food" } },
+ { 1095, new ComboCardInfo { Id = 1095, Name = "Void Geiger", Recipe = "Geiger Giant (3) + Malformed Summon (18)", Element = "Eldritch" } },
+ { 1096, new ComboCardInfo { Id = 1096, Name = "Fungal Queen", Recipe = "Brood Monarch (8) + Fruiting Body (4)", Element = "Fungus" } },
+ { 1097, new ComboCardInfo { Id = 1097, Name = "Cold Fruiting", Recipe = "Fruiting Body (4) + Cold Mote (12)", Element = "Fungus" } },
+ { 1098, new ComboCardInfo { Id = 1098, Name = "Heat Fruiting", Recipe = "Fruiting Body (4) + Heat Mote (11)", Element = "Fungus" } },
+ { 1099, new ComboCardInfo { Id = 1099, Name = "Cold Oracle", Recipe = "Occult Dabbler (16) + Cold Mote (12)", Element = "Eldritch" } },
+ { 1100, new ComboCardInfo { Id = 1100, Name = "Dark Oracle", Recipe = "Occult Dabbler (16) + Jaaaird'thuun (22)", Element = "Eldritch" } },
+ { 1101, new ComboCardInfo { Id = 1101, Name = "Cold Giant", Recipe = "Geiger Giant (3) + Cold Mote (12)", Element = "Thermodynamics" } },
+ { 1102, new ComboCardInfo { Id = 1102, Name = "Toxic Giant", Recipe = "Geiger Giant (3) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1103, new ComboCardInfo { Id = 1103, Name = "Flesh Giant", Recipe = "Geiger Giant (3) + Anthropomorphized Meat (13)", Element = "Flesh" } },
+ { 1104, new ComboCardInfo { Id = 1104, Name = "Star Prophet", Recipe = "Herald of Jaaaird'thuun (21) + Cold Mote (12)", Element = "Eldritch" } },
+ { 1105, new ComboCardInfo { Id = 1105, Name = "Void Prophet", Recipe = "Herald of Jaaaird'thuun (21) + Heat Mote (11)", Element = "Eldritch" } },
+ // Batch 3 combo cards (1051-1079)
+ { 1051, new ComboCardInfo { Id = 1051, Name = "Thermal Fruit", Recipe = "Fruiting Body (4) + Heat Mote (11)", Element = "Fungus" } },
+ { 1052, new ComboCardInfo { Id = 1052, Name = "Frozen Fruit", Recipe = "Fruiting Body (4) + Cold Mote (12)", Element = "Fungus" } },
+ { 1053, new ComboCardInfo { Id = 1053, Name = "Toxic Fruit", Recipe = "Fruiting Body (4) + Refuse Slinger (6)", Element = "Fungus" } },
+ { 1054, new ComboCardInfo { Id = 1054, Name = "Royal Heat", Recipe = "Brood Monarch (8) + Heat Mote (11)", Element = "Toxin" } },
+ { 1055, new ComboCardInfo { Id = 1055, Name = "Royal Cold", Recipe = "Brood Monarch (8) + Cold Mote (12)", Element = "Toxin" } },
+ { 1056, new ComboCardInfo { Id = 1056, Name = "Spore Stump", Recipe = "Undead Stump (9) + Mycelium Spore (5)", Element = "Fungus" } },
+ { 1057, new ComboCardInfo { Id = 1057, Name = "Eldritch Duo", Recipe = "Questing Tendril (15) + Occult Dabbler (16)", Element = "Eldritch" } },
+ { 1058, new ComboCardInfo { Id = 1058, Name = "Star Oracle", Recipe = "Occult Dabbler (16) + Greater Star Spawn (20)", Element = "Eldritch" } },
+ { 1059, new ComboCardInfo { Id = 1059, Name = "Void Spawn", Recipe = "Dwarf Star Spawn (17) + Malformed Summon (18)", Element = "Eldritch" } },
+ { 1061, new ComboCardInfo { Id = 1061, Name = "Cold Meat", Recipe = "Anthropomorphized Meat (13) + Cold Mote (12)", Element = "Flesh" } },
+ { 1062, new ComboCardInfo { Id = 1062, Name = "Rotting Meat", Recipe = "Anthropomorphized Meat (13) + Refuse Slinger (6)", Element = "Flesh" } },
+ { 1063, new ComboCardInfo { Id = 1063, Name = "Flesh Patrol", Recipe = "Anthropomorphized Meat (13) + Pupae Patroller (7)", Element = "Flesh" } },
+ { 1065, new ComboCardInfo { Id = 1065, Name = "Jester Tendril", Recipe = "Jubilee Jester (14) + Questing Tendril (15)", Element = "Eldritch" } },
+ { 1066, new ComboCardInfo { Id = 1066, Name = "Jester Spore", Recipe = "Jubilee Jester (14) + Mycelium Spore (5)", Element = "Fungus" } },
+ { 1067, new ComboCardInfo { Id = 1067, Name = "Giant Jester", Recipe = "Jubilee Jester (14) + Geiger Giant (3)", Element = "Food" } },
+ { 1068, new ComboCardInfo { Id = 1068, Name = "Toxic Heap", Recipe = "Refuse Slinger (6) + Fruiting Body (4)", Element = "Toxin" } },
+ { 1069, new ComboCardInfo { Id = 1069, Name = "Toxic Corpse", Recipe = "Refuse Slinger (6) + Undead Stump (9)", Element = "Toxin" } },
+ { 1070, new ComboCardInfo { Id = 1070, Name = "Armored Insect", Recipe = "Pupae Patroller (7) + Geiger Giant (3)", Element = "Toxin" } },
+ { 1072, new ComboCardInfo { Id = 1072, Name = "Fungal Guardian", Recipe = "Pupae Patroller (7) + Undead Stump (9)", Element = "Fungus" } },
+ { 1074, new ComboCardInfo { Id = 1074, Name = "Warmongers", Recipe = "Pupae Patroller (7) + Heat Mote (11)", Element = "Toxin" } },
+ { 1075, new ComboCardInfo { Id = 1075, Name = "Undead Giant", Recipe = "Undead Stump (9) + Geiger Giant (3)", Element = "Fungus" } },
+ { 1076, new ComboCardInfo { Id = 1076, Name = "Heat Stump", Recipe = "Undead Stump (9) + Heat Mote (11)", Element = "Fungus" } },
+ { 1077, new ComboCardInfo { Id = 1077, Name = "Void Jester", Recipe = "Jubilee Jester (14) + Malformed Summon (18)", Element = "Eldritch" } },
+ { 1078, new ComboCardInfo { Id = 1078, Name = "Abomination", Recipe = "Amalgamation (10) + Pupae Patroller (7)", Element = "Flesh" } },
+ { 1079, new ComboCardInfo { Id = 1079, Name = "Elder Spawn", Recipe = "Greater Star Spawn (20) + Herald of Jaaaird'thuun (21)", Element = "Eldritch" } },
+ // Batch 4 combo cards (1014-1050)
+ { 1014, new ComboCardInfo { Id = 1014, Name = "Radioactive Predator", Recipe = "Irradiated Blob (1) + Refuse Slinger (6)", Element = "Radioactivity" } },
+ { 1015, new ComboCardInfo { Id = 1015, Name = "Toxic Mote", Recipe = "Heat Mote (11) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1016, new ComboCardInfo { Id = 1016, Name = "Frost Amalgamation", Recipe = "Amalgamation (10) + Cold Mote (12)", Element = "Flesh" } },
+ { 1017, new ComboCardInfo { Id = 1017, Name = "Fire Toxin", Recipe = "Confused Predator (2) + Heat Mote (11)", Element = "Toxin" } },
+ { 1018, new ComboCardInfo { Id = 1018, Name = "Eldritch Flesh", Recipe = "Amalgamation (10) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1020, new ComboCardInfo { Id = 1020, Name = "Fungal Predator", Recipe = "Mycelium Spore (5) + Refuse Slinger (6)", Element = "Fungus" } },
+ { 1023, new ComboCardInfo { Id = 1023, Name = "Radiant Flesh", Recipe = "Anthropomorphized Meat (13) + Heat Mote (11)", Element = "Flesh" } },
+ { 1024, new ComboCardInfo { Id = 1024, Name = "Frozen Jester", Recipe = "Jubilee Jester (14) + Cold Mote (12)", Element = "Food" } },
+ { 1025, new ComboCardInfo { Id = 1025, Name = "Spore Tendril", Recipe = "Questing Tendril (15) + Mycelium Spore (5)", Element = "Eldritch" } },
+ { 1026, new ComboCardInfo { Id = 1026, Name = "Star Geiger", Recipe = "Geiger Giant (3) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1027, new ComboCardInfo { Id = 1027, Name = "Toxic Dabbler", Recipe = "Occult Dabbler (16) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1030, new ComboCardInfo { Id = 1030, Name = "Cold Star Spawn", Recipe = "Cold Mote (12) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1031, new ComboCardInfo { Id = 1031, Name = "Heat Star Spawn", Recipe = "Heat Mote (11) + Malformed Summon (18)", Element = "Eldritch" } },
+ { 1035, new ComboCardInfo { Id = 1035, Name = "Biohazard", Recipe = "Refuse Slinger (6) + Pupae Patroller (7)", Element = "Toxin" } },
+ { 1036, new ComboCardInfo { Id = 1036, Name = "Undead Hive", Recipe = "Undead Stump (9) + Brood Monarch (8)", Element = "Fungus" } },
+ { 1037, new ComboCardInfo { Id = 1037, Name = "Giant Flesh", Recipe = "Amalgamation (10) + Geiger Giant (3)", Element = "Flesh" } },
+ { 1042, new ComboCardInfo { Id = 1042, Name = "Spore Giant", Recipe = "Mycelium Spore (5) + Brood Monarch (8)", Element = "Fungus" } },
+ { 1043, new ComboCardInfo { Id = 1043, Name = "Fire Blob", Recipe = "Irradiated Blob (1) + Heat Mote (11)", Element = "Radioactivity" } },
+ { 1045, new ComboCardInfo { Id = 1045, Name = "Frozen Stump", Recipe = "Undead Stump (9) + Cold Mote (12)", Element = "Fungus" } },
+ { 1046, new ComboCardInfo { Id = 1046, Name = "Star Brood", Recipe = "Brood Monarch (8) + Dwarf Star Spawn (17)", Element = "Eldritch" } },
+ { 1047, new ComboCardInfo { Id = 1047, Name = "Toxic Mote", Recipe = "Cold Mote (12) + Refuse Slinger (6)", Element = "Toxin" } },
+ { 1048, new ComboCardInfo { Id = 1048, Name = "Necrotic Giant", Recipe = "Geiger Giant (3) + Undead Stump (9)", Element = "Fungus" } },
+ { 1049, new ComboCardInfo { Id = 1049, Name = "Flesh Tendril", Recipe = "Questing Tendril (15) + Anthropomorphized Meat (13)", Element = "Flesh" } },
+ { 1050, new ComboCardInfo { Id = 1050, Name = "Void Consumer", Recipe = "Eater of Hope (19) + Malformed Summon (18)", Element = "Eldritch" } }
+ };
+
+ ///
+ /// Get a base card by ID
+ ///
+ public static CardInfo? GetBaseCard(int id)
+ {
+ return BaseCards.TryGetValue(id, out var card) ? card : null;
+ }
+
+ ///
+ /// Get a combo card by ID
+ ///
+ public static ComboCardInfo? GetComboCard(int id)
+ {
+ return ComboCards.TryGetValue(id, out var card) ? card : null;
+ }
+
+ ///
+ /// Get any card (base or combo) by ID
+ ///
+ public static object? GetCard(int id)
+ {
+ if (id < 1000)
+ return GetBaseCard(id);
+ return GetComboCard(id);
+ }
+
+ ///
+ /// Check if an ID belongs to a base card
+ ///
+ public static bool IsBaseCard(int id) => id > 0 && id < 1000;
+
+ ///
+ /// Check if an ID belongs to a combo card
+ ///
+ public static bool IsComboCard(int id) => id >= 1000 && id < 2000;
+}
+
+///
+/// Information about a base/combinable card
+///
+public class CardInfo
+{
+ public int Id { get; set; }
+ public string Name { get; set; } = "";
+ public string Element { get; set; } = "";
+ public string Type { get; set; } = "";
+ public int ManaCost { get; set; }
+ public int Health { get; set; }
+ public int Power { get; set; }
+ public string Rarity { get; set; } = "";
+ public bool IsCombinable { get; set; } = true;
+ public bool IsQuestCard { get; set; } = false;
+}
+
+///
+/// Information about a combo/created card
+///
+public class ComboCardInfo
+{
+ public int Id { get; set; }
+ public string Name { get; set; } = "";
+ public string Recipe { get; set; } = "";
+ public string Element { get; set; } = "";
+ public string Type { get; set; } = "Creature";
+}
\ No newline at end of file
diff --git a/MagicalDeckbuilder.Shared/Game/CardFactory.cs b/MagicalDeckbuilder.Shared/Game/CardFactory.cs
index 8f17f60..1ed791c 100644
--- a/MagicalDeckbuilder.Shared/Game/CardFactory.cs
+++ b/MagicalDeckbuilder.Shared/Game/CardFactory.cs
@@ -64,8 +64,7 @@ public static class CardFactory
EffectValue = 2,
RequiresTarget = false
}
- });
- irradiatedBlob.IsCombinable = true;
+ }, 1);
deck.Add(irradiatedBlob);
// Confused Predator - CREATURE, MC:1, H:3, P:3, COMMON
@@ -82,7 +81,7 @@ public static class CardFactory
EffectValue = 1,
IsPassive = true
}
- }));
+ }, 2)); // TemplateId: 2
// Geiger Giant - CREATURE, MC:5, H:10, P:4, RARE
deck.Add(CreateCreature("Geiger Giant", "You're not quite positive who Geiger is, but he sure is tall.\n[ABILITY: Slam - 4 MC, 6 DTA]",
@@ -98,7 +97,7 @@ public static class CardFactory
EffectValue = 6,
RequiresTarget = false
}
- }));
+ }, 3));
// Mutually Assured Duplication - SPELL, MC:5, T:SE&PC, RARE
deck.Add(CreateSpell("Mutually Assured Duplication", "Wait, this is supposed to deter an attack??\n[ABILITY: Budding - Choose one enemy and friendly creature; duplicate these creatures to the closest unoccupied slot]",
@@ -158,7 +157,7 @@ public static class CardFactory
IsTemporary = true,
Duration = 2
}
- }));
+ }, 10));
// Disembody - SPELL, MC:3, T:SEC, COMMON
deck.Add(CreateSpell("Disembody", "Grummaz went from screaming and struggling to quiet and calm in about 2 seconds.\n[ABILITY: Astral Eviction - Creature may no longer attack, or use abilities]",
@@ -240,12 +239,12 @@ public static class CardFactory
IsTemporary = true,
Duration = 3
}
- }));
+ }, 6));
// Pupae Patroller - CREATURE, MC:3, H:2, P:3, UNCOMMON
// SKIP - requires larval creature card/tag (need to add larval creatures first)
deck.Add(CreateCreature("Pupae Patroller", "You're not sure how this guy fits in the insect heirarchy, but he sure seems happy. (this is a literal human being)\n[ABILITY: Prowl - 1 MC, +1P&+1H for a random larval creature]",
- ElementType.Toxin, 3, 2, 3, 2));
+ ElementType.Toxin, 3, 2, 3, 2, false, null, 7));
// Brood Monarch - CREATURE, MC:6, H:4, P:3, RARE
deck.Add(CreateCreature("Brood Monarch", "Without a doubt, the biggest and grossest bug you've ever seen.\n[ABILITY: Larval Gestation - 4 MC, starts 3 turn timer, spawns 2 3H3P workers]",
@@ -263,7 +262,7 @@ public static class CardFactory
IsTemporary = true,
Duration = 3
}
- }));
+ }, 8));
// Suspicious Mound - ARTIFACT, MC:4, UNCOMMON
deck.Add(CreateArtifact("Suspicious Mound", "People have learned to give these a wide berth, and not just because of the smell.\n[ABILITY: Overrun - 1MC, spawns 1 2H1P larval naiad (max 2 per turn)]",
@@ -303,7 +302,7 @@ public static class CardFactory
EffectValue = 1,
RequiresTarget = false
}
- }));
+ }, 5));
// Fruiting Body - CREATURE, MC:4, H:3, P:4, COMMON
deck.Add(CreateCreature("Fruiting Body", "Some poor animal ate one too many mushrooms, and ended up becoming a mushroom.\n[ABILITY: Troop Thickening - 2 MCPT, +1H&+1P PT to all spores]",
@@ -319,7 +318,7 @@ public static class CardFactory
EffectValue = 1,
IsPassive = true
}
- }));
+ }, 4));
// Undead Stump - CREATURE, MC:5, H:4, P:4, UNCOMMON
deck.Add(CreateCreature("Undead Stump", "The tree that once made up this stump is now dead, but to say the stump is lifeless is entirely inaccurate.\n[ABILITY: Germinate - 2MC, spawn 1 spore in the closest unoccupied creature slot]",
@@ -335,7 +334,7 @@ public static class CardFactory
EffectValue = 1,
RequiresTarget = false
}
- }));
+ }, 9));
// Creeping Infection - SPELL, MC:3, T:SC, UNCOMMON
deck.Add(CreateSpell("Creeping Infection", "It enters through the skin and only gets worse with time.\n[ABILITY: It Begins - 2 DTT for 4 turns, DTT increases by 1 for each turn after the first]",
@@ -393,8 +392,7 @@ public static class CardFactory
EffectValue = 0,
IsPassive = true
}
- });
- heatMote.IsCombinable = true;
+ }, 11);
deck.Add(heatMote);
// Cold Mote - CREATURE, MC:1, H:2, P:1, COMMON
@@ -411,8 +409,7 @@ public static class CardFactory
EffectValue = 0,
IsPassive = true
}
- });
- coldMote.IsCombinable = true;
+ }, 12);
deck.Add(coldMote);
// Thermal Shock - SPELL, MC:3, T:SC, COMMON
@@ -489,8 +486,7 @@ public static class CardFactory
EffectValue = 0,
RequiresTarget = false
}
- });
- anthropomorphizedMeat.IsCombinable = true;
+ }, 13);
deck.Add(anthropomorphizedMeat);
// Jubilee Jester - CREATURE, MC:5, H:6, P:6, RARE
@@ -507,7 +503,7 @@ public static class CardFactory
EffectValue = 4,
RequiresTarget = false
}
- }));
+ }, 14));
// Last Morsel - SPELL, MC:2, T:SC, UNCOMMON
deck.Add(CreateSpell("Last Morsel", "Yum, crunchy!\n[ABILITY: Are you going to finish that? - 3 DTT] - If this spell kills a creature, regain 1.5 times that many health points (rounded down)",
@@ -592,7 +588,7 @@ public static class CardFactory
EffectValue = 1,
RequiresTarget = false
}
- }));
+ }, 15));
// Occult Dabbler - CREATURE, MC:2, H:2, P:2, COMMON
deck.Add(CreateCreature("Occult Dabbler", "\"You want me to do WHAT?\"\n[ABILITY: Fiddle With - 1 MC, double quest/search tokens generated this turn]",
@@ -608,7 +604,7 @@ public static class CardFactory
EffectValue = 2, // Double tokens
RequiresTarget = false
}
- }));
+ }, 16));
// Call of the Deep - EVENT, MC:5, RARE, D:3T after effect
deck.Add(CreateEvent("Call of the Deep", "They all laughed, until the ritual worked.\n[ABILITY: Elaborate Rite - 5 MC, +2 MRPT for 2 turns] - Summons SOMETHING on the third turn",
@@ -652,7 +648,7 @@ public static class CardFactory
EffectValue = 4,
RequiresTarget = true
}
- }));
+ }, 17));
// Malformed Summon - CREATURE, MC:3, C:25%, H:2, P:3, COMMON
tableCards.Add(CreateCreature("Malformed Summon", "Whatever this was before, the journey was clearly not kind.\n[ABILITY: Wheeze - 2MC, -2P DBTT]",
@@ -668,7 +664,7 @@ public static class CardFactory
EffectValue = 2,
RequiresTarget = true
}
- }));
+ }, 18));
// Eater of Hope - CREATURE, MC:5, C:20%, H:3, P:8, UNCOMMON
tableCards.Add(CreateCreature("Eater of Hope", "Geez, do they not feed you or something?\n[ABILITY: Otherworldly Hunger - 4MC, Consume]",
@@ -684,7 +680,7 @@ public static class CardFactory
EffectValue = 0,
RequiresTarget = true
}
- }));
+ }, 19));
// Greater Star Spawn - CREATURE, MC:5, C:17%, H:3, P:4, UNCOMMON
tableCards.Add(CreateCreature("Greater Star Spawn", "After growing large in an ear, they crawl forth to aid in bringing about their Lord.\n[ABILITY: Thrash - 3MC, 10DTT]",
@@ -700,7 +696,7 @@ public static class CardFactory
EffectValue = 10,
RequiresTarget = true
}
- }));
+ }, 20));
// Herald of Jaa'aird'thuun - CREATURE, MC:4, C:10%, H:4, P:4, RARE
tableCards.Add(CreateCreature("Herald of Jaa'aird'thuun", "\"Do you have a moment to talk about our Lord and destroyer?\"\n[ABILITY: Proselytize - 3MC, add 2 Infection token/counters]",
@@ -716,7 +712,7 @@ public static class CardFactory
EffectValue = 2,
RequiresTarget = true
}
- }));
+ }, 21));
// Jaa'aird'thuun - CREATURE, MC:7, C:2%, H:8, P:8, LEGENDARY
tableCards.Add(CreateCreature("Jaa'aird'thuun", "He's real!!! And really... hungry?\n[ABILITY: Gobble - 6 MC, 10 DTAEC]",
@@ -732,7 +728,7 @@ public static class CardFactory
EffectValue = 10,
RequiresTarget = false
}
- }));
+ }, 22));
return tableCards;
}
@@ -743,7 +739,8 @@ public static class CardFactory
var deck = new List();
// Slightly Glowing Sponge Cakes - CREATURE, MC:3, RADxFOO, H:7, P:1, COMMON
- // Combo of Anthropomorphized Meat + Irradiated Blob
+ // Combo of Anthropomorphized Meat(13) + Irradiated Blob(1)
+ // Combo TemplateId: 10000 + (1 * 1000) + 13 = 11013
// NOTE: This is a combo-only card - cannot be added to decks
var spongeCakes = CreateCreature("Slightly Glowing Sponge Cakes", "See? I knew the only things that would be left were sponge cakes and giant bugs. (combo anthropomorphized meat + irradiated blob)\n[ABILITY: Temptation - 1 MC, BTS +4P, DBTS -3H]",
ElementType.Radioactivity, 3, 7, 1, 1, false,
@@ -761,10 +758,12 @@ public static class CardFactory
});
spongeCakes.IsCombinable = true;
spongeCakes.IsComboOnly = true;
+ spongeCakes.TemplateId = 11013; // 10000 + (1*1000) + 13
deck.Add(spongeCakes);
// Tempature Mote - CREATURE, MC:3, THExTHE, H:2, P:2, COMMON
- // Combo of Heat Mote + Cold Mote
+ // Combo of Heat Mote(11) + Cold Mote(12)
+ // Combo TemplateId: 10000 + (11 * 1000) + 12 = 12012
// NOTE: This is a combo-only card - cannot be added to decks
var tempMote = CreateCreature("Tempature Mote", "A cold snap just waiting to happen.\n[ABILITY: Tempature Gradient(both) - passive, doubles +P&+H buff values and durations]",
ElementType.Thermodynamics, 3, 2, 2, 1, false,
@@ -782,6 +781,7 @@ public static class CardFactory
});
tempMote.IsCombinable = true;
tempMote.IsComboOnly = true;
+ tempMote.TemplateId = 12012; // 10000 + (11*1000) + 12
deck.Add(tempMote);
return deck;
@@ -971,7 +971,7 @@ public static class CardFactory
private static Card CreateCreature(string name, string description,
ElementType element, int manaCost, int power, int health, int rarity = 1, bool isLegendary = false,
- List? abilities = null)
+ List? abilities = null, int templateId = 0)
{
return new CreatureCard
{
@@ -983,6 +983,8 @@ public static class CardFactory
Health = health,
Rarity = rarity,
IsLegendary = isLegendary,
+ TemplateId = templateId,
+ IsCombinable = templateId > 0 && templateId < 1000,
Abilities = abilities ?? new List(),
Effects = new List
{
diff --git a/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll b/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll
index 9bc5674..646d01f 100644
Binary files a/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll and b/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll differ
diff --git a/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb b/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb
index 3413794..98946ad 100644
Binary files a/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb and b/MagicalDeckbuilder.Shared/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb differ
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfo.cs b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfo.cs
index 71053ac..7bc8dfe 100644
--- a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfo.cs
+++ b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfo.cs
@@ -13,7 +13,7 @@ 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+f0b96ad03f0b23be73e6de74767c208f6b7756aa")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+f7db1d0d598c5b8630c3e11ba0ed0912e32447d1")]
[assembly: System.Reflection.AssemblyProductAttribute("MagicalDeckbuilder.Shared")]
[assembly: System.Reflection.AssemblyTitleAttribute("MagicalDeckbuilder.Shared")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfoInputs.cache b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfoInputs.cache
index 5367071..6c9ae05 100644
--- a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfoInputs.cache
+++ b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.AssemblyInfoInputs.cache
@@ -1 +1 @@
-1ddaddc2fae321d4d74da424f0e1537cf6791a6fd96dea468f06d21cc464409f
+6b78924099cb68fe483ef4bcddc5b5d283aa74fb2c2589d4081e19fb7961b6a7
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.csproj.CoreCompileInputs.cache b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.csproj.CoreCompileInputs.cache
index 02a6068..4771789 100644
--- a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.csproj.CoreCompileInputs.cache
+++ b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-7094ed9ecb5ee7c30c5a3060335603fdf50f1d365efe6b177e1195a2f408e1d1
+b278e861c1a8628ab259f6030168a03520298f979d38e6bbbb76c4018296aeac
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll
index 9bc5674..646d01f 100644
Binary files a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll and b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll differ
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb
index 3413794..98946ad 100644
Binary files a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb and b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb differ
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.sourcelink.json b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.sourcelink.json
index bbede61..0e32ee1 100644
--- a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.sourcelink.json
+++ b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/MagicalDeckbuilder.Shared.sourcelink.json
@@ -1 +1 @@
-{"documents":{"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\*":"https://raw.githubusercontent.com/alexandria121/new/f0b96ad03f0b23be73e6de74767c208f6b7756aa/*"}}
\ No newline at end of file
+{"documents":{"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\*":"https://raw.githubusercontent.com/alexandria121/new/f7db1d0d598c5b8630c3e11ba0ed0912e32447d1/*"}}
\ No newline at end of file
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/ref/MagicalDeckbuilder.Shared.dll b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/ref/MagicalDeckbuilder.Shared.dll
index f0511df..2280dce 100644
Binary files a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/ref/MagicalDeckbuilder.Shared.dll and b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/ref/MagicalDeckbuilder.Shared.dll differ
diff --git a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/refint/MagicalDeckbuilder.Shared.dll b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/refint/MagicalDeckbuilder.Shared.dll
index f0511df..2280dce 100644
Binary files a/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/refint/MagicalDeckbuilder.Shared.dll and b/MagicalDeckbuilder.Shared/obj/Debug/net9.0-windows/refint/MagicalDeckbuilder.Shared.dll differ
diff --git a/NewComboCards.cs b/NewComboCards.cs
new file mode 100644
index 0000000..77b3e74
--- /dev/null
+++ b/NewComboCards.cs
@@ -0,0 +1,73 @@
+// ============ NEW COMBO CARDS (6 cards, using valid ID formula) ============
+
+ // Combo 1: Irradiated Blob(1) + Heat Mote(10) = 1000 + (1*10) + 10 = 1010
+ var radioactiveHeat = CreateCreature("Radioactive Heat", "A bubbling mass of radioactive heat.\n[ABILITY: Meltdown - 3 MC, 5 DTT and +2P self-buff]",
+ ElementType.Radioactivity, 3, 4, 4, 2, false,
+ new List
+ {
+ new CardAbility { Name = "Meltdown", Description = "5 DTT and +2P self-buff", ManaCost = 3, EffectType = EffectType.Buff, EffectValue = 2, RequiresTarget = false }
+ });
+ radioactiveHeat.IsCombinable = true;
+ radioactiveHeat.IsComboOnly = true;
+ radioactiveHeat.TemplateId = 1010;
+ deck.Add(radioactiveHeat);
+
+ // Combo 2: Irradiated Blob(1) + Cold Mote(11) = 1000 + (1*10) + 11 = 1011
+ var frozenBlob = CreateCreature("Frozen Blob", "A frozen irradiated blob.\n[ABILITY: Cold Radiation - 25% freeze attacker]",
+ ElementType.Radioactivity, 2, 4, 5, 1, false,
+ new List
+ {
+ new CardAbility { Name = "Cold Radiation", Description = "25% freeze attacker", ManaCost = 0, EffectType = EffectType.Debuff, EffectValue = 1, IsPassive = true, RequiresTarget = false }
+ });
+ frozenBlob.IsCombinable = true;
+ frozenBlob.IsComboOnly = true;
+ frozenBlob.TemplateId = 1011;
+ deck.Add(frozenBlob);
+
+ // Combo 3: Heat Mote(10) + Cold Mote(11) = 1000 + (10*10) + 11 = 1111 (but 1111 is taken by Temp Mote - use 1012)
+ var thermalBalance = CreateCreature("Thermal Balance", "Balanced thermal energy.\n[ABILITY: Thermal Equilibrium - +2P and +2H]",
+ ElementType.Thermodynamics, 2, 4, 3, 1, false,
+ new List
+ {
+ new CardAbility { Name = "Thermal Equilibrium", Description = "+2P and +2H", ManaCost = 0, EffectType = EffectType.Buff, EffectValue = 2, IsPassive = true, RequiresTarget = false }
+ });
+ thermalBalance.IsCombinable = true;
+ thermalBalance.IsComboOnly = true;
+ thermalBalance.TemplateId = 1012;
+ deck.Add(thermalBalance);
+
+ // Combo 4: Heat Mote(10) + Heat Mote(10) = 1000 + (10*10) + 10 = 1010 (duplicate - use 1013)
+ var doubleHeat = CreateCreature("Double Heat", "Double the heat energy.\n[ABILITY: Heat Amplification - 30% double stats]",
+ ElementType.Thermodynamics, 2, 3, 2, 1, false,
+ new List
+ {
+ new CardAbility { Name = "Heat Amplification", Description = "30% double stats", ManaCost = 0, EffectType = EffectType.Buff, EffectValue = 2, IsPassive = true, RequiresTarget = false }
+ });
+ doubleHeat.IsCombinable = true;
+ doubleHeat.IsComboOnly = true;
+ doubleHeat.TemplateId = 1013;
+ deck.Add(doubleHeat);
+
+ // Combo 5: Cold Mote(11) + Cold Mote(11) = 1000 + (11*10) + 11 = 1121 (use 1014)
+ var doubleCold = CreateCreature("Double Cold", "Double the cold energy.\n[ABILITY: Cold Amplification - 30% double stats]",
+ ElementType.Thermodynamics, 2, 4, 2, 1, false,
+ new List
+ {
+ new CardAbility { Name = "Cold Amplification", Description = "30% double stats", ManaCost = 0, EffectType = EffectType.Buff, EffectValue = 2, IsPassive = true, RequiresTarget = false }
+ });
+ doubleCold.IsCombinable = true;
+ doubleCold.IsComboOnly = true;
+ doubleCold.TemplateId = 1014;
+ deck.Add(doubleCold);
+
+ // Combo 6: Irradiated Blob(1) + Anthropomorphized Meat(12) = 1000 + (1*10) + 12 = 1012? No wait - (1*10)+12 = 22, 1000+22=1022. But 1022 is Sponge Cakes. Use 1015.
+ var radioactiveMeat = CreateCreature("Radioactive Meat", "Flesh infused with radiation.\n[ABILITY: Radioactive Flesh - passive, radiate all attackers]",
+ ElementType.Radioactivity, 2, 6, 6, 1, false,
+ new List
+ {
+ new CardAbility { Name = "Radioactive Flesh", Description = "radiate all attackers", ManaCost = 0, EffectType = EffectType.Damage, EffectValue = 1, IsPassive = true, RequiresTarget = false }
+ });
+ radioactiveMeat.IsCombinable = true;
+ radioactiveMeat.IsComboOnly = true;
+ radioactiveMeat.TemplateId = 1015;
+ deck.Add(radioactiveMeat);
\ No newline at end of file
diff --git a/NewGame.UI/AppSettings.cs b/NewGame.UI/AppSettings.cs
new file mode 100644
index 0000000..0571d61
--- /dev/null
+++ b/NewGame.UI/AppSettings.cs
@@ -0,0 +1,66 @@
+using System.IO;
+using System.Text.Json;
+
+namespace NewGame.UI;
+
+///
+/// Application settings that persist across sessions
+///
+public class AppSettings
+{
+ private static readonly string SettingsFilePath = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
+ "MagicalDeckbuilder",
+ "settings.json");
+
+ public int StartingHealth { get; set; } = 30;
+
+ private static AppSettings? _instance;
+ public static AppSettings Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ _instance = Load();
+ }
+ return _instance;
+ }
+ }
+
+ public static AppSettings Load()
+ {
+ try
+ {
+ if (File.Exists(SettingsFilePath))
+ {
+ var json = File.ReadAllText(SettingsFilePath);
+ return JsonSerializer.Deserialize(json) ?? new AppSettings();
+ }
+ }
+ catch
+ {
+ // If loading fails, return defaults
+ }
+ return new AppSettings();
+ }
+
+ public void Save()
+ {
+ try
+ {
+ var directory = Path.GetDirectoryName(SettingsFilePath);
+ if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
+ {
+ Directory.CreateDirectory(directory);
+ }
+
+ var json = JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
+ File.WriteAllText(SettingsFilePath, json);
+ }
+ catch
+ {
+ // Silently fail if we can't save
+ }
+ }
+}
\ No newline at end of file
diff --git a/NewGame.UI/ViewModels/MainViewModel.cs b/NewGame.UI/ViewModels/MainViewModel.cs
index ec7eb18..67ebd75 100644
--- a/NewGame.UI/ViewModels/MainViewModel.cs
+++ b/NewGame.UI/ViewModels/MainViewModel.cs
@@ -1,6 +1,7 @@
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
+using System.Windows.Input;
using MagicalDeckbuilder.Cards;
using NewGame.UI.Views;
using MagicalDeckbuilder.Combining;
@@ -176,8 +177,8 @@ public class MainViewModel : ViewModelBase
_hasUnsavedDeckChanges = false;
}
- // Navigate to deck builder
- CurrentView = "DeckBuilder";
+ // Navigate to battle select to choose a battle
+ CurrentView = "BattleSelect";
}
private void LoadDeckIntoBuilder(SavedDeck deck)
@@ -1383,7 +1384,14 @@ public class MainViewModel : ViewModelBase
public bool CanCombine
{
get => _canCombine;
- set => SetProperty(ref _canCombine, value);
+ set
+ {
+ if (SetProperty(ref _canCombine, value))
+ {
+ // Force WPF to re-evaluate all commands (fixes button not enabling)
+ CommandManager.InvalidateRequerySuggested();
+ }
+ }
}
public bool IsComboLocked
@@ -1654,12 +1662,14 @@ public class MainViewModel : ViewModelBase
OpponentDeck.DrawCards(4);
RefreshOpponentHand();
- // Reset game state
- PlayerHealth = 30;
- PlayerMaxHealth = 30;
+ // Reset game state with player-configured starting health
+ var startingHealth = AppSettings.Instance.StartingHealth;
+ PlayerHealth = startingHealth;
+ PlayerMaxHealth = startingHealth;
PlayerMana = 2;
PlayerMaxMana = 10;
- OpponentHealth = 30;
+ OpponentHealth = startingHealth;
+ OpponentMaxHealth = startingHealth;
OpponentMana = 2;
OpponentMaxMana = 10;
TurnCount = 1;
@@ -3005,13 +3015,16 @@ public class MainViewModel : ViewModelBase
if (card1ToRemove != null) PlayerHand.Remove(card1ToRemove);
if (card2ToRemove != null) PlayerHand.Remove(card2ToRemove);
- ComboResult = new CardViewModel(newCard);
- CustomCards.Add(ComboResult);
- IsComboLocked = true;
- CanCombine = false;
+ // Create a ViewModel for the new card and add to hand
+ var newCardVM = new CardViewModel(newCard);
+ PlayerHand.Add(newCardVM);
+ PlayerDeck.Hand.Add(newCard);
StatusMessage = $"Created {newCard.Name}!";
OnPropertyChanged(nameof(PlayerHand));
+
+ // Clear the combo slots after successfully combining
+ ClearCombo();
}
///
@@ -3065,6 +3078,18 @@ public class MainViewModel : ViewModelBase
UpdateComboPreview();
}
+ public void RemoveFromComboSlot(int slot)
+ {
+ if (IsComboLocked) return;
+
+ if (slot == 1)
+ ComboCard1 = null;
+ else if (slot == 2)
+ ComboCard2 = null;
+
+ UpdateComboPreview();
+ }
+
private void UpdateComboPreview()
{
if (ComboCard1 == null || ComboCard2 == null)
diff --git a/NewGame.UI/Views/DeckBuilderView.xaml b/NewGame.UI/Views/DeckBuilderView.xaml
index b2e6f0c..7e208ac 100644
--- a/NewGame.UI/Views/DeckBuilderView.xaml
+++ b/NewGame.UI/Views/DeckBuilderView.xaml
@@ -35,9 +35,10 @@
Command="{Binding ClearDeckCommand}"
Margin="10,0,0,0"
Padding="15,6"/>
-
diff --git a/NewGame.UI/Views/GameView.xaml b/NewGame.UI/Views/GameView.xaml
index 3600b47..c5f1452 100644
--- a/NewGame.UI/Views/GameView.xaml
+++ b/NewGame.UI/Views/GameView.xaml
@@ -594,6 +594,10 @@
+
@@ -608,6 +612,10 @@
+
diff --git a/NewGame.UI/Views/GameView.xaml.cs b/NewGame.UI/Views/GameView.xaml.cs
index 0d2968a..81b1aaa 100644
--- a/NewGame.UI/Views/GameView.xaml.cs
+++ b/NewGame.UI/Views/GameView.xaml.cs
@@ -243,6 +243,18 @@ public partial class GameView : UserControl
// Combo slots don't support drag out currently
}
+ private void OnComboSlot1RemoveClick(object sender, System.Windows.RoutedEventArgs e)
+ {
+ ViewModel?.RemoveFromComboSlot(1);
+ e.Handled = true;
+ }
+
+ private void OnComboSlot2RemoveClick(object sender, System.Windows.RoutedEventArgs e)
+ {
+ ViewModel?.RemoveFromComboSlot(2);
+ e.Handled = true;
+ }
+
private void OnComboResultDragEnter(object sender, DragEventArgs e)
{
if (sender is Border comboSlot && ViewModel?.IsComboLocked == true)
diff --git a/NewGame.UI/Views/SettingsView.xaml b/NewGame.UI/Views/SettingsView.xaml
index 9319b12..d06e68b 100644
--- a/NewGame.UI/Views/SettingsView.xaml
+++ b/NewGame.UI/Views/SettingsView.xaml
@@ -18,12 +18,6 @@
-
@@ -183,6 +177,26 @@
Content="Show Tutorial Hints"
IsChecked="True"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NewGame.UI/Views/SettingsView.xaml.cs b/NewGame.UI/Views/SettingsView.xaml.cs
index 0bce3d3..ed33765 100644
--- a/NewGame.UI/Views/SettingsView.xaml.cs
+++ b/NewGame.UI/Views/SettingsView.xaml.cs
@@ -1,4 +1,6 @@
using System.Windows.Controls;
+using System.Windows;
+using NewGame.UI.ViewModels;
namespace NewGame.UI.Views;
@@ -7,5 +9,32 @@ public partial class SettingsView : UserControl
public SettingsView()
{
InitializeComponent();
+ LoadSettings();
+ }
+
+ private void LoadSettings()
+ {
+ // Set the dropdown to current setting value
+ var currentHealth = AppSettings.Instance.StartingHealth;
+ foreach (ComboBoxItem item in StartingHealthCombo.Items)
+ {
+ if (item.Tag is string tag && int.TryParse(tag, out int value) && value == currentHealth)
+ {
+ item.IsSelected = true;
+ break;
+ }
+ }
+ }
+
+ private void StartingHealthCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (StartingHealthCombo.SelectedItem is ComboBoxItem item && item.Tag is string tag)
+ {
+ if (int.TryParse(tag, out int health))
+ {
+ AppSettings.Instance.StartingHealth = health;
+ AppSettings.Instance.Save();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll b/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll
index 9bc5674..646d01f 100644
Binary files a/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll and b/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.dll differ
diff --git a/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb b/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb
index 3413794..98946ad 100644
Binary files a/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb and b/NewGame.UI/bin/Debug/net9.0-windows/MagicalDeckbuilder.Shared.pdb differ
diff --git a/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.dll b/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.dll
index 28df471..f20aa51 100644
Binary files a/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.dll and b/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.dll differ
diff --git a/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.exe b/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.exe
index b71c22c..105ed50 100644
Binary files a/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.exe and b/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.exe differ
diff --git a/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.pdb b/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.pdb
index 0ef7f2f..bfdd08e 100644
Binary files a/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.pdb and b/NewGame.UI/bin/Debug/net9.0-windows/NewGame.UI.pdb differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfo.cs b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfo.cs
index 924cce7..89d3ebf 100644
--- a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfo.cs
+++ b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfo.cs
@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("NewGame.UI")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
-[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+f0b96ad03f0b23be73e6de74767c208f6b7756aa")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+f7db1d0d598c5b8630c3e11ba0ed0912e32447d1")]
[assembly: System.Reflection.AssemblyProductAttribute("NewGame.UI")]
[assembly: System.Reflection.AssemblyTitleAttribute("NewGame.UI")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfoInputs.cache b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfoInputs.cache
index f2a363d..0c1f18f 100644
--- a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfoInputs.cache
+++ b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.AssemblyInfoInputs.cache
@@ -1 +1 @@
-4d6a608fd9add8622cd9f8ac759445ab64b698f21e01f56ae0384dba47bd21f5
+f1693528d19ae061ce534d293972e238a182f27495fa5392bf1ecd6827d7f255
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.AssemblyReference.cache b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.AssemblyReference.cache
index b0ef5b3..8f3e4f4 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.AssemblyReference.cache and b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.AssemblyReference.cache differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.CoreCompileInputs.cache b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.CoreCompileInputs.cache
index aff2590..f0ef128 100644
--- a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.CoreCompileInputs.cache
+++ b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-69bbccbc3428be626512f345ad4f88beec926c5703a9f301574e9070b9f50eb8
+29160f55f2fbc01cb3ad50919bd7f21b6f9985a2b447e7658d489f7f9fff7809
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.dll b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.dll
index 28df471..f20aa51 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.dll and b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.dll differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.g.resources b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.g.resources
index c610397..4bf6696 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.g.resources and b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.g.resources differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.pdb b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.pdb
index 0ef7f2f..bfdd08e 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.pdb and b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.pdb differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.sourcelink.json b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.sourcelink.json
index bbede61..0e32ee1 100644
--- a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.sourcelink.json
+++ b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI.sourcelink.json
@@ -1 +1 @@
-{"documents":{"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\*":"https://raw.githubusercontent.com/alexandria121/new/f0b96ad03f0b23be73e6de74767c208f6b7756aa/*"}}
\ No newline at end of file
+{"documents":{"C:\\Users\\atw61\\OneDrive\\Desktop\\new\\*":"https://raw.githubusercontent.com/alexandria121/new/f7db1d0d598c5b8630c3e11ba0ed0912e32447d1/*"}}
\ No newline at end of file
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI_MarkupCompile.cache b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI_MarkupCompile.cache
index 4636481..c1e1389 100644
--- a/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI_MarkupCompile.cache
+++ b/NewGame.UI/obj/Debug/net9.0-windows/NewGame.UI_MarkupCompile.cache
@@ -12,7 +12,7 @@ TRACE;DEBUG;NET;NET9_0;NETCOREAPP;WINDOWS;WINDOWS7_0;NET5_0_OR_GREATER;NET6_0_OR
C:\Users\atw61\OneDrive\Desktop\new\NewGame.UI\App.xaml
15-1449266402
-23-1598940802
+242056503056
202364243512
Controls\CardZoomOverlay.xaml;MainWindow.xaml;Styles\BaseStyles.xaml;Views\BattleSelectView.xaml;Views\BrowserView.xaml;Views\DeckBuilderView.xaml;Views\DeckNameDialog.xaml;Views\DeckSelectionView.xaml;Views\ErrorWindow.xaml;Views\GalleryView.xaml;Views\GameEndWindow.xaml;Views\GameView.xaml;Views\MenuView.xaml;Views\SettingsView.xaml;Views\UnsavedChangesDialog.xaml;
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.baml b/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.baml
index 22f5157..2f497bd 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.baml and b/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.baml differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.g.cs b/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.g.cs
index b1e15dd..bde3e1d 100644
--- a/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.g.cs
+++ b/NewGame.UI/obj/Debug/net9.0-windows/Views/DeckBuilderView.g.cs
@@ -1,4 +1,4 @@
-#pragma checksum "..\..\..\..\Views\DeckBuilderView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5973C5A6558CB8EDB97951FFFEF36F8E978EB512"
+#pragma checksum "..\..\..\..\Views\DeckBuilderView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "A7D863CC839B06150B5647659C62E953CFBBEB0E"
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
@@ -73,13 +73,13 @@ namespace NewGame.UI.Views {
{
case 2:
- #line 262 "..\..\..\..\Views\DeckBuilderView.xaml"
+ #line 263 "..\..\..\..\Views\DeckBuilderView.xaml"
((System.Windows.Controls.Border)(target)).Drop += new System.Windows.DragEventHandler(this.Deck_Drop);
#line default
#line hidden
- #line 263 "..\..\..\..\Views\DeckBuilderView.xaml"
+ #line 264 "..\..\..\..\Views\DeckBuilderView.xaml"
((System.Windows.Controls.Border)(target)).DragOver += new System.Windows.DragEventHandler(this.Deck_DragOver);
#line default
@@ -100,13 +100,13 @@ namespace NewGame.UI.Views {
{
case 1:
- #line 89 "..\..\..\..\Views\DeckBuilderView.xaml"
+ #line 90 "..\..\..\..\Views\DeckBuilderView.xaml"
((System.Windows.Controls.Border)(target)).MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.Card_MouseLeftButtonDown);
#line default
#line hidden
- #line 90 "..\..\..\..\Views\DeckBuilderView.xaml"
+ #line 91 "..\..\..\..\Views\DeckBuilderView.xaml"
((System.Windows.Controls.Border)(target)).MouseMove += new System.Windows.Input.MouseEventHandler(this.Card_MouseMove);
#line default
@@ -114,7 +114,7 @@ namespace NewGame.UI.Views {
break;
case 3:
- #line 295 "..\..\..\..\Views\DeckBuilderView.xaml"
+ #line 296 "..\..\..\..\Views\DeckBuilderView.xaml"
((System.Windows.Controls.Border)(target)).MouseRightButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.DeckCard_RightClick);
#line default
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.baml b/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.baml
index 2926d28..df9fc7d 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.baml and b/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.baml differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.g.cs b/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.g.cs
index 870821b..2f6796f 100644
--- a/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.g.cs
+++ b/NewGame.UI/obj/Debug/net9.0-windows/Views/GameView.g.cs
@@ -1,4 +1,4 @@
-#pragma checksum "..\..\..\..\Views\GameView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "90FE191AABFB04429CC2634EA11E5D741FA94B1B"
+#pragma checksum "..\..\..\..\Views\GameView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "386C2B8B70E223F0F7E6CA5A081D4FA4D44C4368"
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
@@ -51,7 +51,7 @@ namespace NewGame.UI.Views {
#line hidden
- #line 601 "..\..\..\..\Views\GameView.xaml"
+ #line 605 "..\..\..\..\Views\GameView.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.Border ComboSlot2;
@@ -59,7 +59,7 @@ namespace NewGame.UI.Views {
#line hidden
- #line 638 "..\..\..\..\Views\GameView.xaml"
+ #line 646 "..\..\..\..\Views\GameView.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal NewGame.UI.Controls.CardZoomOverlay CardZoomPopup;
@@ -313,53 +313,69 @@ namespace NewGame.UI.Views {
#line hidden
return;
case 17:
- this.ComboSlot2 = ((System.Windows.Controls.Border)(target));
- #line 602 "..\..\..\..\Views\GameView.xaml"
- this.ComboSlot2.Drop += new System.Windows.DragEventHandler(this.OnComboSlot2Drop);
-
- #line default
- #line hidden
-
- #line 602 "..\..\..\..\Views\GameView.xaml"
- this.ComboSlot2.DragEnter += new System.Windows.DragEventHandler(this.OnComboSlotDragEnter);
-
- #line default
- #line hidden
-
- #line 602 "..\..\..\..\Views\GameView.xaml"
- this.ComboSlot2.DragLeave += new System.Windows.DragEventHandler(this.OnComboSlotDragLeave);
-
- #line default
- #line hidden
-
- #line 602 "..\..\..\..\Views\GameView.xaml"
- this.ComboSlot2.MouseMove += new System.Windows.Input.MouseEventHandler(this.OnComboSlotMouseMove);
+ #line 599 "..\..\..\..\Views\GameView.xaml"
+ ((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnComboSlot1RemoveClick);
#line default
#line hidden
return;
case 18:
+ this.ComboSlot2 = ((System.Windows.Controls.Border)(target));
- #line 619 "..\..\..\..\Views\GameView.xaml"
- ((System.Windows.Controls.Border)(target)).Drop += new System.Windows.DragEventHandler(this.OnComboResultDrop);
+ #line 606 "..\..\..\..\Views\GameView.xaml"
+ this.ComboSlot2.Drop += new System.Windows.DragEventHandler(this.OnComboSlot2Drop);
#line default
#line hidden
- #line 619 "..\..\..\..\Views\GameView.xaml"
- ((System.Windows.Controls.Border)(target)).DragEnter += new System.Windows.DragEventHandler(this.OnComboResultDragEnter);
+ #line 606 "..\..\..\..\Views\GameView.xaml"
+ this.ComboSlot2.DragEnter += new System.Windows.DragEventHandler(this.OnComboSlotDragEnter);
#line default
#line hidden
- #line 619 "..\..\..\..\Views\GameView.xaml"
- ((System.Windows.Controls.Border)(target)).DragLeave += new System.Windows.DragEventHandler(this.OnComboResultDragLeave);
+ #line 606 "..\..\..\..\Views\GameView.xaml"
+ this.ComboSlot2.DragLeave += new System.Windows.DragEventHandler(this.OnComboSlotDragLeave);
+
+ #line default
+ #line hidden
+
+ #line 606 "..\..\..\..\Views\GameView.xaml"
+ this.ComboSlot2.MouseMove += new System.Windows.Input.MouseEventHandler(this.OnComboSlotMouseMove);
#line default
#line hidden
return;
case 19:
+
+ #line 617 "..\..\..\..\Views\GameView.xaml"
+ ((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnComboSlot2RemoveClick);
+
+ #line default
+ #line hidden
+ return;
+ case 20:
+
+ #line 627 "..\..\..\..\Views\GameView.xaml"
+ ((System.Windows.Controls.Border)(target)).Drop += new System.Windows.DragEventHandler(this.OnComboResultDrop);
+
+ #line default
+ #line hidden
+
+ #line 627 "..\..\..\..\Views\GameView.xaml"
+ ((System.Windows.Controls.Border)(target)).DragEnter += new System.Windows.DragEventHandler(this.OnComboResultDragEnter);
+
+ #line default
+ #line hidden
+
+ #line 627 "..\..\..\..\Views\GameView.xaml"
+ ((System.Windows.Controls.Border)(target)).DragLeave += new System.Windows.DragEventHandler(this.OnComboResultDragLeave);
+
+ #line default
+ #line hidden
+ return;
+ case 21:
this.CardZoomPopup = ((NewGame.UI.Controls.CardZoomOverlay)(target));
return;
}
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/apphost.exe b/NewGame.UI/obj/Debug/net9.0-windows/apphost.exe
index b71c22c..105ed50 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/apphost.exe and b/NewGame.UI/obj/Debug/net9.0-windows/apphost.exe differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/ref/NewGame.UI.dll b/NewGame.UI/obj/Debug/net9.0-windows/ref/NewGame.UI.dll
index a1a7b6f..06bc53a 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/ref/NewGame.UI.dll and b/NewGame.UI/obj/Debug/net9.0-windows/ref/NewGame.UI.dll differ
diff --git a/NewGame.UI/obj/Debug/net9.0-windows/refint/NewGame.UI.dll b/NewGame.UI/obj/Debug/net9.0-windows/refint/NewGame.UI.dll
index a1a7b6f..06bc53a 100644
Binary files a/NewGame.UI/obj/Debug/net9.0-windows/refint/NewGame.UI.dll and b/NewGame.UI/obj/Debug/net9.0-windows/refint/NewGame.UI.dll differ
diff --git a/add_combos.ps1 b/add_combos.ps1
new file mode 100644
index 0000000..dcf3520
--- /dev/null
+++ b/add_combos.ps1
@@ -0,0 +1,17 @@
+$lines = Get-Content 'c:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\Game\CardFactory.cs'
+$insertLines = Get-Content 'c:\Users\atw61\OneDrive\Desktop\new\NewComboCards.cs'
+$output = @()
+$found = $false
+
+foreach ($line in $lines) {
+ if ($line -eq ' return deck;' -and -not $found) {
+ foreach ($il in $insertLines) {
+ $output += $il
+ }
+ $found = $true
+ }
+ $output += $line
+}
+
+Set-Content 'c:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\Game\CardFactory.cs' $output
+Write-Host "Done! Added 25 combo cards."
\ No newline at end of file
diff --git a/find_ids.ps1 b/find_ids.ps1
new file mode 100644
index 0000000..8c80f56
--- /dev/null
+++ b/find_ids.ps1
@@ -0,0 +1,12 @@
+$content = Get-Content 'c:\Users\atw61\OneDrive\Desktop\new\MagicalDeckbuilder.Shared\Game\CardFactory.cs' -Raw
+$matches = [regex]::Matches($content, 'ID: (1[0-9]{3})')
+$usedIds = @()
+foreach ($m in $matches) {
+ $usedIds += [int]$m.Groups[1].Value
+}
+$usedIds = $usedIds | Sort-Object -Unique
+
+$allIds = 1000..1300
+$availableIds = $allIds | Where-Object { $_ -notin $usedIds }
+Write-Host "Available count: $($availableIds.Count)"
+Write-Host "Available (first 35): $($availableIds[0..34] -join ', ')"
\ No newline at end of file