示例#1
0
        // Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Skill"/> class.
        /// </summary>
        /// <param name="prefix">Prefix.</param>
        /// <param name="suffix">Suffix.</param>
        /// <param name="x">Primary modifier.</param>
        /// <param name="y">Secondary modifier.</param>
        public Skill(SkillPrefix prefix, SkillSuffix suffix, int x = 0, int y = 0)
        {
            if ((int)prefix < 0 || (int)prefix > Constants.EnumMaxAllowedValues.SkillPrefix)
            {
                throw new ArgumentOutOfRangeException(nameof(prefix), prefix, "Must be a valid " + nameof(SkillPrefix));
            }
            if ((int)suffix < 0 || (int)suffix > Constants.EnumMaxAllowedValues.SkillSuffix)
            {
                throw new ArgumentOutOfRangeException(nameof(suffix), suffix, "Must be a valid " + nameof(SkillSuffix));
            }
            if (suffix == SkillSuffix.None)
            {
                throw new ArgumentException("Can't be None (0)", nameof(suffix));
            }
            if (x < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(x), x, "Must be greater than or equal to 0");
            }
            if (y < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(y), y, "Must be greater than or equal to 0");
            }

            Prefix = prefix;
            Suffix = suffix;
            X      = x;
            Y      = y;
        }
