Example #1
0
        public static bool TryFromCode(string code, Catalog catalog, out Deck? deck)
        {
            IReadOnlyList<RawCardAndCount> rccs;
            try
            {
                rccs = Coding.GetDeckCardsFromCode(code);
            }
            catch
            {
                deck = null;
                return false;
            }

            var ccs = new CardAndCount[rccs.Count];

            for (var i = 0; i < rccs.Count; i++)
            {
                RawCardAndCount rcc = rccs[i];
                LorFaction? region = catalog.Regions.Values.SingleOrDefault(r => r.Index == rcc.Faction);
                if (region is null)
                {
                    deck = null;
                    return false;
                }

                string ss = rcc.Set.ToString().PadLeft(2, '0');
                string ff = region.Abbreviation;
                string nnn = rcc.Number.ToString().PadLeft(3, '0');
                string cardCode = $"{ss}{ff}{nnn}";

                if (!catalog.Cards.TryGetValue(cardCode, out ICard? card))
                {
                    if (!CardCode.TryFromString(cardCode, out CardCode? outCardCode))
                    {
                        deck = null;
                        return false;
                    }

                    LorSet? set = catalog.Sets.Values.SingleOrDefault(s => s.Index == rcc.Set);
                    card = new CodeOnlyCard(outCardCode!, catalog.Locale, catalog.Version, region, set);
                }

                ccs[i] = new CardAndCount(card, rcc.Count);
            }

            deck = new Deck(code, catalog.Locale, catalog.Version, ccs);
            return true;
        }
