From 1b430e5d99af748fe458dada16c6fc00693d2ea1 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 22 Aug 2020 18:48:15 +0400 Subject: [PATCH] Added verify test to check missing second face cards in sets, fixed missing cards; --- Mage.Sets/src/mage/sets/EldritchMoon.java | 4 +-- Mage.Sets/src/mage/sets/Innistrad.java | 22 ++++++------ .../src/mage/sets/MagicOnlinePromos.java | 5 +++ .../twofaced/TwoFacedCardEffectsTest.java | 14 +++++--- .../java/mage/verify/mtgjson/MtgJsonCard.java | 12 +++++++ .../mage/verify/mtgjson/MtgJsonService.java | 4 +-- .../java/mage/verify/VerifyCardDataTest.java | 34 ++++++++++++++++--- Mage/src/main/java/mage/cards/CardImpl.java | 19 ++++++----- .../mage/cards/repository/CardRepository.java | 19 ++++++++++- 9 files changed, 99 insertions(+), 34 deletions(-) diff --git a/Mage.Sets/src/mage/sets/EldritchMoon.java b/Mage.Sets/src/mage/sets/EldritchMoon.java index 40d15bdb2d..a4c43aecac 100644 --- a/Mage.Sets/src/mage/sets/EldritchMoon.java +++ b/Mage.Sets/src/mage/sets/EldritchMoon.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -6,7 +5,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class EldritchMoon extends ExpansionSet { @@ -29,7 +27,7 @@ public final class EldritchMoon extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; this.numBoosterDoubleFaced = 1; - + cards.add(new SetCardInfo("Abandon Reason", 115, Rarity.UNCOMMON, mage.cards.a.AbandonReason.class)); cards.add(new SetCardInfo("Abolisher of Bloodlines", 111, Rarity.RARE, mage.cards.a.AbolisherOfBloodlines.class)); cards.add(new SetCardInfo("Abundant Maw", 1, Rarity.UNCOMMON, mage.cards.a.AbundantMaw.class)); diff --git a/Mage.Sets/src/mage/sets/Innistrad.java b/Mage.Sets/src/mage/sets/Innistrad.java index d70af168b8..1d6be5fd48 100644 --- a/Mage.Sets/src/mage/sets/Innistrad.java +++ b/Mage.Sets/src/mage/sets/Innistrad.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -26,18 +25,19 @@ public final class Innistrad extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; this.numBoosterDoubleFaced = 1; + cards.add(new SetCardInfo("Abattoir Ghoul", 85, Rarity.UNCOMMON, mage.cards.a.AbattoirGhoul.class)); cards.add(new SetCardInfo("Abbey Griffin", 1, Rarity.COMMON, mage.cards.a.AbbeyGriffin.class)); cards.add(new SetCardInfo("Altar's Reap", 86, Rarity.COMMON, mage.cards.a.AltarsReap.class)); cards.add(new SetCardInfo("Ambush Viper", 169, Rarity.COMMON, mage.cards.a.AmbushViper.class)); cards.add(new SetCardInfo("Ancient Grudge", 127, Rarity.COMMON, mage.cards.a.AncientGrudge.class)); - cards.add(new SetCardInfo("Angelic Overseer", 3, Rarity.MYTHIC, mage.cards.a.AngelicOverseer.class)); cards.add(new SetCardInfo("Angel of Flight Alabaster", 2, Rarity.RARE, mage.cards.a.AngelOfFlightAlabaster.class)); + cards.add(new SetCardInfo("Angelic Overseer", 3, Rarity.MYTHIC, mage.cards.a.AngelicOverseer.class)); cards.add(new SetCardInfo("Armored Skaab", 43, Rarity.COMMON, mage.cards.a.ArmoredSkaab.class)); cards.add(new SetCardInfo("Army of the Damned", 87, Rarity.MYTHIC, mage.cards.a.ArmyOfTheDamned.class)); cards.add(new SetCardInfo("Ashmouth Hound", 128, Rarity.COMMON, mage.cards.a.AshmouthHound.class)); - cards.add(new SetCardInfo("Avacynian Priest", 4, Rarity.COMMON, mage.cards.a.AvacynianPriest.class)); cards.add(new SetCardInfo("Avacyn's Pilgrim", 170, Rarity.COMMON, mage.cards.a.AvacynsPilgrim.class)); + cards.add(new SetCardInfo("Avacynian Priest", 4, Rarity.COMMON, mage.cards.a.AvacynianPriest.class)); cards.add(new SetCardInfo("Back from the Brink", 44, Rarity.RARE, mage.cards.b.BackFromTheBrink.class)); cards.add(new SetCardInfo("Balefire Dragon", 129, Rarity.MYTHIC, mage.cards.b.BalefireDragon.class)); cards.add(new SetCardInfo("Bane of Hanweir", 145, Rarity.UNCOMMON, mage.cards.b.BaneOfHanweir.class)); @@ -120,12 +120,12 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Gatstaf Howler", 182, Rarity.UNCOMMON, mage.cards.g.GatstafHowler.class)); cards.add(new SetCardInfo("Gatstaf Shepherd", 182, Rarity.UNCOMMON, mage.cards.g.GatstafShepherd.class)); cards.add(new SetCardInfo("Gavony Township", 239, Rarity.RARE, mage.cards.g.GavonyTownship.class)); + cards.add(new SetCardInfo("Geist of Saint Traft", 213, Rarity.MYTHIC, mage.cards.g.GeistOfSaintTraft.class)); + cards.add(new SetCardInfo("Geist-Honored Monk", 17, Rarity.RARE, mage.cards.g.GeistHonoredMonk.class)); cards.add(new SetCardInfo("Geistcatcher's Rig", 223, Rarity.UNCOMMON, mage.cards.g.GeistcatchersRig.class)); cards.add(new SetCardInfo("Geistflame", 144, Rarity.COMMON, mage.cards.g.Geistflame.class)); - cards.add(new SetCardInfo("Geist-Honored Monk", 17, Rarity.RARE, mage.cards.g.GeistHonoredMonk.class)); - cards.add(new SetCardInfo("Geist of Saint Traft", 213, Rarity.MYTHIC, mage.cards.g.GeistOfSaintTraft.class)); - cards.add(new SetCardInfo("Ghostly Possession", 18, Rarity.COMMON, mage.cards.g.GhostlyPossession.class)); cards.add(new SetCardInfo("Ghost Quarter", 240, Rarity.UNCOMMON, mage.cards.g.GhostQuarter.class)); + cards.add(new SetCardInfo("Ghostly Possession", 18, Rarity.COMMON, mage.cards.g.GhostlyPossession.class)); cards.add(new SetCardInfo("Ghoulcaller's Bell", 224, Rarity.COMMON, mage.cards.g.GhoulcallersBell.class)); cards.add(new SetCardInfo("Ghoulcaller's Chant", 101, Rarity.COMMON, mage.cards.g.GhoulcallersChant.class)); cards.add(new SetCardInfo("Ghoulraiser", 102, Rarity.COMMON, mage.cards.g.Ghoulraiser.class)); @@ -162,8 +162,8 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Island", 255, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Isolated Chapel", 242, Rarity.RARE, mage.cards.i.IsolatedChapel.class)); cards.add(new SetCardInfo("Kessig Cagebreakers", 189, Rarity.RARE, mage.cards.k.KessigCagebreakers.class)); - cards.add(new SetCardInfo("Kessig Wolf", 151, Rarity.COMMON, mage.cards.k.KessigWolf.class)); cards.add(new SetCardInfo("Kessig Wolf Run", 243, Rarity.RARE, mage.cards.k.KessigWolfRun.class)); + cards.add(new SetCardInfo("Kessig Wolf", 151, Rarity.COMMON, mage.cards.k.KessigWolf.class)); cards.add(new SetCardInfo("Kindercatch", 190, Rarity.COMMON, mage.cards.k.Kindercatch.class)); cards.add(new SetCardInfo("Krallenhorde Wantons", 185, Rarity.COMMON, mage.cards.k.KrallenhordeWantons.class)); cards.add(new SetCardInfo("Kruin Outlaw", 152, Rarity.RARE, mage.cards.k.KruinOutlaw.class)); @@ -206,10 +206,10 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Naturalize", 197, Rarity.COMMON, mage.cards.n.Naturalize.class)); cards.add(new SetCardInfo("Nephalia Drownyard", 245, Rarity.RARE, mage.cards.n.NephaliaDrownyard.class)); cards.add(new SetCardInfo("Nevermore", 25, Rarity.RARE, mage.cards.n.Nevermore.class)); - cards.add(new SetCardInfo("Nightbird's Clutches", 154, Rarity.COMMON, mage.cards.n.NightbirdsClutches.class)); - cards.add(new SetCardInfo("Nightfall Predator", 176, Rarity.RARE, mage.cards.n.NightfallPredator.class)); cards.add(new SetCardInfo("Night Revelers", 153, Rarity.COMMON, mage.cards.n.NightRevelers.class)); cards.add(new SetCardInfo("Night Terrors", 111, Rarity.COMMON, mage.cards.n.NightTerrors.class)); + cards.add(new SetCardInfo("Nightbird's Clutches", 154, Rarity.COMMON, mage.cards.n.NightbirdsClutches.class)); + cards.add(new SetCardInfo("Nightfall Predator", 176, Rarity.RARE, mage.cards.n.NightfallPredator.class)); cards.add(new SetCardInfo("Olivia Voldaren", 215, Rarity.MYTHIC, mage.cards.o.OliviaVoldaren.class)); cards.add(new SetCardInfo("One-Eyed Scarecrow", 230, Rarity.COMMON, mage.cards.o.OneEyedScarecrow.class)); cards.add(new SetCardInfo("Orchard Spirit", 198, Rarity.COMMON, mage.cards.o.OrchardSpirit.class)); @@ -245,8 +245,8 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Sharpened Pitchfork", 232, Rarity.UNCOMMON, mage.cards.s.SharpenedPitchfork.class)); cards.add(new SetCardInfo("Shimmering Grotto", 246, Rarity.COMMON, mage.cards.s.ShimmeringGrotto.class)); cards.add(new SetCardInfo("Silent Departure", 75, Rarity.COMMON, mage.cards.s.SilentDeparture.class)); - cards.add(new SetCardInfo("Silverchase Fox", 31, Rarity.COMMON, mage.cards.s.SilverchaseFox.class)); cards.add(new SetCardInfo("Silver-Inlaid Dagger", 233, Rarity.UNCOMMON, mage.cards.s.SilverInlaidDagger.class)); + cards.add(new SetCardInfo("Silverchase Fox", 31, Rarity.COMMON, mage.cards.s.SilverchaseFox.class)); cards.add(new SetCardInfo("Skaab Goliath", 76, Rarity.UNCOMMON, mage.cards.s.SkaabGoliath.class)); cards.add(new SetCardInfo("Skaab Ruinator", 77, Rarity.MYTHIC, mage.cards.s.SkaabRuinator.class)); cards.add(new SetCardInfo("Skeletal Grimace", 116, Rarity.COMMON, mage.cards.s.SkeletalGrimace.class)); @@ -281,8 +281,8 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Thraben Sentry", 38, Rarity.COMMON, mage.cards.t.ThrabenSentry.class)); cards.add(new SetCardInfo("Tormented Pariah", 165, Rarity.COMMON, mage.cards.t.TormentedPariah.class)); cards.add(new SetCardInfo("Traitorous Blood", 166, Rarity.COMMON, mage.cards.t.TraitorousBlood.class)); - cards.add(new SetCardInfo("Traveler's Amulet", 234, Rarity.COMMON, mage.cards.t.TravelersAmulet.class)); cards.add(new SetCardInfo("Travel Preparations", 206, Rarity.COMMON, mage.cards.t.TravelPreparations.class)); + cards.add(new SetCardInfo("Traveler's Amulet", 234, Rarity.COMMON, mage.cards.t.TravelersAmulet.class)); cards.add(new SetCardInfo("Tree of Redemption", 207, Rarity.MYTHIC, mage.cards.t.TreeOfRedemption.class)); cards.add(new SetCardInfo("Trepanation Blade", 235, Rarity.UNCOMMON, mage.cards.t.TrepanationBlade.class)); cards.add(new SetCardInfo("Tribute to Hunger", 119, Rarity.UNCOMMON, mage.cards.t.TributeToHunger.class)); diff --git a/Mage.Sets/src/mage/sets/MagicOnlinePromos.java b/Mage.Sets/src/mage/sets/MagicOnlinePromos.java index cfb9252ebe..b601febdf5 100644 --- a/Mage.Sets/src/mage/sets/MagicOnlinePromos.java +++ b/Mage.Sets/src/mage/sets/MagicOnlinePromos.java @@ -66,6 +66,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Arc Lightning", 36116, Rarity.COMMON, mage.cards.a.ArcLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arc Lightning", 55791, Rarity.RARE, mage.cards.a.ArcLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arcanis the Omnipotent", 54547, Rarity.MYTHIC, mage.cards.a.ArcanisTheOmnipotent.class)); + cards.add(new SetCardInfo("Archdemon of Greed", 43503, Rarity.RARE, mage.cards.a.ArchdemonOfGreed.class)); cards.add(new SetCardInfo("Archfiend of Depravity", 55711, Rarity.RARE, mage.cards.a.ArchfiendOfDepravity.class)); cards.add(new SetCardInfo("Archfiend of Ifnir", 64422, Rarity.RARE, mage.cards.a.ArchfiendOfIfnir.class)); cards.add(new SetCardInfo("Archon of the Triumvirate", 46877, Rarity.RARE, mage.cards.a.ArchonOfTheTriumvirate.class)); @@ -553,6 +554,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Hoodwink", 62449, Rarity.COMMON, mage.cards.h.Hoodwink.class)); cards.add(new SetCardInfo("Hordeling Outburst", 55783, Rarity.UNCOMMON, mage.cards.h.HordelingOutburst.class)); cards.add(new SetCardInfo("Hostage Taker", 69987, Rarity.RARE, mage.cards.h.HostageTaker.class)); + cards.add(new SetCardInfo("Howlpack Alpha", 42866, Rarity.RARE, mage.cards.h.HowlpackAlpha.class)); cards.add(new SetCardInfo("Huatli, the Sun's Heart", 72241, Rarity.RARE, mage.cards.h.HuatliTheSunsHeart.class)); cards.add(new SetCardInfo("Hydra Broodmaster", 53850, Rarity.RARE, mage.cards.h.HydraBroodmaster.class)); cards.add(new SetCardInfo("Hydroblast", 69979, Rarity.COMMON, mage.cards.h.Hydroblast.class)); @@ -578,6 +580,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Infest", 43568, Rarity.UNCOMMON, mage.cards.i.Infest.class, FULL_ART)); cards.add(new SetCardInfo("Ink-Eyes, Servant of Oni", 32013, Rarity.RARE, mage.cards.i.InkEyesServantOfOni.class)); cards.add(new SetCardInfo("Inkmoth Nexus", 62999, Rarity.RARE, mage.cards.i.InkmothNexus.class)); + cards.add(new SetCardInfo("Insidious Mist", 60472, Rarity.RARE, mage.cards.i.InsidiousMist.class)); cards.add(new SetCardInfo("Intuition", 36046, Rarity.RARE, mage.cards.i.Intuition.class)); cards.add(new SetCardInfo("Island", 239, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 247, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); @@ -689,6 +692,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Lowland Oaf", 62415, Rarity.COMMON, mage.cards.l.LowlandOaf.class)); cards.add(new SetCardInfo("Loyal Retainers", 47973, Rarity.UNCOMMON, mage.cards.l.LoyalRetainers.class)); cards.add(new SetCardInfo("Lu Bu, Master-at-Arms", 36130, Rarity.RARE, mage.cards.l.LuBuMasterAtArms.class)); + cards.add(new SetCardInfo("Ludevic's Abomination", 42874, Rarity.RARE, mage.cards.l.LudevicsAbomination.class)); cards.add(new SetCardInfo("Ludevic's Test Subject", 42874, Rarity.RARE, mage.cards.l.LudevicsTestSubject.class)); cards.add(new SetCardInfo("Mad Auntie", 35066, Rarity.RARE, mage.cards.m.MadAuntie.class)); cards.add(new SetCardInfo("Maelstrom Pulse", 37845, Rarity.RARE, mage.cards.m.MaelstromPulse.class)); @@ -1212,6 +1216,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Tormented Hero", 51934, Rarity.UNCOMMON, mage.cards.t.TormentedHero.class)); cards.add(new SetCardInfo("Tormented Soul", 41652, Rarity.COMMON, mage.cards.t.TormentedSoul.class)); cards.add(new SetCardInfo("Tormod's Crypt", 31427, Rarity.UNCOMMON, mage.cards.t.TormodsCrypt.class)); + cards.add(new SetCardInfo("Tovolar's Magehunter", 43507, Rarity.RARE, mage.cards.t.TovolarsMagehunter.class)); cards.add(new SetCardInfo("Tradewind Rider", 36048, Rarity.RARE, mage.cards.t.TradewindRider.class)); cards.add(new SetCardInfo("Transmute Artifact", 65644, Rarity.RARE, mage.cards.t.TransmuteArtifact.class)); cards.add(new SetCardInfo("Traxos, Scourge of Kroog", 69242, Rarity.RARE, mage.cards.t.TraxosScourgeOfKroog.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/twofaced/TwoFacedCardEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/twofaced/TwoFacedCardEffectsTest.java index 69bd3a726a..4b5c5511d9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/twofaced/TwoFacedCardEffectsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/twofaced/TwoFacedCardEffectsTest.java @@ -72,17 +72,24 @@ public class TwoFacedCardEffectsTest extends CardTestPlayerBase { */ @Test public void testCopyCantTransform() { + // At the beginning of each upkeep, if no spells were cast last turn, transform Mayor of Avabruck. + addCard(Zone.HAND, playerA, "Mayor of Avabruck"); // {1}{G} addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); - addCard(Zone.HAND, playerA, "Mayor of Avabruck"); + // + // You may have Clone enter the battlefield as a copy of any creature on the battlefield. + addCard(Zone.HAND, playerB, "Clone"); // {3}{U} addCard(Zone.BATTLEFIELD, playerB, "Island", 4); - addCard(Zone.HAND, playerB, "Clone"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mayor of Avabruck"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Clone"); + setChoice(playerB, "Yes"); // use copy + setChoice(playerB, "Mayor of Avabruck"); // clone target + setStrictChooseMode(true); setStopAt(5, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 2); assertHandCount(playerB, 2); @@ -120,14 +127,13 @@ public class TwoFacedCardEffectsTest extends CardTestPlayerBase { /** * Tests that triggered abilities of the frontside do not trigger if the card is transformed - * */ @Test public void testTransformedDOesNotTriggerFrontsideAbilities() { addCard(Zone.BATTLEFIELD, playerA, "Loyal Cathar"); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); - addCard(Zone.HAND, playerB, "Lightning Bolt",2); + addCard(Zone.HAND, playerB, "Lightning Bolt", 2); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Loyal Cathar"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Unhallowed Cathar"); diff --git a/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonCard.java b/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonCard.java index 5efe55a622..5cbeea2797 100644 --- a/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonCard.java +++ b/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonCard.java @@ -32,4 +32,16 @@ public final class MtgJsonCard { public String layout; public boolean isFullArt; public List printings; // set codes with that card + + public String getRealCardName() { + // double faces cards must be split in different cards in xmage (so use faceName instead name) + // for card searching + if ("transform".equals(layout) + || "flip".equals(layout) + || "adventure".equals(layout) + || "meld".equals(layout)) { // TODO: remove or keep after mtgjson's meld bug resolve https://github.com/mtgjson/mtgjson/issues/661 + return faceName; + } + return asciiName != null ? asciiName : name; + } } diff --git a/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonService.java b/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonService.java index 2476850ce2..36f27971c4 100644 --- a/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonService.java +++ b/Mage.Verify/src/main/java/mage/verify/mtgjson/MtgJsonService.java @@ -78,7 +78,7 @@ public final class MtgJsonService { String needName = convertXmageToMtgJsonCardName(name); return set.cards.stream() - .filter(c -> needName.equals(c.name) || needName.equals(c.asciiName) || needName.equals(c.faceName)) + .filter(c -> needName.equals(c.getRealCardName())) .collect(Collectors.toList()); } @@ -146,7 +146,7 @@ public final class MtgJsonService { public HashMap> data; private boolean containsSameNames(ArrayList list) { - Set names = list.stream().map(c -> c.name).collect(Collectors.toSet()); + Set names = list.stream().map(MtgJsonCard::getRealCardName).collect(Collectors.toSet()); return names.size() == 1; } diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index b87f45a159..0b3a8957ad 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -547,6 +547,32 @@ public class VerifyCardDataTest { } } + @Test + public void test_checkMissingSecondSideCardsInSets() { + Collection errorsList = new ArrayList<>(); + + // CHECK: if card have second side (flip, transform) then it must have all sides in that set + for (ExpansionSet set : Sets.getInstance().values()) { + for (ExpansionSet.SetCardInfo info : set.getSetCardInfo()) { + CardInfo cardInfo = CardRepository.instance.findCardsByClass(info.getCardClass().getCanonicalName()).stream().findFirst().orElse(null); + Assert.assertNotNull(cardInfo); + + Card card = cardInfo.getCard(); + Card secondCard = card.getSecondCardFace(); + if (secondCard != null) { + if (set.findCardInfoByClass(secondCard.getClass()).isEmpty()) { + errorsList.add("Error: missing second face card from set: " + set.getCode() + " - " + set.getName() + " - main: " + card.getName() + "; second: " + secondCard.getName()); + } + } + } + } + + printMessages(errorsList); + if (errorsList.size() > 0) { + Assert.fail("Found missing second side cards in sets, errors: " + errorsList.size()); + } + } + @Test @Ignore // TODO: enable after all missing cards and settings fixes public void test_checkWrongCardsDataInSets() { @@ -571,7 +597,7 @@ public class VerifyCardDataTest { } // index for missing cards - String code = MtgJsonService.xMageToMtgJsonCodes.getOrDefault(set.getCode(), set.getCode()) + " - " + jsonCard.name + " - " + jsonCard.number; + String code = MtgJsonService.xMageToMtgJsonCodes.getOrDefault(set.getCode(), set.getCode()) + " - " + jsonCard.getRealCardName() + " - " + jsonCard.number; foundedJsonCards.add(code); // CHECK: must use full art setting @@ -602,13 +628,13 @@ public class VerifyCardDataTest { } for (MtgJsonCard jsonCard : jsonSet.cards) { - String code = jsonSet.code + " - " + jsonCard.name + " - " + jsonCard.number; + String code = jsonSet.code + " - " + jsonCard.getRealCardName() + " - " + jsonCard.number; if (!foundedJsonCards.contains(code)) { - if (CardRepository.instance.findCard(jsonCard.name) == null) { + if (CardRepository.instance.findCard(jsonCard.getRealCardName()) == null) { // ignore non-implemented cards continue; } - errorsList.add("Error: missing card from xmage's set: " + jsonSet.code + " - " + jsonCard.name + " - " + jsonCard.number); + errorsList.add("Error: missing card from xmage's set: " + jsonSet.code + " - " + jsonCard.getRealCardName() + " - " + jsonCard.number); } } } diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index b0546be8a9..5d04ad1880 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -10,6 +10,8 @@ import mage.abilities.hint.Hint; import mage.abilities.hint.HintUtils; import mage.abilities.keyword.FlashbackAbility; import mage.abilities.mana.ActivatedManaAbilityImpl; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; import mage.cards.repository.PluginClassloaderRegistery; import mage.constants.*; import mage.counters.Counter; @@ -683,6 +685,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { @Override public final Card getSecondCardFace() { + // init second side card on first call if (secondSideCardClazz == null && secondSideCard == null) { return null; } @@ -691,14 +694,12 @@ public abstract class CardImpl extends MageObjectImpl implements Card { return secondSideCard; } - List cardInfo = Sets.findSet(expansionSetCode).findCardInfoByClass(secondSideCardClazz); - if (cardInfo.isEmpty()) { - return null; - } - - ExpansionSet.SetCardInfo info = cardInfo.get(0); - return secondSideCard = createCard(secondSideCardClazz, - new CardSetInfo(info.getName(), expansionSetCode, info.getCardNumber(), info.getRarity(), info.getGraphicInfo())); + // must be non strict search in any sets, not one set + // example: if set contains only one card side, e.g. dev forget to add it + // verify test checks missing side cards in test_checkMissingSecondSideCardsInSets + CardInfo cardInfo = CardRepository.instance.findPreferedCoreExpansionCardByClassName(secondSideCardClazz.getCanonicalName(), expansionSetCode); + secondSideCard = cardInfo.getCard(); + return secondSideCard; } @Override @@ -971,5 +972,5 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } } return false; - } + } } diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index f92a1b20e8..de7da86ce2 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -406,14 +406,21 @@ public enum CardRepository { } public CardInfo findPreferedCoreExpansionCard(String name, boolean caseInsensitive, String preferedSetCode) { - List cards; if (caseInsensitive) { cards = findCardsCaseInsensitive(name); } else { cards = findCards(name); } + return findPreferedOrLatestCard(cards, preferedSetCode); + } + public CardInfo findPreferedCoreExpansionCardByClassName(String canonicalClassName, String preferedSetCode) { + List cards = findCardsByClass(canonicalClassName); + return findPreferedOrLatestCard(cards, preferedSetCode); + } + + private CardInfo findPreferedOrLatestCard(List cards, String preferedSetCode) { if (!cards.isEmpty()) { Date lastReleaseDate = null; Date lastExpansionDate = null; @@ -469,6 +476,16 @@ public enum CardRepository { return Collections.emptyList(); } + public List findCardsByClass(String canonicalClassName) { + try { + QueryBuilder queryBuilder = cardDao.queryBuilder(); + queryBuilder.where().eq("className", new SelectArg(canonicalClassName)); + return cardDao.query(queryBuilder.prepare()); + } catch (SQLException ex) { + } + return Collections.emptyList(); + } + public List findCardsCaseInsensitive(String name) { try { String sqlName = name.toLowerCase(Locale.ENGLISH).replaceAll("'", "''");