示例#2
0
        private static Skill ParseAbility(string abilityString)
        {
            if (abilityString == "No ability")
            {
                return(Skill.NoAbility);
            }

            // -- Exceptional cases --

            // There are some cases that hold enough inconsistency that justify exceptional cases in the parser

            // Exceptional case: Balorg (ID = 1195). Every card with a prefix has a colon (:) after the prefix. This one has a semicolon (;)
            // Why: The alternative is add an extra case on the regex "PrefixAndSuffix"
            if (abilityString == "Courage; -2 Opp Pillz. Min 1")
            {
                return(new Skill(SkillPrefix.Courage, SkillSuffix.DecreasePillzXMinY, 2, 1));
            }

            // Exceptional case: DJ Korps (ID = 1260). Every card has a single prefix, or none. This one has a double prefix
            // Why: The alternative is add a loop that calls (at least) two times the regex "PrefixAndSuffix" for each parse
            if (abilityString == "Defeat: Growth: -1 Opp. Life, Min 1")
            {
                return(new Skill(SkillPrefix.GrowthAndDefeat, SkillSuffix.DecreaseLifeXMinY, 1, 1));
            }

            // Exceptional case: Excess LD (ID = 1678). Every card has a single prefix, or none. This one has a double prefix
            // Why: The alternative is add a loop that calls (at least) two times the regex "PrefixAndSuffix" for each parse
            if (abilityString == "Stop: Victory Or Defeat : +3 Life")
            {
                return(null);
            }

            // Exceptional case: Ghoonbones (ID = 1755). Every card has a single prefix, or none. This one has a double prefix
            // Why: The alternative is add a loop that calls (at least) two times the regex "PrefixAndSuffix" for each parse
            if (abilityString == "Backlash: Growth: - 1 Life Min 2")
            {
                return(null);
            }

            // Exceptional case: Hydraereva (ID = 1619). Every card has a single prefix, or none. This one has a double prefix
            // Why: The alternative is add a loop that calls (at least) two times the regex "PrefixAndSuffix" for each parse
            if (abilityString == "Defeat: Equalizer: +1 Life")
            {
                return(null);
            }

            // Exceptional case: Xantiax Robb Cr (ID = 1573). Is the only card with this prefix.
            // Why: It is a new prefix that resembles to Backlash and Victory or Defeat. Needs to much work for a single card by now.
            if (abilityString == "Xantiax: -3 Life, Min. 0")
            {
                return(null);
            }

            // Exceptional case: Silvano (ID = 1714). Every card has a single prefix, or none. This one has a double prefix
            // Why: The alternative is add a loop that calls (at least) two times the regex "PrefixAndSuffix" for each parse
            if (abilityString == "Defeat: Brawl: +1 Life")
            {
                return(null);
            }
            //


            // -- End Exceptional cases --

            // Leaders
            switch (abilityString)
            {
            case "Team: Courage, Power +3, Max. 10":
                return(new Skill(SkillLeader.Ambre));

            case "Counter-attack":
                return(new Skill(SkillLeader.Ashigaru));

            case "+1 Life Per Round":
                return(new Skill(SkillLeader.Bridget));

            case "-1 Opp. Pillz, Per Round, Min 3":
                return(new Skill(SkillLeader.Eklore));

            case "Team: -1 Opp. Power, Min 5":
                return(new Skill(SkillLeader.Eyrik));

            case "Team: +6 Attack":
                return(new Skill(SkillLeader.Hugo));

            case "Team: Reprisal: -2 Pow. & Dmg, Min 3":
                return(new Skill(SkillLeader.JonhDoom));

            case "Team: Defeat: Rec. 1 Pillz Out Of 2":
                return(new Skill(SkillLeader.Melody));

            case "+1 Pillz Per Round, Max. 10":
                return(new Skill(SkillLeader.Morphun));

            case "Nuke":
                return(new Skill(SkillLeader.MrBigDuke));

            case "Bypass":
                return(new Skill(SkillLeader.RobbertCobb));

            case "Tie-break":
                return(new Skill(SkillLeader.Solomon));

            case "Team: +1 Damage":
                return(new Skill(SkillLeader.Timber));

            case "Team: Xp +90%":
                return(new Skill(SkillLeader.Vansaar));

            case "Team: -2 Opp. Damage, Min 4":
                return(new Skill(SkillLeader.Vholt));
            }

            string      prefixText, suffixText;
            SkillPrefix prefix = SkillPrefix.None;
            SkillSuffix suffix = SkillSuffix.None;
            string      x      = "0";
            string      y      = "0";

            var match = UsedRegex.PrefixAndSuffix.Match(abilityString);

            if (match.Groups["prefix"].Captures.Count != 0)
            {
                // This ability has both prefix and suffix
                prefixText = match.Groups["prefix"].Captures[0].Value;
                suffixText = match.Groups["suffix"].Captures[0].Value;
            }
            else
            {
                // This skill only has suffix
                prefixText = "";
                suffixText = abilityString;
            }

            // -- Prefix --
            switch (prefixText)
            {
            case "Backlash":
                prefix = SkillPrefix.Backlash;
                break;

            case "Brawl":
                prefix = SkillPrefix.Brawl;
                break;

            case "Confidence":
                prefix = SkillPrefix.Confidence;
                break;

            case "Courage":
                prefix = SkillPrefix.Courage;
                break;

            case "Defeat":
                prefix = SkillPrefix.Defeat;
                break;

            case "Degrowth":
                prefix = SkillPrefix.Degrowth;
                break;

            case "Equalizer":
                prefix = SkillPrefix.Equalizer;
                break;

            case "Growth":
                prefix = SkillPrefix.Growth;
                break;

            case "Killshot":
                prefix = SkillPrefix.Killshot;
                break;

            case "Reprisal":
                prefix = SkillPrefix.Reprisal;
                break;

            case "Revenge":
                prefix = SkillPrefix.Revenge;
                break;

            case "Stop":
                prefix = SkillPrefix.Stop;
                break;

            case "Support":
                prefix = SkillPrefix.Support;
                break;

            case "Victory Or Defeat":
            case "Vict. Or Def.":
                prefix = SkillPrefix.VictoryOrDefeat;
                break;

            default:
                prefix = SkillPrefix.None;
                break;
            }
            // -- End Prefix

            // -- Suffix --
            // CancelLeader and ProtectAbility cannot be valid Ability Suffixes, so they are not included here
            if (UsedRegex.Suffix.CancelAttackModifier.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CancelAttackModifier;
            }
            else if (UsedRegex.Suffix.CancelDamageModifier.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CancelDamageModifier;
            }
            else if (UsedRegex.Suffix.CancelLifeModifier.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CancelLifeModifier;
            }
            else if (UsedRegex.Suffix.CancelPillzAndLifeModifier.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CancelPillzAndLifeModifier;
            }
            else if (UsedRegex.Suffix.CancelPillzModifier.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CancelPillzModifier;
            }
            else if (UsedRegex.Suffix.CancelPowerAndDamageModifier.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CancelPowerAndDamageModifier;
            }
            else if (UsedRegex.Suffix.CancelPowerModifier.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CancelPowerModifier;
            }
            else if (UsedRegex.Suffix.ConsumeXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.ConsumeXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.ConsumeXMinY;
            }
            else if (UsedRegex.Suffix.CopyBonus.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CopyBonus;
            }
            else if (UsedRegex.Suffix.CopyDamage.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CopyDamage;
            }
            else if (UsedRegex.Suffix.CopyPower.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CopyPower;
            }
            else if (UsedRegex.Suffix.CopyPowerAndDamage.IsMatch(suffixText))
            {
                suffix = SkillSuffix.CopyPowerAndDamage;
            }
            else if (UsedRegex.Suffix.CorrosionXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.CorrosionXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.CorrosionXMinY;
            }
            else if (UsedRegex.Suffix.DecreaseAttackXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreaseAttackXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreaseAttackXMinY;
            }
            else if (UsedRegex.Suffix.DecreaseAttackXPerRemainingLifeMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreaseAttackXPerRemainingLifeMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreaseAttackXPerRemainingLifeMinY;
            }
            else if (UsedRegex.Suffix.DecreaseAttackXPerRemainingPillzMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreaseAttackXPerRemainingPillzMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreaseAttackXPerRemainingPillzMinY;
            }
            else if (UsedRegex.Suffix.DecreaseDamageXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreaseDamageXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreaseDamageXMinY;
            }
            else if (UsedRegex.Suffix.DecreaseLifeAndPillzXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreaseLifeAndPillzXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreaseLifeAndPillzXMinY;
            }
            else if (UsedRegex.Suffix.DecreaseLifeXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreaseLifeXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreaseLifeXMinY;
            }
            else if (UsedRegex.Suffix.DecreasePillzXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreasePillzXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreasePillzXMinY;
            }
            else if (UsedRegex.Suffix.DecreasePowerAndDamageXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreasePowerAndDamageXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreasePowerAndDamageXMinY;
            }
            else if (UsedRegex.Suffix.DecreasePowerXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DecreasePowerXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DecreasePowerXMinY;
            }
            else if (UsedRegex.Suffix.DopeXMaxY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.DopeXMaxY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.DopeXMaxY;
            }
            else if (UsedRegex.Suffix.ExchangeDamage.IsMatch(suffixText))
            {
                suffix = SkillSuffix.ExchangeDamage;
            }
            else if (UsedRegex.Suffix.ExchangePower.IsMatch(suffixText))
            {
                suffix = SkillSuffix.ExchangePower;
            }
            else if (UsedRegex.Suffix.HealXMaxY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.HealXMaxY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.HealXMaxY;
            }
            else if (UsedRegex.Suffix.IncreaseAttackX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseAttackX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseAttackX;
            }
            else if (UsedRegex.Suffix.IncreaseAttackXPerRemainingLife.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseAttackXPerRemainingLife.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseAttackXPerRemainingLife;
            }
            else if (UsedRegex.Suffix.IncreaseAttackXPerRemainingPillz.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseAttackXPerRemainingPillz.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseAttackXPerRemainingPillz;
            }
            else if (UsedRegex.Suffix.IncreaseDamageX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseDamageX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseDamageX;
            }
            else if (UsedRegex.Suffix.IncreaseLifeX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseLifeX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseLifeX;
            }
            else if (UsedRegex.Suffix.IncreaseLifeXMaxY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseLifeXMaxY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseLifeXMaxY;
            }
            else if (UsedRegex.Suffix.IncreaseLifeXPerDamage.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseLifeXPerDamage.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseLifeXPerDamage;
            }
            else if (UsedRegex.Suffix.IncreaseLifeXPerDamageMaxY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreaseLifeXPerDamageMaxY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.IncreaseLifeXPerDamageMaxY;
            }
            else if (UsedRegex.Suffix.IncreasePillzAndLifeX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreasePillzAndLifeX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreasePillzAndLifeX;
            }
            else if (UsedRegex.Suffix.IncreasePillzX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreasePillzX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreasePillzX;
            }
            else if (UsedRegex.Suffix.IncreasePillzXMaxY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreasePillzXMaxY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.IncreasePillzXMaxY;
            }
            else if (UsedRegex.Suffix.IncreasePillzXPerDamage.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreasePillzXPerDamage.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreasePillzXPerDamage;
            }
            else if (UsedRegex.Suffix.IncreasePowerAndDamageX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreasePowerAndDamageX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreasePowerAndDamageX;
            }
            else if (UsedRegex.Suffix.IncreasePowerX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.IncreasePowerX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.IncreasePowerX;
            }
            else if (UsedRegex.Suffix.InfectionXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.InfectionXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.IncreasePowerX;
            }
            else if (UsedRegex.Suffix.PoisonXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.PoisonXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.PoisonXMinY;
            }
            else if (UsedRegex.Suffix.ProtectAttack.IsMatch(suffixText))
            {
                suffix = SkillSuffix.ProtectAttack;
            }
            else if (UsedRegex.Suffix.ProtectBonus.IsMatch(suffixText))
            {
                suffix = SkillSuffix.ProtectBonus;
            }
            else if (UsedRegex.Suffix.ProtectDamage.IsMatch(suffixText))
            {
                suffix = SkillSuffix.ProtectDamage;
            }
            else if (UsedRegex.Suffix.ProtectPower.IsMatch(suffixText))
            {
                suffix = SkillSuffix.ProtectPower;
            }
            else if (UsedRegex.Suffix.ProtectPowerAndDamage.IsMatch(suffixText))
            {
                suffix = SkillSuffix.ProtectPowerAndDamage;
            }
            else if (UsedRegex.Suffix.ReanimateX.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.ReanimateX.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                suffix = SkillSuffix.ReanimateX;
            }
            else if (UsedRegex.Suffix.RebirthXMaxY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.RebirthXMaxY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.RebirthXMaxY;
            }
            else if (UsedRegex.Suffix.RecoverXPillzOutOfY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.RecoverXPillzOutOfY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.RecoverXPillzOutOfY;
            }
            else if (UsedRegex.Suffix.RegenXMaxY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.RegenXMaxY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.RegenXMaxY;
            }
            else if (UsedRegex.Suffix.StopAbility.IsMatch(suffixText))
            {
                suffix = SkillSuffix.StopAbility;
            }
            else if (UsedRegex.Suffix.StopBonus.IsMatch(suffixText))
            {
                suffix = SkillSuffix.StopBonus;
            }
            else if (UsedRegex.Suffix.ToxinXMinY.IsMatch(suffixText))
            {
                match  = UsedRegex.Suffix.ToxinXMinY.Match(suffixText);
                x      = match.Groups["x"].Captures[0].Value;
                y      = match.Groups["y"].Captures[0].Value;
                suffix = SkillSuffix.ToxinXMinY;
            }

            // -- End Suffix --

            int X, Y;

            int.TryParse(x, out X);
            int.TryParse(y, out Y);

            return(new Skill(prefix, suffix, X, Y));
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="id">Must be an existing id on the database</param>
        /// <returns></returns>
        public CardBase GetCardBase(int id)
        {
            if (id <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(id), id, "Must be greater than 0");
            }

            DataTable       table;
            SQLiteErrorCode returnCode;

            // Look up for CardLevel's
            SQLiteCommand command = new SQLiteCommand("SELECT * FROM cardlevel WHERE baseid == ? ORDER BY level;");

            command.Parameters.AddWithValue("@p1", id);
            returnCode = ExecuteSelect(command, FilepathManagerInstance.PersistentDatabase, out table);
            if (returnCode != SQLiteErrorCode.Ok)
            {
                throw new SQLiteException(returnCode, "Failed executing CardLevel SELECT");
            }

            // CardLevel's
            var levels = new List <CardLevel>();

            foreach (DataRow cardLevelRow in table.Rows)
            {
                int level  = Convert.ToInt32(cardLevelRow["level"]);
                int power  = Convert.ToInt32(cardLevelRow["power"]);
                int damage = Convert.ToInt32(cardLevelRow["damage"]);
                levels.Add(new CardLevel(level, power, damage));
            }

            // Look up for CardBase
            command = new SQLiteCommand("SELECT * FROM cardbase WHERE baseid == ?;");
            command.Parameters.AddWithValue("@p1", id);
            returnCode = ExecuteSelect(command, FilepathManagerInstance.PersistentDatabase, out table);
            if (returnCode != SQLiteErrorCode.Ok)
            {
                throw new SQLiteException(returnCode, "Failed executing CardBase SELECT");
            }
            DataRow row = table.Rows[0];

            // Clan
            ClanId clanid = (ClanId)Convert.ToInt32(row["clanid"]);
            Clan   clan   = Clan.GetClanById(clanid);

            // Ability
            Skill       ability;
            SkillLeader leader = (SkillLeader)Convert.ToInt32(row["leader"]);

            if (leader != SkillLeader.None)
            {
                ability = new Skill(leader);
            }
            else
            {
                SkillSuffix suffix = (SkillSuffix)Convert.ToInt32(row["suffix"]);
                if (suffix == SkillSuffix.None)
                {
                    ability = Skill.NoAbility;
                }
                else
                {
                    SkillPrefix prefix = (SkillPrefix)Convert.ToInt32(row["prefix"]);
                    int         x      = Convert.ToInt32(row["x"]);
                    int         y      = Convert.ToInt32(row["y"]);
                    ability = new Skill(prefix, suffix, x, y);
                }
            }

            // Other CardBase details
            string     name        = row["name"].ToString();
            int        minlevel    = Convert.ToInt32(row["minlevel"]);
            int        maxlevel    = Convert.ToInt32(row["maxlevel"]);
            int        unlocklevel = Convert.ToInt32(row["unlocklevel"]);
            CardRarity rarity      = (CardRarity)Convert.ToInt32(row["rarity"]);
            DateTime   releasedate = (Convert.ToDateTime(row["releasedate"]));

            return(new CardBase(id, name, clan, minlevel, maxlevel, levels, ability, unlocklevel, rarity, releasedate));
        }