Example #2
0
        public Catalog MakeCatalog()
        {
            // Convert collections of items from Data Dragon globals DTOs

            Dictionary <string, LorVocabTerm> vocabTerms = ConvertDdItems <DdVocabTerm, LorVocabTerm>(Globals.VocabTerms, "vocabTerms", LorVocabTerm.TryFromDataDragon);

            Dictionary <string, LorKeyword> keywords = ConvertDdItems <DdKeyword, LorKeyword>(Globals.Keywords, "keywords", LorKeyword.TryFromDataDragon);

            Dictionary <string, LorFaction> regions = ConvertIndexedDdItems <DdRegion, LorFaction>(Globals.Regions, "regions", LorFaction.TryFromDataDragon, RegionIndices);

            Dictionary <string, LorSpellSpeed> spellSpeeds = ConvertDdItems <DdSpellSpeed, LorSpellSpeed>(Globals.SpellSpeeds, "spellSpeeds", LorSpellSpeed.TryFromDataDragon);

            Dictionary <string, LorRarity> rarities = ConvertDdItems <DdRarity, LorRarity>(Globals.Rarities, "rarities", LorRarity.TryFromDataDragon);

            Dictionary <string, LorSet> sets = ConvertIndexedDdItems <DdSet, LorSet>(Globals.Sets, "sets", LorSet.TryFromDataDragon, SetIndices);

            // Populate collections of [super/sub]types manually from list of cards

            var supertypes   = new List <LorSupertype>();
            var supertypeDic = new Dictionary <string, LorSupertype>();

            foreach (string supertypeRef in DdCards
                     .Select(c => c.Supertype)
                     .Where(s => !string.IsNullOrWhiteSpace(s))
                     .Select(s => s !)
                     .Distinct())
            {
                string name      = TextInfo.ToTitleCase(TextInfo.ToLower(supertypeRef));
                var    supertype = new LorSupertype(name);
                supertypes.Add(supertype);
                supertypeDic.Add(supertypeRef, new LorSupertype(name));
            }

            var types   = new List <LorType>();
            var typeDic = new Dictionary <string, LorType>();

            foreach (string typeRef in DdCards
                     .Select(c => c.Type)
                     .Where(s => !string.IsNullOrWhiteSpace(s))
                     .Select(s => s !)
                     .Distinct())
            {
                string name = TextInfo.ToTitleCase(TextInfo.ToLower(typeRef));
                var    type = new LorType(name);
                types.Add(type);
                typeDic.Add(typeRef, type);
            }

            var subtypes   = new List <LorSubtype>();
            var subtypeDic = new Dictionary <string, LorSubtype>();

            foreach (string subtypeRef in DdCards
                     .SelectMany(c => c.GetDistinctSubtypes())
                     .Distinct())
            {
                string name    = TextInfo.ToTitleCase(TextInfo.ToLower(subtypeRef));
                var    subtype = new LorSubtype(name);
                subtypes.Add(subtype);
                subtypeDic.Add(subtypeRef, subtype);
            }

            // First card pass to initialize cards and add them to lookup

            var cards = new Dictionary <string, ICard>();

            foreach (DdCard ddCard in DdCards)
            {
                if (ddCard.CardCode is null)
                {
                    string name = ddCard.Name ?? "[Unnamed card]";
                    Logger.LogWarning($"{name} does not have a card code. Ignoring card.");
                    continue;
                }

                if (!CardCode.TryFromString(ddCard.CardCode, out CardCode? cardCode))
                {
                    Logger.LogWarning($"Could not parse the card code '{cardCode}'. Ignoring card.");
                    continue;
                }

                var card = new BasicCard(cardCode !, Locale, Version, ddCard.Name);
                if (!cards.TryAdd(ddCard.CardCode, card))
                {
                    Logger.LogWarning($"Multiple cards have the card code '{cardCode}'. Ignoring this duplicate card.");
                    continue;
                }

                AddPropToCard(card, ddCard.RegionRef, "RegionRef", regions, (c, v) => c.Region         = v);
                AddPropToCard(card, ddCard.Supertype, "Supertype", supertypeDic, (c, v) => c.Supertype = v);
                AddPropToCard(card, ddCard.Type, "Type", typeDic, (c, v) => c.Type = v);
                AddPropToCard(card, ddCard.SpellSpeedRef, "SpellSpeedRef", spellSpeeds, (c, v) => c.SpellSpeed = v);
                AddPropToCard(card, ddCard.Set, "Set", sets, (c, v) => c.Set = v);
                AddPropToCard(card, ddCard.RarityRef, "RarityRef", rarities, (c, v) => c.Rarity = v);

                AddPropListToCard(card, ddCard.RegionRefs, "RegionRef", regions, (c, vs) => c.Regions     = vs);
                AddPropListToCard(card, ddCard.Subtypes, "Subtype", subtypeDic, (c, vs) => c.Subtypes     = vs);
                AddPropListToCard(card, ddCard.KeywordRefs, "KeywordRef", keywords, (c, vs) => c.Keywords = vs);

                card.Cost                  = ddCard.Cost;
                card.Attack                = ddCard.Attack;
                card.Health                = ddCard.Health;
                card.Collectible           = ddCard.Collectible;
                card.Description           = ddCard.Description;
                card.DescriptionRaw        = ddCard.DescriptionRaw;
                card.LevelupDescription    = ddCard.LevelupDescription;
                card.LevelupDescriptionRaw = ddCard.LevelupDescriptionRaw;
                card.FlavorText            = ddCard.FlavorText;
                card.ArtistName            = ddCard.ArtistName;

                if (ddCard.Assets != null && ddCard.Assets.Length > 0)
                {
                    string?gamePath = ddCard.Assets[0].GameAbsolutePath;
                    if (gamePath != null)
                    {
                        card.GameArtPath = new Uri(gamePath);
                    }

                    string?fullPath = ddCard.Assets[0].FullAbsolutePath;
                    if (fullPath != null)
                    {
                        card.FullArtPath = new Uri(fullPath);
                    }
                }
            }

            // Second card pass to fill in associated card references

            foreach (DdCard ddCard in DdCards)
            {
                if (ddCard.AssociatedCardRefs is null)
                {
                    continue;
                }

                if (ddCard.CardCode is null)
                {
                    continue;
                }

                string code = ddCard.CardCode !;

                if (!cards.TryGetValue(code, out ICard? card))
                {
                    continue;
                }

                var assoCards = new List <ICard>();
                foreach (string assoCode in ddCard.AssociatedCardRefs)
                {
                    if (cards.TryGetValue(assoCode, out ICard? assoCard))
                    {
                        assoCards.Add(assoCard);
                    }
                    else
                    {
                        Logger.LogWarning($"{card} has an associated card with the code '{assoCode}' that isn't in the card collection. Ignoring this associated card.");
                    }
                }

                // Small hack to cast the card to its known BasicCard type since C# can't make the cards dictionary covariant
                (card as BasicCard) !.AssociatedCards = assoCards;
            }

            // Return the finished product

            return(new Catalog(Locale, Version)
            {
                VocabTerms = vocabTerms,
                Keywords = keywords,
                Regions = regions,
                SpellSpeeds = spellSpeeds,
                Rarities = rarities,
                Sets = sets,
                Supertypes = supertypes,
                Types = types,
                Subtypes = subtypes,
                Cards = cards,
            });
        }