diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index f2d2dccbe0a..7e9dffbb244 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -2061,7 +2061,7 @@ public class Card extends GameEntity implements Comparable { // Vanguard Modifiers if (this.isType("Vanguard")) { - final CardPrinted avatar = CardDb.instance().getCard(this); + final CardPrinted avatar = CardDb.getCard(this); sb.append("Hand Modifier: "); sb.append(avatar.getCard().getHand()); sb.append("\r\nLife Modifier: "); diff --git a/src/main/java/forge/card/BoosterGenerator.java b/src/main/java/forge/card/BoosterGenerator.java index 701413ae9f5..970614eb1ca 100644 --- a/src/main/java/forge/card/BoosterGenerator.java +++ b/src/main/java/forge/card/BoosterGenerator.java @@ -122,7 +122,7 @@ public class BoosterGenerator { public BoosterGenerator(Predicate filter) { this(); - for (final CardPrinted c : Iterables.filter(CardDb.instance().getAllTraditionalCards(), filter)) { + for (final CardPrinted c : Iterables.filter(CardDb.instance().getAllCards(), filter)) { this.addToRarity(c); // System.out.println(c); } diff --git a/src/main/java/forge/card/CardEdition.java b/src/main/java/forge/card/CardEdition.java index 622786b56cf..f63ae3aedd3 100644 --- a/src/main/java/forge/card/CardEdition.java +++ b/src/main/java/forge/card/CardEdition.java @@ -186,7 +186,7 @@ public final class CardEdition implements Comparable { // immutable public static final Predicate hasBasicLands = new Predicate() { @Override public boolean apply(CardEdition ed) { - return CardDb.instance().isCardSupported("Plains", ed.getCode()); + return null != CardDb.instance().tryGetCard("Plains", ed.getCode()); }; }; diff --git a/src/main/java/forge/card/CardRules.java b/src/main/java/forge/card/CardRules.java index dfe3f1a58a9..85e99a26703 100644 --- a/src/main/java/forge/card/CardRules.java +++ b/src/main/java/forge/card/CardRules.java @@ -413,6 +413,11 @@ public final class CardRules { public Integer getLife() { return life; } + + + public boolean isTraditional() { + return !(getType().isVanguard() || getType().isScheme() || getType().isPlane() || getType().isPhenomenon()); + } } diff --git a/src/main/java/forge/card/MetaSet.java b/src/main/java/forge/card/MetaSet.java index 22246eb50df..a6f3ece64a3 100644 --- a/src/main/java/forge/card/MetaSet.java +++ b/src/main/java/forge/card/MetaSet.java @@ -226,7 +226,7 @@ public class MetaSet { // NOTE: The following code is far from ideal in a number of ways. If someone can // think of a way to improve it, please do so. --BBU // ItemPool cardPool = new ItemPool(CardPrinted.class); - for (CardPrinted aCard : CardDb.instance().getAllTraditionalCards()) { + for (CardPrinted aCard : CardDb.instance().getAllCards()) { if (data.indexOf(aCard.getEdition()) > -1) { cardPool.add(aCard); // System.out.println("Added card" + aCard.getName()); @@ -293,7 +293,7 @@ public class MetaSet { if (mSet.type.equalsIgnoreCase("meta") || mSet.type.equalsIgnoreCase("booster") || mSet.type.equalsIgnoreCase("pack")) { final String mData = new String(mSet.data); - for (CardPrinted aCard : CardDb.instance().getAllTraditionalCards()) { + for (CardPrinted aCard : CardDb.instance().getAllCards()) { if (mData.indexOf(aCard.getEdition()) > -1) { if (!cardPool.contains(aCard)) { cardPool.add(aCard); diff --git a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java index 976ec3f8728..35b7a5d40fb 100644 --- a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java +++ b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java @@ -785,7 +785,7 @@ public class ChangeZoneEffect extends SpellEffect { } } if (sa.hasParam("Reveal") && !movedCards.isEmpty()) { - GuiChoose.one(card + " - Revealed card: ", movedCards.toArray()); + GuiChoose.one(card + " - Revealed card: ", movedCards); } if ((origin.contains(ZoneType.Library) && !destination.equals(ZoneType.Library) && !defined) diff --git a/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java b/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java index 29ad4425444..49fe5e5b6eb 100644 --- a/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java @@ -1,13 +1,20 @@ package forge.card.ability.effects; +import java.util.Collections; import java.util.List; +import org.apache.commons.lang3.StringUtils; + +import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import forge.Card; import forge.CardLists; import forge.Singletons; import forge.CardPredicates.Presets; +import forge.card.CardRulesPredicates; import forge.card.ability.SpellEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; @@ -51,10 +58,29 @@ public class ChooseCardNameEffect extends SpellEffect { boolean ok = false; while (!ok) { if (p.isHuman()) { - final String message = validDesc.equals("card") ? "Name a card" : "Name a " + validDesc - + " card. (Case sensitive)"; + + final String message = validDesc.equals("card") ? "Name a card" : "Name a " + validDesc + " card."; + + List cards = Lists.newArrayList(CardDb.instance().getAllUniqueCards()); + if ( StringUtils.containsIgnoreCase(valid, "nonland") ) + { + Predicate cpp = Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, CardPrinted.FN_GET_RULES); + cards = Lists.newArrayList(Iterables.filter(cards, cpp)); + } + if ( StringUtils.containsIgnoreCase(valid, "nonbasic") ) + { + Predicate cpp = Predicates.compose(Predicates.not(CardRulesPredicates.Presets.IS_BASIC_LAND), CardPrinted.FN_GET_RULES); + cards = Lists.newArrayList(Iterables.filter(cards, cpp)); + } + if ( StringUtils.containsIgnoreCase(valid, "creature") ) + { + Predicate cpp = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, CardPrinted.FN_GET_RULES); + cards = Lists.newArrayList(Iterables.filter(cards, cpp)); + } - CardPrinted cp = GuiChoose.one(message, CardDb.instance().getAllUniqueCards()); + Collections.sort(cards); + + CardPrinted cp = GuiChoose.one(message, cards); if (cp.getMatchingForgeCard().isValid(valid, host.getController(), host)) { host.setNamedCard(cp.getName()); ok = true; diff --git a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java index d56bd5fe8c7..e1e2ec759bc 100644 --- a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java +++ b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java @@ -82,7 +82,7 @@ public class CopyPermanentEffect extends SpellEffect { if (!c.isToken() || c.isCopiedToken()) { // copy creature and put it onto the battlefield - copy = Singletons.getModel().getCardFactory().getCard(CardDb.instance().getCard(c), sa.getActivatingPlayer()); + copy = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(c), sa.getActivatingPlayer()); // when copying something stolen: copy.addController(controller); diff --git a/src/main/java/forge/card/ability/effects/PlayEffect.java b/src/main/java/forge/card/ability/effects/PlayEffect.java index 2495fee4ed9..879cea96f5f 100644 --- a/src/main/java/forge/card/ability/effects/PlayEffect.java +++ b/src/main/java/forge/card/ability/effects/PlayEffect.java @@ -150,7 +150,7 @@ public class PlayEffect extends SpellEffect { source.clearRemembered(); } if (sa.hasParam("CopyCard")) { - tgtCard = Singletons.getModel().getCardFactory().getCard(CardDb.instance().getCard(tgtCard), sa.getActivatingPlayer()); + tgtCard = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(tgtCard), sa.getActivatingPlayer()); // when copying something stolen: tgtCard.addController(sa.getActivatingPlayer()); diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index 80025e3b58d..9375f8f53c5 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -99,7 +99,7 @@ public class CardFactory { if (in.isInAlternateState()) { in.setState(CardCharacteristicName.Original); } - final Card out = this.getCard(CardDb.instance().getCard(in), in.getOwner()); + final Card out = this.getCard(CardDb.getCard(in), in.getOwner()); out.setUniqueNumber(in.getUniqueNumber()); CardFactoryUtil.copyCharacteristics(in, out); diff --git a/src/main/java/forge/deck/CardPool.java b/src/main/java/forge/deck/CardPool.java index bdc6fee3f8e..115585b39ef 100644 --- a/src/main/java/forge/deck/CardPool.java +++ b/src/main/java/forge/deck/CardPool.java @@ -58,7 +58,7 @@ public class CardPool extends ItemPool { public void set(final Iterable cardNames) { this.clear(); for (final String name : cardNames) { - this.add(CardDb.instance().getCard(name)); + this.add(name); } } @@ -69,7 +69,7 @@ public class CardPool extends ItemPool { * the card */ public void add(final Card card) { - this.add(CardDb.instance().getCard(card)); + this.add(CardDb.getCard(card)); } /** @@ -81,7 +81,7 @@ public class CardPool extends ItemPool { * the set code */ public void add(final String cardName, final String setCode) { - this.add(CardDb.instance().getCard(cardName, setCode)); + this.add(cardName, setCode, 1); } /** @@ -92,7 +92,14 @@ public class CardPool extends ItemPool { * @param amount the amount */ public void add(final String cardName, final String setCode, final int amount) { - this.add(CardDb.instance().getCard(cardName, setCode), amount); + CardPrinted cp = CardDb.instance().tryGetCard(cardName, setCode); + if ( cp == null ) + cp = CardDb.variants().tryGetCard(cardName, setCode); + + if ( cp != null) + this.add(cp, amount); + else + throw new RuntimeException(String.format("Card %s from %s is not supported by Forge, as it's neither a known common card nor one of casual variants' card.", cardName, setCode )); } /** @@ -125,7 +132,14 @@ public class CardPool extends ItemPool { * @param cardName the card name */ public void add(final String cardName) { - this.add(CardDb.instance().getCard(cardName)); + CardPrinted cp = CardDb.instance().tryGetCard(cardName); + if ( cp == null ) + cp = CardDb.variants().tryGetCard(cardName); + + if ( cp != null) + this.add(cp); + else + throw new RuntimeException(String.format("Card %s is not supported by Forge, as it's neither a known common card nor one of casual variants' card.", cardName)); } /** diff --git a/src/main/java/forge/deck/DeckRecognizer.java b/src/main/java/forge/deck/DeckRecognizer.java index 29c86a68a5b..cb7a7fb8a91 100644 --- a/src/main/java/forge/deck/DeckRecognizer.java +++ b/src/main/java/forge/deck/DeckRecognizer.java @@ -189,7 +189,7 @@ public class DeckRecognizer { * Token(cardName, amount); } */ else { - if (CardDb.instance().isCardSupported(line)) { + if (null != CardDb.instance().tryGetCard(line)) { return Token.knownCard(CardDb.instance().getCard(line, newestEdition), 1); } result = DeckRecognizer.recognizeNonCard(line, 1); @@ -198,7 +198,7 @@ public class DeckRecognizer { } private static Token recognizePossibleNameAndNumber(final String name, final int n, final boolean newestEdition) { - if (CardDb.instance().isCardSupported(name)) { + if (null != CardDb.instance().tryGetCard(name)) { return Token.knownCard(CardDb.instance().getCard(name, newestEdition), n); } diff --git a/src/main/java/forge/deck/DeckgenUtil.java b/src/main/java/forge/deck/DeckgenUtil.java index f2f57ee4110..408f1d78700 100644 --- a/src/main/java/forge/deck/DeckgenUtil.java +++ b/src/main/java/forge/deck/DeckgenUtil.java @@ -314,7 +314,7 @@ public class DeckgenUtil { public static CardPool generateSchemeDeck() { CardPool schemes = new CardPool(); List allSchemes = new ArrayList(); - for (CardPrinted c : CardDb.instance().getAllNonTraditionalCards()) { + for (CardPrinted c : CardDb.variants().getAllCards()) { if (c.getCard().getType().isScheme()) { allSchemes.add(c); } @@ -339,7 +339,7 @@ public class DeckgenUtil { public static CardPool generatePlanarDeck() { CardPool res = new CardPool(); List allPlanars = new ArrayList(); - for (CardPrinted c : CardDb.instance().getAllNonTraditionalCards()) { + for (CardPrinted c : CardDb.variants().getAllCards()) { if (c.getCard().getType().isPlane() || c.getCard().getType().isPhenomenon()) { allPlanars.add(c); } diff --git a/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java b/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java index afaaa3904df..5105b6179e8 100644 --- a/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java +++ b/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java @@ -224,7 +224,7 @@ public abstract class GenerateColoredDeckBase { if (!Singletons.getModel().getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS)) { hasColor = Predicates.or(hasColor, GenerateDeckUtil.COLORLESS_CARDS); } - return Iterables.filter(CardDb.instance().getAllTraditionalCards(), Predicates.compose(Predicates.and(canPlay, hasColor), CardPrinted.FN_GET_RULES)); + return Iterables.filter(CardDb.instance().getAllCards(), Predicates.compose(Predicates.and(canPlay, hasColor), CardPrinted.FN_GET_RULES)); } protected static Map countLands(ItemPool outList) { diff --git a/src/main/java/forge/game/limited/LimitedDeck.java b/src/main/java/forge/game/limited/LimitedDeck.java index 1aed3adefde..e9d17122d7c 100644 --- a/src/main/java/forge/game/limited/LimitedDeck.java +++ b/src/main/java/forge/game/limited/LimitedDeck.java @@ -265,7 +265,7 @@ public class LimitedDeck { private void findBasicLandSets() { Set sets = new HashSet(); for (CardPrinted cp : aiPlayables) { - if (CardDb.instance().isCardSupported("Plains", cp.getEdition())) { + if (null != CardDb.instance().tryGetCard("Plains", cp.getEdition())) { sets.add(cp.getEdition()); } } diff --git a/src/main/java/forge/gui/GuiDialog.java b/src/main/java/forge/gui/GuiDialog.java index 9d2c6734e39..a8f88b14c7a 100644 --- a/src/main/java/forge/gui/GuiDialog.java +++ b/src/main/java/forge/gui/GuiDialog.java @@ -89,7 +89,7 @@ public class GuiDialog { * @return a boolean. */ public static boolean flipCoin(final Player caller, final Card source) { - String choice = ""; + String choice; final String[] choices = { "heads", "tails" }; final boolean flip = MyRandom.getRandom().nextBoolean(); @@ -99,7 +99,7 @@ public class GuiDialog { choice = choices[MyRandom.getRandom().nextInt(2)]; } - final boolean winFlip = flip == choice.equals("heads"); + final boolean winFlip = flip == choice.equals(choices[0]); final String winMsg = winFlip ? " wins flip." : " loses flip."; // Play the Flip A Coin sound diff --git a/src/main/java/forge/gui/GuiMigrateLocalMWSSetPicturesHQ.java b/src/main/java/forge/gui/GuiMigrateLocalMWSSetPicturesHQ.java index b82e4ea0c68..92c96f00afd 100644 --- a/src/main/java/forge/gui/GuiMigrateLocalMWSSetPicturesHQ.java +++ b/src/main/java/forge/gui/GuiMigrateLocalMWSSetPicturesHQ.java @@ -491,7 +491,7 @@ public final class GuiMigrateLocalMWSSetPicturesHQ extends DefaultBoundedRangeMo final String urlBase = "C:\\MTGForge\\HQPICS\\"; String imgFN = ""; - for (final CardPrinted cp : CardDb.instance().getAllTraditionalCards()) { + for (final CardPrinted cp : CardDb.instance().getAllCards()) { // String url = c.getSVar("Picture"); // String[] URLs = url.split("\\\\"); diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java index af5535252b3..0d25e1f207a 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java @@ -152,7 +152,7 @@ public final class CEditorConstructed extends ACEditorBase { @Override public void resetTables() { // Constructed mode can use all cards, no limitations. - this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllTraditionalCards(), CardPrinted.class), true); + this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class), true); this.getTableDeck().setDeck(this.controller.getModel().getMain()); } @@ -179,7 +179,7 @@ public final class CEditorConstructed extends ACEditorBase { } else { lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); this.getTableCatalog().setAvailableColumns(lstCatalogCols); - this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllTraditionalCards(), CardPrinted.class), true); + this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class), true); this.getTableDeck().setDeck(this.controller.getModel().getMain()); } diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java index b5118e68328..2d905c112e6 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java @@ -96,7 +96,7 @@ public final class CEditorQuestCardShop extends ACEditorBase cardsForSale; private final ItemPool fullCatalogCards = - ItemPool.createFrom(CardDb.instance().getAllTraditionalCards(), InventoryItem.class); + ItemPool.createFrom(CardDb.instance().getAllCards(), InventoryItem.class); private boolean showingFullCatalog = false; private DragCell allDecksParent = null; private DragCell deckGenParent = null; diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java index 7edfe5f368d..8a67c732eae 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java @@ -141,7 +141,7 @@ public final class CEditorVariant extends ACEditorBase { */ @Override public void resetTables() { - Iterable allNT = CardDb.instance().getAllNonTraditionalCards(); + Iterable allNT = CardDb.variants().getAllCards(); allNT = Iterables.filter(allNT, cardPoolCondition); this.getTableCatalog().setDeck(ItemPool.createFrom(allNT, CardPrinted.class), true); diff --git a/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java b/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java index 77c5e1698f4..1fa7f7350cc 100644 --- a/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java +++ b/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java @@ -92,7 +92,7 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloader { // read token names and urls final ArrayList cList = new ArrayList(); - Iterable allPrinted = Iterables.concat(CardDb.instance().getAllTraditionalCards(), CardDb.instance().getAllNonTraditionalCards()); + Iterable allPrinted = Iterables.concat(CardDb.instance().getAllCards(), CardDb.variants().getAllCards()); for (final CardPrinted c : allPrinted) { final String setCode3 = c.getEdition(); diff --git a/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java b/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java index 0e4ead9f557..c9873ec4378 100644 --- a/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java +++ b/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java @@ -358,7 +358,7 @@ public enum VSubmenuVanguard implements IVSubmenu { */ public Iterable getAllAvatars() { if ( allAvatars.isEmpty() ) { - for(CardPrinted c : CardDb.instance().getAllNonTraditionalCards()) { + for(CardPrinted c : CardDb.variants().getAllCards()) { if( c.getCard().getType().isVanguard()) allAvatars.add(c); } diff --git a/src/main/java/forge/gui/match/ControlWinLose.java b/src/main/java/forge/gui/match/ControlWinLose.java index d841ae800ae..8594496e076 100644 --- a/src/main/java/forge/gui/match/ControlWinLose.java +++ b/src/main/java/forge/gui/match/ControlWinLose.java @@ -135,7 +135,7 @@ public class ControlWinLose { Deck oDeck = match.getPlayersOriginalDeck(loser.getLobbyPlayer()); for (Card c : compAntes) { - CardPrinted toRemove = CardDb.instance().getCard(c); + CardPrinted toRemove = CardDb.getCard(c); cDeck.getMain().remove(toRemove); if ( cDeck != oDeck ) oDeck.getMain().remove(toRemove); diff --git a/src/main/java/forge/gui/match/QuestWinLose.java b/src/main/java/forge/gui/match/QuestWinLose.java index aa6279464ee..ccb326428d7 100644 --- a/src/main/java/forge/gui/match/QuestWinLose.java +++ b/src/main/java/forge/gui/match/QuestWinLose.java @@ -135,7 +135,7 @@ public class QuestWinLose extends ControlWinLose { continue; } for (Card c : p.getCardsIn(ZoneType.Ante)) { - anteCards.add(CardDb.instance().getCard(c)); + anteCards.add(CardDb.getCard(c)); } } diff --git a/src/main/java/forge/item/CardDb.java b/src/main/java/forge/item/CardDb.java index b24f0ad3c4e..3719ef7e72f 100644 --- a/src/main/java/forge/item/CardDb.java +++ b/src/main/java/forge/item/CardDb.java @@ -20,12 +20,12 @@ package forge.item; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; @@ -37,7 +37,6 @@ import com.google.common.collect.Iterables; import forge.Card; import forge.card.CardInSet; import forge.card.CardRules; -import forge.card.MtgDataParser; import forge.util.Aggregates; @@ -50,8 +49,8 @@ import forge.util.Aggregates; * @version $Id: CardDb.java 9708 2011-08-09 19:34:12Z jendave $ */ public final class CardDb { - private static volatile CardDb onlyInstance = null; // 'volatile' keyword - // makes this working + private static volatile CardDb commonCards = null; // 'volatile' keyword makes this working + private static volatile CardDb variantCards = null; // 'volatile' keyword makes this working private final String foilSuffix = " foil"; /** @@ -60,12 +59,20 @@ public final class CardDb { * @return the card db */ public static CardDb instance() { - if (CardDb.onlyInstance == null) { + if (CardDb.commonCards == null) { throw new NullPointerException("CardDb has not yet been initialized, run setup() first"); } - return CardDb.onlyInstance; + return CardDb.commonCards; + } + + public static CardDb variants() { + if (CardDb.variantCards == null) { + throw new NullPointerException("CardDb has not yet been initialized, run setup() first"); + } + return CardDb.variantCards; } + /** * Sets the up. * @@ -73,14 +80,14 @@ public final class CardDb { * the new up */ public static void setup(final Iterator list) { - if (CardDb.onlyInstance != null) { + if (CardDb.commonCards != null) { throw new RuntimeException("CardDb has already been initialized, don't do it twice please"); } synchronized (CardDb.class) { - if (CardDb.onlyInstance == null) { // It's broken under 1.4 and - // below, on - // 1.5+ works again! - CardDb.onlyInstance = new CardDb(list); + if (CardDb.commonCards == null) { // It's broken under 1.4 and below, on 1.5+ works again! + CardSorter cs = new CardSorter(list); + commonCards = new CardDb(cs.uniqueCommonCards, cs.allCommonCardsFlat, cs.allCommonCardsBySet); + variantCards = new CardDb(cs.uniqueSpecialCards, cs.allSpecialCardsFlat, cs.allSpecialCardsBySet); } } } @@ -92,13 +99,12 @@ public final class CardDb { // Here are refs, get them by name private final Map uniqueCards; + // need this to obtain cardReference by name+set+artindex - private final Map> allCardsBySet = new Hashtable>(); + private final Map> allCardsBySet; // this is the same list in flat storage - private final List allTraditionalCardsFlat = new ArrayList(); - - private final List allNonTraditionalCardsFlat = new ArrayList(); - + private final List allCardsFlat; + // Lambda to get rules for selects from list of printed cards /** The Constant fnGetCardPrintedByForgeCard. */ public static final Function FN_GET_CARD_PRINTED_BY_FORGE_CARD = new Function() { @@ -108,80 +114,10 @@ public final class CardDb { } }; - private CardDb() { - this(new MtgDataParser()); // I wish cardname.txt parser was here. - } - - private CardDb(final Iterator parser) { - Map uniques = new Hashtable(); - while (parser.hasNext()) { - this.addNewCard(parser.next(), uniques); - } - - this.uniqueCards = Collections.unmodifiableMap(uniques); - } - - /** - * Adds the new card. - * - * @param card - * the card - */ - private void addNewCard(final CardRules card, Map uniques) { - if (null == card) { - return; - } // consider that a success - // System.out.println(card.getName()); - final String cardName = card.getName().toLowerCase(); - - // 1. register among oracle uniques - // cards.put(cardName, card); - - // 2. Save refs into two lists: one flat and other keyed with sets & - // name - CardPrinted lastAdded = null; - for (final Entry s : card.getSetsPrinted()) { - lastAdded = this.addToLists(card, cardName, s); - } - uniques.put(cardName, lastAdded); - } - - /** - * Adds the to lists. - * - * @param card - * the card - * @param cardName - * the card name - * @param s - * the s - * @return the card printed - */ - public CardPrinted addToLists(final CardRules card, final String cardName, final Entry s) { - CardPrinted lastAdded = null; - final String set = s.getKey(); - - // get this set storage, if not found, create it! - Map setMap = this.allCardsBySet.get(set); - if (null == setMap) { - setMap = new Hashtable(); - this.allCardsBySet.put(set, setMap); - } - - final int count = s.getValue().getCopiesCount(); - final CardPrinted[] cardCopies = new CardPrinted[count]; - setMap.put(cardName, cardCopies); - for (int i = 0; i < count; i++) { - lastAdded = CardPrinted.build(card, set, s.getValue().getRarity(), i); - if (lastAdded.isTraditional()) { - this.allTraditionalCardsFlat.add(lastAdded); - } else { - this.allNonTraditionalCardsFlat.add(lastAdded); - } - cardCopies[i] = lastAdded; - } - - return lastAdded; + private CardDb(Map uniqueCards, List cardsFlat, Map> cardsBySet) { + this.uniqueCards = Collections.unmodifiableMap(uniqueCards); + this.allCardsFlat = Collections.unmodifiableList(cardsFlat); + this.allCardsBySet = cardsBySet; } /** @@ -223,29 +159,29 @@ public final class CardDb { * the card name * @return true, if is card supported */ - public boolean isCardSupported(final String cardName0) { + public CardPrinted tryGetCard(final String cardName0) { if (null == cardName0) { - return false; // obviously + return null; // obviously } final boolean isFoil = this.isFoil(cardName0); final String cardName = isFoil ? this.removeFoilSuffix(cardName0) : cardName0; final ImmutablePair nameWithSet = CardDb.splitCardName(cardName); if (nameWithSet.right == null) { - return this.uniqueCards.containsKey(nameWithSet.left.toLowerCase()); + return this.uniqueCards.get(nameWithSet.left); } - return isCardSupported(nameWithSet.left, nameWithSet.right); + return tryGetCard(nameWithSet.left, nameWithSet.right); } - public boolean isCardSupported(final String cardName, String setName) { + public CardPrinted tryGetCard(final String cardName, String setName) { // Set exists? final Map cardsFromset = this.allCardsBySet.get(setName.toUpperCase()); if (cardsFromset == null) { - return false; + return null; } // Card exists? final CardPrinted[] cardCopies = cardsFromset.get(cardName.toLowerCase()); - return (cardCopies != null) && (cardCopies.length > 0); + return cardCopies != null ? cardCopies[0] : null; } // Single fetch @@ -318,27 +254,17 @@ public final class CardDb { * the forge card * @return the card */ - public CardPrinted getCard(final Card forgeCard) { + public static CardPrinted getCard(final Card forgeCard) { final String name = forgeCard.getName(); final String set = forgeCard.getCurSetCode(); + if (StringUtils.isNotBlank(set)) { - return this.getCard(name, set); + CardPrinted cp = variants().tryGetCard(name, set); + + return cp == null ? instance().getCard(name, set) : cp; } - return this.getCard(name); - } - - /** - * Gets the cards from latest sets. - * - * @param names the names - * @return the cards from latest sets - */ - public List getCardsFromLatestSets(final Iterable names) { - final List result = new ArrayList(); - for (final String name : names) { - result.add(this.getCard(name, true)); - } - return result; + CardPrinted cp = variants().tryGetCard(name); + return cp == null ? instance().getCard(name) : cp; } // returns a list of all cards from their respective latest editions @@ -351,6 +277,8 @@ public final class CardDb { return this.uniqueCards.values(); } + + // public Iterable getAllCardRules() { return cards.values(); } // // still not needed /** @@ -358,12 +286,8 @@ public final class CardDb { * * @return the all cards */ - public Iterable getAllTraditionalCards() { - return this.allTraditionalCardsFlat; - } - - public Iterable getAllNonTraditionalCards() { - return this.allNonTraditionalCardsFlat; + public Collection getAllCards() { + return this.allCardsFlat; } /** @@ -393,16 +317,11 @@ public final class CardDb { } else { // OK, plain name here final Predicate predicate = CardPrinted.Predicates.name(nameWithSet.left); - final Iterable namedCards = Iterables.filter(this.allTraditionalCardsFlat, predicate); + final Iterable namedCards = Iterables.filter(this.allCardsFlat, predicate); // Find card with maximal set index result = Aggregates.itemWithMax(namedCards, CardPrinted.FN_GET_EDITION_INDEX); if (null == result) { - // 2nd chance: look in planes, schemes and so on - final Iterable namedNonTraditionals = Iterables.filter(this.allNonTraditionalCardsFlat, predicate); - result = Aggregates.itemWithMax(namedNonTraditionals, CardPrinted.FN_GET_EDITION_INDEX); - - if ( null == result ) // sure thing, throw exception - throw new NoSuchElementException(String.format("Card '%s' not found in our database.", name)); + throw new NoSuchElementException(String.format("Card '%s' not found in our database.", name)); } } @@ -413,4 +332,92 @@ public final class CardDb { return result; } + private static class CardSorter{ + // Here oracle cards + // private final Map cards = new Hashtable(); + + // need this to obtain cardReference by name+set+artindex + public final Map> allCommonCardsBySet = new TreeMap>(String.CASE_INSENSITIVE_ORDER); + public final Map> allSpecialCardsBySet = new TreeMap>(String.CASE_INSENSITIVE_ORDER); + // Here are refs, get them by name + public final Map uniqueCommonCards = new TreeMap(String.CASE_INSENSITIVE_ORDER); + public final Map uniqueSpecialCards = new TreeMap(String.CASE_INSENSITIVE_ORDER); + // this is the same list in flat storage + public final List allCommonCardsFlat = new ArrayList(); + public final List allSpecialCardsFlat = new ArrayList(); + + /** + * Adds the to lists. + * + * @param card + * the card + * @param cardName + * the card name + * @param s + * the s + * @return the card printed + */ + public CardPrinted addToLists(final CardRules card, final String cardName, final Entry s) { + CardPrinted lastAdded = null; + final String set = s.getKey(); + + final Map> allCardsBySet = card.isTraditional() ? allCommonCardsBySet : allSpecialCardsBySet; + // get this set storage, if not found, create it! + Map setMap = allCardsBySet.get(set); + if (null == setMap) { + setMap = new TreeMap(String.CASE_INSENSITIVE_ORDER); + allCardsBySet.put(set, setMap); + } + + final int count = s.getValue().getCopiesCount(); + final CardPrinted[] cardCopies = new CardPrinted[count]; + setMap.put(cardName, cardCopies); + for (int i = 0; i < count; i++) { + lastAdded = CardPrinted.build(card, set, s.getValue().getRarity(), i); + if (card.isTraditional()) { + this.allCommonCardsFlat.add(lastAdded); + } else { + this.allSpecialCardsFlat.add(lastAdded); + } + cardCopies[i] = lastAdded; + } + + return lastAdded; + } + + /** + * Adds the new card. + * + * @param card + * the card + */ + private void addNewCard(final CardRules card) { + if (null == card) { + return; + } // consider that a success + // System.out.println(card.getName()); + final String cardName = card.getName().toLowerCase(); + + // 1. register among oracle uniques + // cards.put(cardName, card); + + // 2. Save refs into two lists: one flat and other keyed with sets & + // name + CardPrinted lastAdded = null; + for (final Entry s : card.getSetsPrinted()) { + lastAdded = this.addToLists(card, cardName, s); + } + if ( lastAdded.getCard().isTraditional() ) + uniqueCommonCards.put(cardName, lastAdded); + else + uniqueSpecialCards.put(cardName, lastAdded); + } + + CardSorter(final Iterator parser) { + while (parser.hasNext()) { + this.addNewCard(parser.next()); + } + } + } } diff --git a/src/main/java/forge/item/CardPrinted.java b/src/main/java/forge/item/CardPrinted.java index 7eeaeee72f1..5c4606969f2 100644 --- a/src/main/java/forge/item/CardPrinted.java +++ b/src/main/java/forge/item/CardPrinted.java @@ -115,13 +115,6 @@ public final class CardPrinted implements Comparable, InventoryItem return this.foiled; } - public boolean isTraditional() { - return !(getCard().getType().isVanguard() - || getCard().getType().isScheme() - || getCard().getType().isPlane() - || getCard().getType().isPhenomenon()); - } - /** * Gets the card. * diff --git a/src/main/java/forge/item/OpenablePack.java b/src/main/java/forge/item/OpenablePack.java index 7541ff6c0d7..41e0b157d7b 100644 --- a/src/main/java/forge/item/OpenablePack.java +++ b/src/main/java/forge/item/OpenablePack.java @@ -175,7 +175,7 @@ public abstract class OpenablePack implements InventoryItemFromSet { Predicate cardsRule = Predicates.and( CardPrinted.Predicates.printedInSets(setCode), Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, CardPrinted.FN_GET_RULES)); - return Aggregates.random(Iterables.filter(CardDb.instance().getAllTraditionalCards(), cardsRule), count); + return Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), cardsRule), count); } } diff --git a/src/main/java/forge/quest/BoosterUtils.java b/src/main/java/forge/quest/BoosterUtils.java index 04698f16bae..9ab41f3b4d8 100644 --- a/src/main/java/forge/quest/BoosterUtils.java +++ b/src/main/java/forge/quest/BoosterUtils.java @@ -88,7 +88,7 @@ public final class BoosterUtils { } // This will save CPU time when sets are limited - final List cardpool = Lists.newArrayList(Iterables.filter(CardDb.instance().getAllTraditionalCards(), filter)); + final List cardpool = Lists.newArrayList(Iterables.filter(CardDb.instance().getAllCards(), filter)); final Predicate pCommon = CardPrinted.Predicates.Presets.IS_COMMON; cards.addAll(BoosterUtils.generateDefinetlyColouredCards(cardpool, pCommon, numCommon, colorFilters)); @@ -180,7 +180,7 @@ public final class BoosterUtils { * @return the list */ public static List generateDistinctCards(final Predicate filter, final int cntNeeded) { - return BoosterUtils.generateDistinctCards(CardDb.instance().getAllTraditionalCards(), filter, cntNeeded); + return BoosterUtils.generateDistinctCards(CardDb.instance().getAllCards(), filter, cntNeeded); } /** diff --git a/src/main/java/forge/quest/QuestRewardCardChooser.java b/src/main/java/forge/quest/QuestRewardCardChooser.java index 48334d014b8..497982403c8 100644 --- a/src/main/java/forge/quest/QuestRewardCardChooser.java +++ b/src/main/java/forge/quest/QuestRewardCardChooser.java @@ -223,7 +223,7 @@ public class QuestRewardCardChooser implements InventoryItem { } else if (type == poolType.predicateFilter) { List cardChoices = new ArrayList(); - for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllTraditionalCards(), predicates)) { + for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllCards(), predicates)) { cardChoices.add(card); } Collections.sort(cardChoices); diff --git a/src/main/java/forge/quest/QuestRewardCardFiltered.java b/src/main/java/forge/quest/QuestRewardCardFiltered.java index 2d504191447..bab37fe3fb8 100644 --- a/src/main/java/forge/quest/QuestRewardCardFiltered.java +++ b/src/main/java/forge/quest/QuestRewardCardFiltered.java @@ -171,7 +171,7 @@ public class QuestRewardCardFiltered implements IQuestRewardCard { */ public final List getChoices() { List cardChoices = new ArrayList(); - for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllTraditionalCards(), predicates)) { + for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllCards(), predicates)) { cardChoices.add(card); } Collections.sort(cardChoices); diff --git a/src/main/java/forge/quest/QuestUtilCards.java b/src/main/java/forge/quest/QuestUtilCards.java index 3b5c932ae18..386c8bc7c61 100644 --- a/src/main/java/forge/quest/QuestUtilCards.java +++ b/src/main/java/forge/quest/QuestUtilCards.java @@ -90,7 +90,7 @@ public final class QuestUtilCards { if (usedFormat != null) { List availableEditions = usedFormat.getAllowedSetCodes(); for (String edition : availableEditions) { - if (db.isCardSupported("Plains", edition)) { + if (null != db.tryGetCard("Plains", edition)) { landCodes.add(edition); } } @@ -205,7 +205,7 @@ public final class QuestUtilCards { final Predicate myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE); - final CardPrinted card = Aggregates.random(Iterables.filter(CardDb.instance().getAllTraditionalCards(), myFilter)); + final CardPrinted card = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), myFilter)); this.addSingleCard(card); return card; } @@ -220,7 +220,7 @@ public final class QuestUtilCards { public List addRandomRare(final int n) { final Predicate myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE); - final List newCards = Aggregates.random(Iterables.filter(CardDb.instance().getAllTraditionalCards(), myFilter), n); + final List newCards = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), myFilter), n); this.addAllCards(newCards); return newCards; } @@ -509,9 +509,9 @@ public final class QuestUtilCards { Iterable cardList = null; if (qc.getFormat() == null) { - cardList = CardDb.instance().getAllTraditionalCards(); } + cardList = CardDb.instance().getAllCards(); } else { - cardList = Iterables.filter(CardDb.instance().getAllTraditionalCards(), + cardList = Iterables.filter(CardDb.instance().getAllCards(), qc.getFormat().getFilterPrinted()); } @@ -627,7 +627,7 @@ public final class QuestUtilCards { public int getCompletionPercent(String edition) { // get all cards in the specified edition Predicate filter = CardPrinted.Predicates.printedInSets(edition); - Iterable editionCards = Iterables.filter(CardDb.instance().getAllTraditionalCards(), filter); + Iterable editionCards = Iterables.filter(CardDb.instance().getAllCards(), filter); ItemPool ownedCards = qa.getCardPool(); // 100% means at least one of every basic land and at least 4 of every other card in the set diff --git a/src/main/java/forge/util/PredicateString.java b/src/main/java/forge/util/PredicateString.java index e829281f5c1..70ec7415e51 100644 --- a/src/main/java/forge/util/PredicateString.java +++ b/src/main/java/forge/util/PredicateString.java @@ -108,13 +108,5 @@ public abstract class PredicateString implements Predicate { } }; } - public static PredicateString equalsIgnoreCase(final String what) { - return new PredicateString(StringOp.EQUALS_IC) { - @Override - public boolean apply(String subject) { - return op(subject, what); - } - }; - } }