diff --git a/.gitattributes b/.gitattributes index b267693a623..927779af89a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13923,9 +13923,9 @@ src/main/java/forge/card/CardAiHints.java -text src/main/java/forge/card/CardBlock.java -text src/main/java/forge/card/CardCharacteristics.java -text src/main/java/forge/card/CardCoreType.java -text +src/main/java/forge/card/CardDb.java -text src/main/java/forge/card/CardEdition.java -text src/main/java/forge/card/CardFace.java -text -src/main/java/forge/card/CardInSet.java -text src/main/java/forge/card/CardRarity.java -text src/main/java/forge/card/CardRules.java -text src/main/java/forge/card/CardRulesPredicates.java -text @@ -13939,6 +13939,7 @@ src/main/java/forge/card/EditionCollection.java svneol=native#text/plain src/main/java/forge/card/FatPackTemplate.java -text src/main/java/forge/card/FormatCollection.java -text src/main/java/forge/card/ICardCharacteristics.java -text +src/main/java/forge/card/ICardDatabase.java -text src/main/java/forge/card/ICardFace.java -text src/main/java/forge/card/ICardRawAbilites.java -text src/main/java/forge/card/IUnOpenedProduct.java -text @@ -14673,7 +14674,6 @@ src/main/java/forge/gui/toolbox/FTextField.java -text src/main/java/forge/gui/toolbox/SaveOpenDialog.java -text src/main/java/forge/gui/toolbox/package-info.java svneol=native#text/plain src/main/java/forge/item/BoosterPack.java -text -src/main/java/forge/item/CardDb.java -text src/main/java/forge/item/FatPack.java -text src/main/java/forge/item/IPaperCard.java -text src/main/java/forge/item/InventoryItem.java -text diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index d78e7d6589e..412f291cb04 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -40,6 +40,7 @@ import com.google.common.collect.ImmutableList; import forge.CardPredicates.Presets; import forge.card.CardCharacteristics; +import forge.card.CardDb; import forge.card.CardRarity; import forge.card.CardRules; import forge.card.ColorSet; @@ -75,7 +76,6 @@ import forge.game.phase.Combat; import forge.game.player.Player; import forge.game.zone.Zone; import forge.game.zone.ZoneType; -import forge.item.CardDb; import forge.util.Expressions; /** diff --git a/src/main/java/forge/ImageCache.java b/src/main/java/forge/ImageCache.java index 026bc0b8636..68ba038ef13 100644 --- a/src/main/java/forge/ImageCache.java +++ b/src/main/java/forge/ImageCache.java @@ -34,6 +34,7 @@ import com.google.common.cache.CacheLoader.InvalidCacheLoadException; import com.google.common.cache.LoadingCache; import com.mortennobel.imagescaling.ResampleOp; +import forge.card.CardDb; import forge.card.CardRules; import forge.card.CardSplitType; import forge.game.player.IHasIcon; @@ -247,7 +248,7 @@ public class ImageCache { final int cntPictures; final boolean hasManyPictures; if (includeSet) { - cntPictures = card.getEditionInfo(edition).getCopiesCount(); + cntPictures = card.isTraditional() ? CardDb.instance().getPrintCount(card.getName(), edition) : CardDb.variants().getPrintCount(card.getName(), edition); hasManyPictures = cntPictures > 1; } else { // without set number of pictures equals number of urls provided in Svar:Picture @@ -255,10 +256,7 @@ public class ImageCache { cntPictures = StringUtils.countMatches(urls, "\\") + 1; // raise the art index limit to the maximum of the sets this card was printed in - int maxCntPictures = 1; - for (String set : card.getSets()) { - maxCntPictures = Math.max(maxCntPictures, card.getEditionInfo(set).getCopiesCount()); - } + int maxCntPictures = card.isTraditional() ? CardDb.instance().getMaxPrintCount(card.getName()) : CardDb.variants().getMaxPrintCount(card.getName()); hasManyPictures = maxCntPictures > 1; } diff --git a/src/main/java/forge/card/BoosterGenerator.java b/src/main/java/forge/card/BoosterGenerator.java index 43adee5d83f..3a3ac5a0ada 100644 --- a/src/main/java/forge/card/BoosterGenerator.java +++ b/src/main/java/forge/card/BoosterGenerator.java @@ -35,7 +35,6 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import forge.Singletons; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.item.PrintSheet; diff --git a/src/main/java/forge/card/CardDb.java b/src/main/java/forge/card/CardDb.java new file mode 100644 index 00000000000..9ed06640c53 --- /dev/null +++ b/src/main/java/forge/card/CardDb.java @@ -0,0 +1,349 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.card; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +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; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +import forge.Card; +import forge.item.PaperCard; +import forge.util.Aggregates; +import forge.util.MyRandom; +import forge.util.maps.CollectionSuppliers; +import forge.util.maps.MapOfLists; +import forge.util.maps.TreeMapOfLists; + +public final class CardDb implements ICardDatabase { + private static volatile CardDb commonCards = null; // 'volatile' keyword makes this working + private static volatile CardDb variantCards = null; // 'volatile' keyword makes this working + public final static String foilSuffix = " foil"; + private final static int foilSuffixLength = foilSuffix.length(); + + public static ICardDatabase instance() { + if (CardDb.commonCards == null) { + throw new NullPointerException("CardDb has not yet been initialized, run setup() first"); + } + return CardDb.commonCards; + } + + public static ICardDatabase variants() { + if (CardDb.variantCards == null) { + throw new NullPointerException("CardDb has not yet been initialized, run setup() first"); + } + return CardDb.variantCards; + } + + public static void setup(final Iterable rules, Iterable editions) { + if (CardDb.commonCards != null) { + throw new RuntimeException("CardDb has already been initialized, don't do it twice please"); + } + synchronized (CardDb.class) { + if (CardDb.commonCards == null) { // It's broken under 1.4 and below, on 1.5+ works again! + CardSorter cs = new CardSorter(rules); + commonCards = new CardDb(cs.regularCards, editions); + variantCards = new CardDb(cs.variantsCards, editions); + } + } + } + + // need this to obtain cardReference by name+set+artindex + private final MapOfLists allCardsByName = new TreeMapOfLists(String.CASE_INSENSITIVE_ORDER, CollectionSuppliers.arrayLists()); + private final Map uniqueCardsByName = new TreeMap(String.CASE_INSENSITIVE_ORDER); + private final Map rulesByName; + + private final List allCards = new ArrayList(); + private final List roAllCards = Collections.unmodifiableList(allCards); + private final Collection roUniqueCards = Collections.unmodifiableCollection(uniqueCardsByName.values()); + + // 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() { + @Override + public PaperCard apply(final Card from) { + return CardDb.instance().getCard(from.getName()); + } + }; + + private CardDb(Map rules, Iterable editions) { + this.rulesByName = rules; + for(CardEdition e : editions) { + String lastCardName = null; + int artIdx = 0; + for(CardEdition.CardInSet cis : e.getCards()) { + if ( cis.name.equals(lastCardName) ) + artIdx++; + else { + artIdx = 0; + lastCardName = cis.name; + } + CardRules cr = rulesByName.get(lastCardName); + if( cr != null ) + addCard(new PaperCard(cr, e.getCode(), cis.rarity, artIdx)); + // else card is not scripted yet + } + } + reIndex(); + } + + private void addCard(PaperCard paperCard) { + allCardsByName.add(paperCard.name, paperCard); + } + + private void reIndex() { + uniqueCardsByName.clear(); + allCards.clear(); + for(Entry> kv : allCardsByName.entrySet()) { + uniqueCardsByName.put(kv.getKey(), Iterables.get(kv.getValue(), 0)); + allCards.addAll(kv.getValue()); + } + } + + /** + * Splits cardname into Name and set whenever deck line reads as name|set. + */ + private static ImmutablePair splitCardName(final String name) { + String cardName = name; // .trim() ? + final int pipePos = cardName.indexOf('|'); + + if (pipePos >= 0) { + final String setName = cardName.substring(pipePos + 1).trim(); + cardName = cardName.substring(0, pipePos); + // only if set is not blank try to load it + if (StringUtils.isNotBlank(setName) && !"???".equals(setName)) { + return new ImmutablePair(cardName, setName); + } + } + return new ImmutablePair(cardName, null); + } + + private boolean isFoil(final String cardName) { + return cardName.toLowerCase().endsWith(CardDb.foilSuffix) && (cardName.length() > CardDb.foilSuffixLength); + } + + /** + * Removes the foil suffix. + * + * @param cardName the card name + * @return the string + */ + public String removeFoilSuffix(final String cardName) { + return cardName.substring(0, cardName.length() - CardDb.foilSuffixLength); + } + + + /** + * Checks if is card supported. + */ + + @Override + public PaperCard tryGetCard(final String cardName0) { + return tryGetCard(cardName0, true); + } + + @Override + public PaperCard tryGetCard(final String cardName0, boolean fromLastSet) { + if (null == cardName0) { + return null; // obviously + } + + final boolean isFoil = this.isFoil(cardName0); + final String cardName = isFoil ? this.removeFoilSuffix(cardName0) : cardName0; + final ImmutablePair nameWithSet = CardDb.splitCardName(cardName); + + final PaperCard res = nameWithSet.right == null + ? ( fromLastSet ? this.uniqueCardsByName.get(nameWithSet.left) : Aggregates.random(this.allCardsByName.get(nameWithSet.left)) ) + : tryGetCard(nameWithSet.left, nameWithSet.right); + return null != res && isFoil ? PaperCard.makeFoiled(res) : res; + } + + @Override + public PaperCard tryGetCard(final String cardName, String setName) { + return tryGetCard(cardName, setName, -1); + } + + @Override + public int getPrintCount(String cardName, String edition) { + int cnt = 0; + for( PaperCard pc : allCardsByName.get(cardName) ) { + if( pc.getEdition().equals(edition) ) + cnt++; + } + return cnt; + } + + @Override + public int getMaxPrintCount(String cardName) { + int max = -1; + for( PaperCard pc : allCardsByName.get(cardName) ) { + if ( max < pc.getArtIndex() ) + max = pc.getArtIndex(); + } + return max + 1; + } + + @Override + public PaperCard tryGetCard(final String cardName, String setName, int index) { + Collection cards = allCardsByName.get(cardName); + if ( null == cards ) return null; + + if ( index < 0 ) { // this stands for 'random art' + PaperCard[] candidates = new PaperCard[8]; // 8 cards with same name per set is a maximum of what has been printed (lands of Zendikar) + int cnt = 0; + for( PaperCard pc : cards ) { + if( pc.getEdition().equals(setName) ) + candidates[cnt++] = pc; + } + + if (candidates.length == 0 ) return null; + if (candidates.length == 1 ) return candidates[0]; + return candidates[MyRandom.getRandom().nextInt(cnt)]; + } else + for( PaperCard pc : cards ) { + if( pc.getEdition().equals(setName) && index == pc.getArtIndex() ) + return pc; + } + return null; + } + + // Single fetch + @Override + public PaperCard getCard(final String name) { + return this.getCard(name, false); + } + + @Override + public PaperCard getCard(final String name0, final boolean fromLatestSet) { + // Sometimes they read from decks things like "CardName|Set" - but we + // can handle it + final PaperCard result = tryGetCard(name0, fromLatestSet); + if (null == result) { + throw new NoSuchElementException(String.format("Card '%s' not found in our database.", name0)); + } + return result; + } + + // Advanced fetch by name+set + @Override + public PaperCard getCard(final String name, final String set) { + return this.getCard(name, set, -1); + } + + @Override + public PaperCard getCard(final String name, final String set, final int artIndex) { + + final PaperCard result = tryGetCard(name, set, artIndex); + if (null == result) { + final String message = String.format("Asked for '%s' from '%s' #%d: db didn't find that copy.", name, set, artIndex); + throw new NoSuchElementException(message); + } + return result; + } + + // Fetch from Forge's Card instance. Well, there should be no errors, but + // we'll still check + public static PaperCard getCard(final Card forgeCard) { + final String name = forgeCard.getName(); + final String set = forgeCard.getCurSetCode(); + + if (StringUtils.isNotBlank(set)) { + PaperCard cp = variants().tryGetCard(name, set); + + return cp == null ? instance().getCard(name, set) : cp; + } + PaperCard cp = variants().tryGetCard(name, true); + return cp == null ? instance().getCard(name) : cp; + } + + // returns a list of all cards from their respective latest editions + @Override + public Collection getUniqueCards() { + return roUniqueCards; + } + + @Override + public List getAllCards() { + return roAllCards; + } + + /** Returns a modifiable list of cards matching the given predicate */ + @Override + public List getAllCards(Predicate predicate) { + return Lists.newArrayList(Iterables.filter(this.roAllCards, predicate)); + } + + private static class CardSorter{ + // Here are refs, get them by name + public final Map regularCards = new TreeMap(String.CASE_INSENSITIVE_ORDER); + public final Map variantsCards = new TreeMap(String.CASE_INSENSITIVE_ORDER); + + private void addNewCard(final CardRules card) { + if (null == card) { + return; + } // consider that a success + // System.out.println(card.getName()); + final String cardName = card.getName(); + + + if ( card.isTraditional() ) + regularCards.put(cardName, card); + else + variantsCards.put(cardName, card); + } + + CardSorter(final Iterable parser) { + for (CardRules cr : parser) { + this.addNewCard(cr); + } + } + } + + + public Predicate wasPrintedInSets(List setCodes) { + return new PredicateExistsInSets(setCodes); + } + + private class PredicateExistsInSets implements Predicate { + private final List sets; + + public PredicateExistsInSets(final List wantSets) { + this.sets = wantSets; // maybe should make a copy here? + } + + @Override + public boolean apply(final PaperCard subject) { + Collection cc = allCardsByName.get(subject.getName()); + for(PaperCard c : cc) if (sets.contains(c.getEdition())) return true; + return false; + } + } + +} diff --git a/src/main/java/forge/card/CardEdition.java b/src/main/java/forge/card/CardEdition.java index 9251a63372a..30f302bc89d 100644 --- a/src/main/java/forge/card/CardEdition.java +++ b/src/main/java/forge/card/CardEdition.java @@ -17,16 +17,26 @@ */ package forge.card; +import java.io.File; +import java.io.FilenameFilter; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; import java.util.Locale; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; import com.google.common.base.Function; import com.google.common.base.Predicate; import forge.Singletons; import forge.game.GameFormat; -import forge.item.CardDb; import forge.util.FileSection; -import forge.util.storage.StorageReaderFile; +import forge.util.FileUtil; +import forge.util.storage.StorageReaderFolder; /** @@ -40,23 +50,45 @@ import forge.util.storage.StorageReaderFile; public final class CardEdition implements Comparable { // immutable public enum Type { UNKNOWN, + CORE, EXPANSION, + REPRINT, STARTER, - OTHER + + DUEL_DECKS, + PREMIUM_DECK_SERIES, + FROM_THE_VAULT, + + OTHER, + THIRDPARTY // custom sets } - /** The Constant unknown. */ - public static final CardEdition UNKNOWN = new CardEdition(-1, "??", "???", Type.UNKNOWN, "Undefined", null, false); + public static class CardInSet { + public final CardRarity rarity; + public final String name; - private final int index; + public CardInSet(final String name, final CardRarity rarity) { + this.rarity = rarity; + this.name = name; + } + } + + + /** The Constant unknown. */ + private final static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + + public static final CardEdition UNKNOWN = new CardEdition("1990-01-01", "??", "???", Type.UNKNOWN, "Undefined", null, false, new CardInSet[]{}); + + private Date date; private final String code2; private final String code; private final Type type; private final String name; private final String alias; private final boolean whiteBorder; + private final CardInSet[] cards; /** * Instantiates a new card set. @@ -71,22 +103,30 @@ public final class CardEdition implements Comparable { // immutable * @param name the name of the set * @param an optional secondary code alias for the set */ - private CardEdition(int index, String code2, String code, Type type, String name, String alias, boolean whiteBorder) { - this.index = index; + private CardEdition(String date, String code2, String code, Type type, String name, String alias, boolean whiteBorder, CardInSet[] cards) { this.code2 = code2; this.code = code; this.type = type; this.name = name; this.alias = alias; this.whiteBorder = whiteBorder; + this.cards = cards; + if( date.length() <= 7 ) + date = date + "-01"; + try { + this.date = formatter.parse(date); + } catch (ParseException e) { + this.date = new Date(); + } } - public int getIndex() { return index; } + public Date getDate() { return date; } public String getCode2() { return code2; } public String getCode() { return code; } public Type getType() { return type; } public String getName() { return name; } public String getAlias() { return alias; } + public CardInSet[] getCards() { return cards; } /** The Constant fnGetName. */ public static final Function FN_GET_CODE = new Function() { @@ -101,7 +141,7 @@ public final class CardEdition implements Comparable { // immutable if (o == null) { return 1; } - return o.index - this.index; + return date.compareTo(o.date); } @Override @@ -202,19 +242,26 @@ public final class CardEdition implements Comparable { // immutable } - public static class Reader extends StorageReaderFile { - public Reader(String pathname) { - super(pathname, CardEdition.FN_GET_CODE); + public static class EditionReader extends StorageReaderFolder { + public EditionReader(File path) { + super(path, CardEdition.FN_GET_CODE); } + + public final static CardInSet[] arrCards = new CardInSet[] {}; @Override - protected CardEdition read(String line, int i) { - FileSection section = FileSection.parse(line, ":", "|"); - int index = 1+i; - String code2 = section.get("code2"); - String code = section.get("code3"); - String type = section.get("type"); + protected CardEdition read(File file) { + final Map> contents = FileSection.parseSections(FileUtil.readFile(file)); + + FileSection section = FileSection.parse(contents.get("metadata"), "="); String name = section.get("name"); + String date = section.get("date"); + String code = section.get("code"); + String code2 = section.get("code2"); + if( code2 == null ) + code2 = code; + + String type = section.get("type"); String alias = section.get("alias"); boolean borderWhite = "white".equalsIgnoreCase(section.get("border")); @@ -228,10 +275,33 @@ public final class CardEdition implements Comparable { // immutable } } - // if( !code2.equals(code) ) System.out.printf("%s->%s|", code, code); + List processedCards = new ArrayList(); + for(String line : contents.get("cards")) { + if (StringUtils.isBlank(line)) + continue; - return new CardEdition(index, code2, code, enumType, name, alias, borderWhite); + // You may omit rarity for early development + CardRarity r = CardRarity.smartValueOf(line.substring(0, 1)); + boolean hadRarity = r != CardRarity.Unknown && line.charAt(1) == ' '; + String cardName = hadRarity ? line.substring(2) : line; + CardInSet cis = new CardInSet(cardName, r); + processedCards.add(cis); + } + + return new CardEdition(date, code2, code, enumType, name, alias, borderWhite, processedCards.toArray(arrCards)); } + @Override + protected FilenameFilter getFileFilter() { + return TXT_FILE_FILTER; + } + + + public static final FilenameFilter TXT_FILE_FILTER = new FilenameFilter() { + @Override + public boolean accept(final File dir, final String name) { + return name.endsWith(".txt"); + } + }; } } diff --git a/src/main/java/forge/card/CardInSet.java b/src/main/java/forge/card/CardInSet.java deleted file mode 100644 index d9247f12b01..00000000000 --- a/src/main/java/forge/card/CardInSet.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.card; - -/** - *

- * CardInSet class. - *

- * - * @author Forge - * @version $Id: CardInSet.java 9708 2011-08-09 19:34:12Z jendave $ - */ - -public class CardInSet { - private final CardRarity rarity; - private final int numCopies; - - /** - * Instantiates a new card in set. - * - * @param rarity - * the rarity - * @param cntCopies - * the cnt copies - */ - public CardInSet(final CardRarity rarity, final int cntCopies ) { - this.rarity = rarity; - this.numCopies = cntCopies; - } - - /** - * Gets the copies count. - * - * @return the copies count - */ - public final int getCopiesCount() { - return this.numCopies; - } - - /** - * Gets the rarity. - * - * @return the rarity - */ - public final CardRarity getRarity() { - return this.rarity; - } - -} diff --git a/src/main/java/forge/card/CardRarity.java b/src/main/java/forge/card/CardRarity.java index 2c9cd4fe7b5..6f5b19f5fd9 100644 --- a/src/main/java/forge/card/CardRarity.java +++ b/src/main/java/forge/card/CardRarity.java @@ -36,4 +36,12 @@ public enum CardRarity { public String toString() { return this.strValue; } + + public static CardRarity smartValueOf(String input) { + for(CardRarity r : CardRarity.values()) { + if( r.name().equalsIgnoreCase(input) || r.strValue.equalsIgnoreCase(input)) + return r; + } + return Unknown; + } } diff --git a/src/main/java/forge/card/CardRules.java b/src/main/java/forge/card/CardRules.java index a1e1062c9ae..5de093ce270 100644 --- a/src/main/java/forge/card/CardRules.java +++ b/src/main/java/forge/card/CardRules.java @@ -19,10 +19,6 @@ package forge.card; import java.util.List; import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; - import forge.card.mana.ManaCost; /** @@ -36,13 +32,13 @@ public final class CardRules implements ICardCharacteristics { private final CardSplitType splitType; private final ICardFace mainPart; private final ICardFace otherPart; - private final Map setsPrinted = new TreeMap(String.CASE_INSENSITIVE_ORDER); + //private final Map setsPrinted = new TreeMap(String.CASE_INSENSITIVE_ORDER); private CardAiHints aiHints; private ColorSet colorIdentity = null; - public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah, Map sets) { + public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah) { splitType = altMode; mainPart = faces[0]; otherPart = faces[1]; @@ -50,16 +46,16 @@ public final class CardRules implements ICardCharacteristics { //System.out.print(faces[0].getName()); - for (Entry cs : sets.entrySet()) { - if( CardRulesReader.editions.get(cs.getKey()) != null ) - setsPrinted.put(cs.getKey(), cs.getValue()); - } - - if ( setsPrinted.isEmpty() ) { - System.err.println(getName() + " was not assigned any set."); - setsPrinted.put(CardEdition.UNKNOWN.getCode(), new CardInSet(CardRarity.Common, 1) ); - } - +// for (Entry cs : sets.entrySet()) { +// if( CardRulesReader.editions.get(cs.getKey()) != null ) +// setsPrinted.put(cs.getKey(), cs.getValue()); +// } +// +// if ( setsPrinted.isEmpty() ) { +// System.err.println(getName() + " was not assigned any set."); +// setsPrinted.put(CardEdition.UNKNOWN.getCode(), new CardInSet(CardRarity.Common, 1) ); +// } +// //Calculate Color Identity byte colMask = calculateColorIdentity(mainPart); @@ -176,11 +172,11 @@ public final class CardRules implements ICardCharacteristics { } } - public Set getSets() { return this.setsPrinted.keySet(); } - public CardInSet getEditionInfo(final String setCode) { - final CardInSet result = this.setsPrinted.get(setCode); - return result; // if returns null, String.format("Card '%s' was never printed in set '%s'", this.getName(), setCode); - } +// public Set getSets() { return this.setsPrinted.keySet(); } +// public CardInSet getEditionInfo(final String setCode) { +// final CardInSet result = this.setsPrinted.get(setCode); +// return result; // if returns null, String.format("Card '%s' was never printed in set '%s'", this.getName(), setCode); +// } // vanguard card fields, they don't use sides. private int deltaHand; diff --git a/src/main/java/forge/card/CardRulesPredicates.java b/src/main/java/forge/card/CardRulesPredicates.java index a555c62dfb6..a67aa6793d8 100644 --- a/src/main/java/forge/card/CardRulesPredicates.java +++ b/src/main/java/forge/card/CardRulesPredicates.java @@ -159,17 +159,6 @@ public final class CardRulesPredicates { }; } - /** - * Was printed in sets. - * - * @param setCodes - * the set codes - * @return the predicate - */ - public static Predicate wasPrintedInSets(final List setCodes) { - return new PredicateExistsInSets(setCodes); - } - /** * Core type. * @@ -439,22 +428,6 @@ public final class CardRulesPredicates { } } - private static class PredicateExistsInSets implements Predicate { - private final List sets; - - public PredicateExistsInSets(final List wantSets) { - this.sets = wantSets; // maybe should make a copy here? - } - - @Override - public boolean apply(final CardRules subject) { - for (final String s : this.sets) - if ( null != subject.getEditionInfo(s) ) - return true; - return false; - } - } - private static class PredicateSplitType implements Predicate { private final CardSplitType cst; diff --git a/src/main/java/forge/card/CardRulesReader.java b/src/main/java/forge/card/CardRulesReader.java index fb1ff50e9c2..fa7cbe882ee 100644 --- a/src/main/java/forge/card/CardRulesReader.java +++ b/src/main/java/forge/card/CardRulesReader.java @@ -17,10 +17,7 @@ */ package forge.card; -import java.util.Map; import java.util.StringTokenizer; -import java.util.TreeMap; - import org.apache.commons.lang3.StringUtils; import forge.card.mana.IParserManaCost; @@ -38,8 +35,6 @@ import forge.card.mana.ManaCostShard; * @version $Id$ */ public class CardRulesReader { - public final static EditionCollection editions = new EditionCollection(); // create a copy here, Singletons.model... is not initialized yet. - // fields to build private CardFace[] faces = new CardFace[] { null, null }; private String[] pictureUrl = new String[] { null, null }; @@ -47,8 +42,6 @@ public class CardRulesReader { private CardSplitType altMode = CardSplitType.None; private String handLife = null; - private Map sets = new TreeMap(String.CASE_INSENSITIVE_ORDER); - // fields to build CardAiHints private boolean removedFromAIDecks = false; private boolean removedFromRandomDecks = false; @@ -68,8 +61,6 @@ public class CardRulesReader { this.faces[1] = null; this.pictureUrl[0] = null; this.pictureUrl[1] = null; - - this.sets.clear(); this.handLife = null; this.altMode = CardSplitType.None; @@ -89,7 +80,7 @@ public class CardRulesReader { CardAiHints cah = new CardAiHints(removedFromAIDecks, removedFromRandomDecks, hints, needs ); faces[0].assignMissingFields(); if (null != faces[1]) faces[1].assignMissingFields(); - final CardRules result = new CardRules(faces, altMode, cah, sets); + final CardRules result = new CardRules(faces, altMode, cah); result.setDlUrls(pictureUrl); if (StringUtils.isNotBlank(handLife)) result.setVanguardProperties(handLife); @@ -219,7 +210,7 @@ public class CardRulesReader { } else this.faces[curFace].addSVar(variable, value); } else if ("SetInfo".equals(key)) { - parseSetInfoLine(value); + // deprecated } break; @@ -236,64 +227,6 @@ public class CardRulesReader { } - /** - * Parse a SetInfo line from a card txt file. - * - * @param line - * must begin with "SetInfo:" - * @param setsData - * the current mapping of set names to CardInSet instances - */ - private void parseSetInfoLine(final String value) { - // Sample SetInfo line: - // SetInfo:POR Land x4 - - int i = 0; - String setCode = null; - String txtRarity = "Common"; - String txtCount = "x1"; - - StringTokenizer stt = new StringTokenizer(value, " "); - while(stt.hasMoreTokens()) { - if( i == 0 ) setCode = stt.nextToken(); - if( i == 1 ) txtRarity = stt.nextToken(); - if( i == 2 ) txtCount = stt.nextToken(); - i++; - } - - - int numIllustrations = 1; - if ( i > 2 ) - numIllustrations = Integer.parseInt(txtCount.substring(1)); - - if (sets.containsKey(setCode)) { - System.err.print(faces[0].getName()); - throw new RuntimeException("Found multiple SetInfo lines for set code <<" + setCode + ">>"); - } - - - CardRarity rarity = null; - if ("Land".equals(txtRarity)) { - rarity = CardRarity.BasicLand; - } else if ("Common".equals(txtRarity)) { - rarity = CardRarity.Common; - } else if ("Uncommon".equals(txtRarity)) { - rarity = CardRarity.Uncommon; - } else if ("Rare".equals(txtRarity)) { - rarity = CardRarity.Rare; - } else if ("Mythic".equals(txtRarity)) { - rarity = CardRarity.MythicRare; - } else if ("Special".equals(txtRarity)) { - rarity = CardRarity.Special; - } else { - throw new RuntimeException("Unrecognized rarity string <<" + txtRarity + ">>"); - } - - final CardInSet cardInSet = new CardInSet(rarity, numIllustrations); - - sets.put(setCode, cardInSet); - } - /** * Instantiates class, reads a card. Do not use for batch operations. * @param script diff --git a/src/main/java/forge/card/EditionCollection.java b/src/main/java/forge/card/EditionCollection.java index 991a33c583a..d33d8e988c3 100644 --- a/src/main/java/forge/card/EditionCollection.java +++ b/src/main/java/forge/card/EditionCollection.java @@ -17,6 +17,7 @@ */ package forge.card; +import java.io.File; import java.util.Map; import java.util.TreeMap; @@ -28,8 +29,8 @@ public final class EditionCollection extends StorageView { private final Map aliasToEdition = new TreeMap(); - public EditionCollection() { - super(new CardEdition.Reader("res/blockdata/setdata.txt")); + public EditionCollection(File folder) { + super(new CardEdition.EditionReader(folder)); for (CardEdition ee : this) { String alias = ee.getAlias(); @@ -54,7 +55,7 @@ public final class EditionCollection extends StorageView { } /** - * Gets the sets the by code or throw. + * Gets the sets by code or throw. * * @param code * the code diff --git a/src/main/java/forge/card/ICardDatabase.java b/src/main/java/forge/card/ICardDatabase.java new file mode 100644 index 00000000000..b87217f6c95 --- /dev/null +++ b/src/main/java/forge/card/ICardDatabase.java @@ -0,0 +1,27 @@ +package forge.card; + +import java.util.Collection; +import java.util.List; + +import com.google.common.base.Predicate; + +import forge.item.PaperCard; + +public interface ICardDatabase { + PaperCard tryGetCard(String cardName); + PaperCard tryGetCard(String cardName, boolean fromLastSet); + PaperCard tryGetCard(String cardName, String edition); + int getPrintCount(String cardName, String edition); + int getMaxPrintCount(String cardName); + PaperCard tryGetCard(String cardName, String edition, int artIndex); + PaperCard getCard(String cardName); + PaperCard getCard(String cardName, boolean fromLastSet); + PaperCard getCard(String cardName, String edition); + PaperCard getCard(String cardName, String edition, int artIndex); + + Collection getUniqueCards(); + List getAllCards(); + List getAllCards(Predicate predicate); + + Predicate wasPrintedInSets(List allowedSetCodes); +} \ No newline at end of file diff --git a/src/main/java/forge/card/UnOpenedProduct.java b/src/main/java/forge/card/UnOpenedProduct.java index 000517fae56..272b32644b3 100644 --- a/src/main/java/forge/card/UnOpenedProduct.java +++ b/src/main/java/forge/card/UnOpenedProduct.java @@ -10,7 +10,6 @@ import org.apache.commons.lang3.tuple.Pair; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.ItemPoolView; import forge.item.PrintSheet; diff --git a/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java b/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java index 1d427bb5272..95ad9b9cc1f 100644 --- a/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java @@ -13,6 +13,7 @@ import com.google.common.collect.Lists; import forge.Card; import forge.CardLists; import forge.CardPredicates.Presets; +import forge.card.CardDb; import forge.card.CardRules; import forge.card.CardRulesPredicates; import forge.card.ability.AbilityUtils; @@ -23,7 +24,6 @@ import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; -import forge.item.CardDb; import forge.item.PaperCard; import forge.util.Aggregates; import forge.util.ComparableOp; diff --git a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java index 2f1be3eabc4..123f19bc06e 100644 --- a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java +++ b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java @@ -16,6 +16,7 @@ import forge.CardCharacteristicName; import forge.CardLists; import forge.Command; import forge.GameEntity; +import forge.card.CardDb; import forge.card.CardRulesPredicates; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; @@ -30,7 +31,6 @@ import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; -import forge.item.CardDb; import forge.item.PaperCard; import forge.util.Aggregates; import forge.util.PredicateString.StringOp; diff --git a/src/main/java/forge/card/ability/effects/PlayEffect.java b/src/main/java/forge/card/ability/effects/PlayEffect.java index 74d7ca98727..cef26c29558 100644 --- a/src/main/java/forge/card/ability/effects/PlayEffect.java +++ b/src/main/java/forge/card/ability/effects/PlayEffect.java @@ -13,6 +13,7 @@ import com.google.common.collect.Lists; import forge.Card; import forge.CardCharacteristicName; import forge.CardLists; +import forge.card.CardDb; import forge.card.CardRulesPredicates; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; @@ -27,7 +28,6 @@ import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; import forge.gui.GuiDialog; -import forge.item.CardDb; import forge.item.PaperCard; import forge.util.Aggregates; diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index a0fb5f55978..687958bc1ed 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -30,6 +30,7 @@ import forge.Command; import forge.CounterType; import forge.ImageCache; import forge.card.CardCharacteristics; +import forge.card.CardDb; import forge.card.CardRules; import forge.card.CardSplitType; import forge.card.ICardFace; @@ -46,7 +47,6 @@ import forge.card.spellability.Target; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.game.player.Player; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; diff --git a/src/main/java/forge/deck/CardPool.java b/src/main/java/forge/deck/CardPool.java index 4dbdd76b70f..796fae40c63 100644 --- a/src/main/java/forge/deck/CardPool.java +++ b/src/main/java/forge/deck/CardPool.java @@ -27,7 +27,7 @@ import java.util.NoSuchElementException; import org.apache.commons.lang3.StringUtils; import forge.Card; -import forge.item.CardDb; +import forge.card.CardDb; import forge.item.PaperCard; import forge.item.ItemPool; diff --git a/src/main/java/forge/deck/Deck.java b/src/main/java/forge/deck/Deck.java index bc9699f2953..dc6dbc87586 100644 --- a/src/main/java/forge/deck/Deck.java +++ b/src/main/java/forge/deck/Deck.java @@ -31,10 +31,10 @@ import org.apache.commons.lang3.StringUtils; import com.google.common.base.Function; +import forge.card.CardDb; import forge.deck.io.DeckFileHeader; import forge.deck.io.DeckSerializer; import forge.gui.deckeditor.tables.TableSorter; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.item.ItemPoolView; diff --git a/src/main/java/forge/deck/DeckFormat.java b/src/main/java/forge/deck/DeckFormat.java index 76b6c0d1b57..ac9c8cf92c0 100644 --- a/src/main/java/forge/deck/DeckFormat.java +++ b/src/main/java/forge/deck/DeckFormat.java @@ -26,8 +26,8 @@ import org.apache.commons.lang.math.IntRange; import forge.Singletons; import forge.card.CardCoreType; +import forge.card.CardDb; import forge.card.ColorSet; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.properties.ForgePreferences.FPref; diff --git a/src/main/java/forge/deck/DeckRecognizer.java b/src/main/java/forge/deck/DeckRecognizer.java index c24490f6c68..2575ae2963b 100644 --- a/src/main/java/forge/deck/DeckRecognizer.java +++ b/src/main/java/forge/deck/DeckRecognizer.java @@ -22,7 +22,7 @@ import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; -import forge.item.CardDb; +import forge.card.CardDb; import forge.item.PaperCard; /** diff --git a/src/main/java/forge/deck/DeckgenUtil.java b/src/main/java/forge/deck/DeckgenUtil.java index 539f8d0ebba..67ca9f89efa 100644 --- a/src/main/java/forge/deck/DeckgenUtil.java +++ b/src/main/java/forge/deck/DeckgenUtil.java @@ -15,13 +15,13 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import forge.Singletons; +import forge.card.CardDb; import forge.deck.generate.Generate2ColorDeck; import forge.deck.generate.Generate3ColorDeck; import forge.deck.generate.Generate5ColorDeck; import forge.deck.generate.GenerateColoredDeckBase; import forge.deck.generate.GenerateMonoColorDeck; import forge.deck.generate.GenerateThemeDeck; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.ItemPoolView; import forge.item.PreconDeck; diff --git a/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java b/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java index 510ffc465ed..393adf72a3c 100644 --- a/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java +++ b/src/main/java/forge/deck/generate/GenerateColoredDeckBase.java @@ -33,12 +33,12 @@ import com.google.common.collect.Lists; import forge.Constant; import forge.Singletons; +import forge.card.CardDb; import forge.card.CardRules; import forge.card.CardRulesPredicates; import forge.card.ColorSet; import forge.card.MagicColor; import forge.deck.generate.GenerateDeckUtil.FilterCMC; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.ItemPool; import forge.item.ItemPoolView; @@ -133,7 +133,7 @@ public abstract class GenerateColoredDeckBase { // not an error if looped too much - could play singleton mode, with 6 slots for 3 non-basic lands. PaperCard cp = CardDb.instance().getCard(s); - tDeck.add(CardDb.instance().getCard(cp.getName(), Aggregates.random(cp.getRules().getSets()))); + tDeck.add(CardDb.instance().getCard(cp.getName(), false)); final int n = this.cardCounts.get(s); this.cardCounts.put(s, n + 1); @@ -170,7 +170,7 @@ public abstract class GenerateColoredDeckBase { this.cardCounts.put(color, nLand); PaperCard cp = CardDb.instance().getCard(color); - String basicLandSet = Aggregates.random(cp.getRules().getSets()); + String basicLandSet = cp.getEdition(); tDeck.add(CardDb.instance().getCard(cp.getName(), basicLandSet), nLand); landsLeft -= nLand; @@ -222,8 +222,7 @@ public abstract class GenerateColoredDeckBase { final List curvedRandomized = Lists.newArrayList(); for (PaperCard c : curved) { this.cardCounts.put(c.getName(), 0); - PaperCard cpRandomSet = CardDb.instance().getCard(c.getName(), Aggregates.random(c.getRules().getSets())); - curvedRandomized.add(cpRandomSet); + curvedRandomized.add(CardDb.instance().getCard(c.getName(), false)); } addSome(addOfThisCmc, curvedRandomized); diff --git a/src/main/java/forge/deck/generate/GenerateThemeDeck.java b/src/main/java/forge/deck/generate/GenerateThemeDeck.java index 74d7e85302d..1c9f2297399 100644 --- a/src/main/java/forge/deck/generate/GenerateThemeDeck.java +++ b/src/main/java/forge/deck/generate/GenerateThemeDeck.java @@ -22,8 +22,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import forge.card.CardDb; import forge.error.BugReporter; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.ItemPoolView; import forge.util.FileUtil; diff --git a/src/main/java/forge/game/GameFormat.java b/src/main/java/forge/game/GameFormat.java index 25dcd7ccf86..a83d3fee5d6 100644 --- a/src/main/java/forge/game/GameFormat.java +++ b/src/main/java/forge/game/GameFormat.java @@ -26,6 +26,7 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Lists; +import forge.card.CardDb; import forge.card.CardRulesPredicates; import forge.item.PaperCard; import forge.item.IPaperCard; @@ -90,7 +91,7 @@ public class GameFormat implements Comparable { if (this.allowedSetCodes == null || this.allowedSetCodes.isEmpty()) { return banNames; } - return Predicates.and(banNames, Predicates.compose(CardRulesPredicates.wasPrintedInSets(this.allowedSetCodes), PaperCard.FN_GET_RULES)); + return Predicates.and(banNames, CardDb.instance().wasPrintedInSets(this.allowedSetCodes)); } /** diff --git a/src/main/java/forge/game/GameNew.java b/src/main/java/forge/game/GameNew.java index 6628563d3b6..223069ced4e 100644 --- a/src/main/java/forge/game/GameNew.java +++ b/src/main/java/forge/game/GameNew.java @@ -19,6 +19,7 @@ import forge.Card; import forge.CardLists; import forge.CardPredicates; import forge.GameLogEntryType; +import forge.card.CardDb; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.deck.CardPool; @@ -29,7 +30,6 @@ import forge.game.player.PlayerType; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.gui.GuiDialog; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.properties.ForgePreferences; @@ -122,12 +122,9 @@ public class GameNew { PaperCard cpi = cp; // apply random pictures for cards if (preferences.getPrefBoolean(FPref.UI_RANDOM_CARD_ART)) { - final int cntVariants = cp.getRules().getEditionInfo(cp.getEdition()).getCopiesCount(); - if (cntVariants > 1) { - cpi = CardDb.instance().getCard(cp.getName(), cp.getEdition(), generator.nextInt(cntVariants)); - if ( cp.isFoil() ) - cpi = PaperCard.makeFoiled(cpi); - } + cpi = CardDb.instance().getCard(cp.getName(), cp.getEdition(), -1); + if ( cp.isFoil() ) + cpi = PaperCard.makeFoiled(cpi); } final Card card = cpi.toForgeCard(player); diff --git a/src/main/java/forge/game/limited/BoosterDraft.java b/src/main/java/forge/game/limited/BoosterDraft.java index 52e9f2ab66d..4f033364f2f 100644 --- a/src/main/java/forge/game/limited/BoosterDraft.java +++ b/src/main/java/forge/game/limited/BoosterDraft.java @@ -38,13 +38,13 @@ import forge.Constant.Preferences; import forge.Singletons; import forge.card.BoosterTemplate; import forge.card.CardBlock; +import forge.card.CardDb; import forge.card.CardEdition; import forge.card.IUnOpenedProduct; import forge.card.SealedProductTemplate; import forge.card.UnOpenedProduct; import forge.deck.Deck; import forge.gui.GuiChoose; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.item.ItemPool; diff --git a/src/main/java/forge/game/limited/CustomLimited.java b/src/main/java/forge/game/limited/CustomLimited.java index cbc76bdffe1..622ad860d80 100644 --- a/src/main/java/forge/game/limited/CustomLimited.java +++ b/src/main/java/forge/game/limited/CustomLimited.java @@ -25,10 +25,10 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import forge.card.BoosterTemplate; +import forge.card.CardDb; import forge.card.SealedProductTemplate; import forge.deck.Deck; import forge.deck.DeckBase; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.ItemPool; import forge.item.ItemPoolView; diff --git a/src/main/java/forge/game/limited/LimitedDeckBuilder.java b/src/main/java/forge/game/limited/LimitedDeckBuilder.java index b208183af94..be93cea168d 100644 --- a/src/main/java/forge/game/limited/LimitedDeckBuilder.java +++ b/src/main/java/forge/game/limited/LimitedDeckBuilder.java @@ -19,6 +19,7 @@ import com.google.common.collect.Lists; import forge.Constant.Preferences; import forge.card.CardAiHints; +import forge.card.CardDb; import forge.card.CardRules; import forge.card.CardRulesPredicates; import forge.card.ColorSet; @@ -30,7 +31,6 @@ import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckSection; import forge.deck.generate.GenerateDeckUtil; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.util.MyRandom; diff --git a/src/main/java/forge/game/limited/SealedCardPoolGenerator.java b/src/main/java/forge/game/limited/SealedCardPoolGenerator.java index 38591575e77..98cd353bac5 100644 --- a/src/main/java/forge/game/limited/SealedCardPoolGenerator.java +++ b/src/main/java/forge/game/limited/SealedCardPoolGenerator.java @@ -29,13 +29,13 @@ import org.apache.commons.lang.ArrayUtils; import forge.Singletons; import forge.card.BoosterTemplate; import forge.card.CardBlock; +import forge.card.CardDb; import forge.card.CardEdition; import forge.card.IUnOpenedProduct; import forge.card.UnOpenedMeta; import forge.card.UnOpenedProduct; import forge.deck.CardPool; import forge.gui.GuiChoose; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.ItemPool; import forge.util.FileUtil; diff --git a/src/main/java/forge/gauntlet/GauntletIO.java b/src/main/java/forge/gauntlet/GauntletIO.java index f392ce553ac..0669436c7ee 100644 --- a/src/main/java/forge/gauntlet/GauntletIO.java +++ b/src/main/java/forge/gauntlet/GauntletIO.java @@ -20,9 +20,9 @@ import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import forge.card.CardDb; import forge.deck.CardPool; import forge.error.BugReporter; -import forge.item.CardDb; import forge.item.PaperCard; import forge.properties.NewConstants; import forge.util.IgnoringXStream; diff --git a/src/main/java/forge/gui/GuiDisplayUtil.java b/src/main/java/forge/gui/GuiDisplayUtil.java index 788a46a3470..c0b7969fb32 100644 --- a/src/main/java/forge/gui/GuiDisplayUtil.java +++ b/src/main/java/forge/gui/GuiDisplayUtil.java @@ -41,6 +41,7 @@ import forge.CardLists; import forge.CardPredicates; import forge.CounterType; import forge.Singletons; +import forge.card.CardDb; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.SpellAbility; import forge.card.trigger.TriggerType; @@ -52,7 +53,6 @@ import forge.game.player.HumanPlay; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.input.InputSelectCardsFromList; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; diff --git a/src/main/java/forge/gui/ImportSourceAnalyzer.java b/src/main/java/forge/gui/ImportSourceAnalyzer.java index 7d5b4cff085..1caf756ee6d 100644 --- a/src/main/java/forge/gui/ImportSourceAnalyzer.java +++ b/src/main/java/forge/gui/ImportSourceAnalyzer.java @@ -30,10 +30,10 @@ import com.google.common.collect.Iterables; import forge.ImageCache; import forge.Singletons; +import forge.card.CardDb; import forge.card.CardEdition; import forge.card.CardRules; import forge.card.EditionCollection; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.properties.NewConstants; diff --git a/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java b/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java index 1e2d47965aa..14a15ad81f8 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java @@ -5,6 +5,7 @@ import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import forge.Command; +import forge.card.CardDb; import forge.card.CardRulesPredicates; import forge.deck.Deck; import forge.deck.DeckBase; @@ -16,7 +17,6 @@ import forge.gui.deckeditor.SEditorIO; import forge.gui.deckeditor.views.VDeckgen; import forge.gui.framework.ICDoc; import forge.gui.toolbox.FLabel; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.InventoryItem; import forge.util.Aggregates; diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java index 713a243452f..2e28225efff 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java @@ -26,6 +26,7 @@ import com.google.common.base.Supplier; import forge.Command; import forge.Singletons; +import forge.card.CardDb; import forge.card.CardRulesPredicates; import forge.deck.Deck; import forge.deck.DeckSection; @@ -41,7 +42,6 @@ import forge.gui.deckeditor.views.VCardCatalog; import forge.gui.deckeditor.views.VCurrentDeck; import forge.gui.framework.EDocID; import forge.gui.toolbox.FLabel; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.InventoryItem; import forge.item.ItemPool; diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java index 982dce85f49..4b691e69d9d 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java @@ -21,6 +21,7 @@ import javax.swing.JOptionPane; import javax.swing.ListSelectionModel; import forge.Singletons; +import forge.card.CardDb; import forge.control.FControl; import forge.deck.CardPool; import forge.deck.Deck; @@ -37,7 +38,6 @@ import forge.gui.deckeditor.views.VCurrentDeck; import forge.gui.deckeditor.views.VDeckgen; import forge.gui.framework.DragCell; import forge.gui.home.sanctioned.CSubmenuDraft; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.InventoryItem; import forge.item.ItemPoolView; diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java index 98b1895abcf..f153e62874f 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java @@ -33,6 +33,7 @@ import com.google.common.base.Function; import forge.Command; import forge.Singletons; +import forge.card.CardDb; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckBase; @@ -54,7 +55,6 @@ import forge.gui.home.quest.CSubmenuQuestDecks; import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FSkin; import forge.item.BoosterPack; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.FatPack; import forge.item.IPaperCard; diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java index 9df31b0caa0..c9659a6f9db 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java @@ -24,6 +24,7 @@ import com.google.common.base.Supplier; import com.google.common.collect.Iterables; import forge.Singletons; +import forge.card.CardDb; import forge.deck.Deck; import forge.deck.DeckSection; import forge.gui.deckeditor.SEditorIO; @@ -39,7 +40,6 @@ import forge.gui.deckeditor.views.VCurrentDeck; import forge.gui.deckeditor.views.VDeckgen; import forge.gui.framework.DragCell; import forge.gui.framework.EDocID; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.InventoryItem; import forge.item.ItemPool; diff --git a/src/main/java/forge/gui/download/GuiDownloadPicturesLQ.java b/src/main/java/forge/gui/download/GuiDownloadPicturesLQ.java index 3d1dbbcea65..b2a9ead4172 100644 --- a/src/main/java/forge/gui/download/GuiDownloadPicturesLQ.java +++ b/src/main/java/forge/gui/download/GuiDownloadPicturesLQ.java @@ -24,8 +24,8 @@ import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; import forge.ImageCache; +import forge.card.CardDb; import forge.card.CardRules; -import forge.item.CardDb; import forge.item.PaperCard; import forge.properties.NewConstants; diff --git a/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java b/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java index 11d7057e515..c0dd2fe15ce 100644 --- a/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java +++ b/src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java @@ -26,8 +26,8 @@ import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Iterables; import forge.ImageCache; +import forge.card.CardDb; import forge.card.CardEdition; -import forge.item.CardDb; import forge.item.PaperCard; import forge.properties.NewConstants; diff --git a/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java b/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java index 4b102df8478..b3a69099070 100644 --- a/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java +++ b/src/main/java/forge/gui/home/variant/VSubmenuVanguard.java @@ -17,6 +17,7 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import net.miginfocom.swing.MigLayout; +import forge.card.CardDb; import forge.gui.CardDetailPanel; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; @@ -35,7 +36,6 @@ import forge.gui.toolbox.FRadioButton; import forge.gui.toolbox.FScrollPane; import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FTabbedPane; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; diff --git a/src/main/java/forge/gui/match/ControlWinLose.java b/src/main/java/forge/gui/match/ControlWinLose.java index 8aece6cac9b..7f792c045b3 100644 --- a/src/main/java/forge/gui/match/ControlWinLose.java +++ b/src/main/java/forge/gui/match/ControlWinLose.java @@ -9,6 +9,7 @@ import javax.swing.JButton; import forge.Card; import forge.Singletons; +import forge.card.CardDb; import forge.control.FControl; import forge.deck.Deck; import forge.game.GameOutcome; @@ -19,7 +20,6 @@ import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; import forge.gui.SOverlayUtils; -import forge.item.CardDb; import forge.item.PaperCard; import forge.properties.ForgePreferences.FPref; diff --git a/src/main/java/forge/gui/match/QuestWinLose.java b/src/main/java/forge/gui/match/QuestWinLose.java index 2850605395a..1350dc11549 100644 --- a/src/main/java/forge/gui/match/QuestWinLose.java +++ b/src/main/java/forge/gui/match/QuestWinLose.java @@ -35,6 +35,7 @@ import org.apache.commons.lang.StringUtils; import forge.Card; import forge.Singletons; import forge.card.BoosterTemplate; +import forge.card.CardDb; import forge.card.CardEdition; import forge.card.IUnOpenedProduct; import forge.card.UnOpenedProduct; @@ -55,7 +56,6 @@ import forge.gui.home.quest.CSubmenuChallenges; import forge.gui.home.quest.CSubmenuDuels; import forge.gui.toolbox.FSkin; import forge.item.BoosterPack; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.InventoryItem; import forge.item.OpenablePack; diff --git a/src/main/java/forge/item/CardDb.java b/src/main/java/forge/item/CardDb.java deleted file mode 100644 index 7a714532bcf..00000000000 --- a/src/main/java/forge/item/CardDb.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.item; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.TreeMap; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -import forge.Card; -import forge.card.CardInSet; -import forge.card.CardRules; -import forge.util.Aggregates; - -public final class CardDb { - private static volatile CardDb commonCards = null; // 'volatile' keyword makes this working - private static volatile CardDb variantCards = null; // 'volatile' keyword makes this working - public final static String foilSuffix = " foil"; - private final static int foilSuffixLength = foilSuffix.length(); - - public static CardDb instance() { - if (CardDb.commonCards == null) { - throw new NullPointerException("CardDb has not yet been initialized, run setup() first"); - } - 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; - } - - public static void setup(final Iterable list) { - if (CardDb.commonCards != null) { - throw new RuntimeException("CardDb has already been initialized, don't do it twice please"); - } - synchronized (CardDb.class) { - 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); - } - } - } - - // Here are refs, get them by name - private final Map uniqueCards; - - - // need this to obtain cardReference by name+set+artindex - private final Map> allCardsBySet; - // this is the same list in flat storage - 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() { - @Override - public PaperCard apply(final Card from) { - return CardDb.instance().getCard(from.getName()); - } - }; - - private CardDb(Map uniqueCards, List cardsFlat, Map> cardsBySet) { - this.uniqueCards = Collections.unmodifiableMap(uniqueCards); - this.allCardsFlat = Collections.unmodifiableList(cardsFlat); - this.allCardsBySet = cardsBySet; - } - - /** - * Splits cardname into Name and set whenever deck line reads as name|set. - */ - private static ImmutablePair splitCardName(final String name) { - String cardName = name; // .trim() ? - final int pipePos = cardName.indexOf('|'); - - if (pipePos >= 0) { - final String setName = cardName.substring(pipePos + 1).trim(); - cardName = cardName.substring(0, pipePos); - // only if set is not blank try to load it - if (StringUtils.isNotBlank(setName) && !"???".equals(setName)) { - return new ImmutablePair(cardName, setName); - } - } - return new ImmutablePair(cardName, null); - } - - private boolean isFoil(final String cardName) { - return cardName.toLowerCase().endsWith(CardDb.foilSuffix) && (cardName.length() > CardDb.foilSuffixLength); - } - - /** - * Removes the foil suffix. - * - * @param cardName the card name - * @return the string - */ - public String removeFoilSuffix(final String cardName) { - return cardName.substring(0, cardName.length() - CardDb.foilSuffixLength); - } - - /** - * Checks if is card supported. - */ - public PaperCard tryGetCard(final String cardName0) { - if (null == cardName0) { - 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.get(nameWithSet.left); - } - - PaperCard res = tryGetCard(nameWithSet.left, nameWithSet.right); - if ( null != res && isFoil ) - return PaperCard.makeFoiled(res); - return res; - - } - - public PaperCard tryGetCard(final String cardName, String setName) { - return tryGetCard(cardName, setName, 0); - } - - public PaperCard tryGetCard(final String cardName, String setName, int index) { - // Set exists? - final Map cardsFromset = this.allCardsBySet.get(setName); - if (cardsFromset == null) { - return null; - } - // Card exists? - final PaperCard[] cardCopies = cardsFromset.get(cardName); - return cardCopies != null && index < cardCopies.length ? cardCopies[index] : null; - } - - // Single fetch - public PaperCard getCard(final String name) { - return this.getCard(name, false); - } - - // Advanced fetch by name+set - public PaperCard getCard(final String name, final String set) { - return this.getCard(name, set, 0); - } - - public PaperCard getCard(final String name, final String set, final int artIndex) { - // 1. get set - final Map cardsFromset = this.allCardsBySet.get(set.toUpperCase()); - if (null == cardsFromset) { - final String err = String - .format("Asked for card '%s' from set '%s': that set was not found. :(", name, set); - throw new NoSuchElementException(err); - } - // 2. Find the card itself - final PaperCard[] cardCopies = cardsFromset.get(name.toLowerCase()); - if (null == cardCopies) { - final String err = String.format("Asked for card '%s' from '%s': set found, but the card wasn't. :(", name, - set); - throw new NoSuchElementException(err); - } - // 3. Get the proper copy - if ((artIndex >= 0) && (artIndex <= cardCopies.length)) { - return cardCopies[artIndex]; - } - final String err = String - .format("Asked for '%s' from '%s' #%d: db didn't find that copy.", name, set, artIndex); - throw new NoSuchElementException(err); - } - - // Fetch from Forge's Card instance. Well, there should be no errors, but - // we'll still check - public static PaperCard getCard(final Card forgeCard) { - final String name = forgeCard.getName(); - final String set = forgeCard.getCurSetCode(); - - if (StringUtils.isNotBlank(set)) { - PaperCard cp = variants().tryGetCard(name, set); - - return cp == null ? instance().getCard(name, set) : cp; - } - PaperCard cp = variants().tryGetCard(name); - return cp == null ? instance().getCard(name) : cp; - } - - // returns a list of all cards from their respective latest editions - public Collection getUniqueCards() { - return this.uniqueCards.values(); - } - - public List getAllCards() { - return this.allCardsFlat; - } - - /** Returns a modifiable list of cards matching the given predicate */ - public List getAllCards(Predicate predicate) { - return Lists.newArrayList(Iterables.filter(this.allCardsFlat, predicate)); - } - - public PaperCard getCard(final String name0, final boolean fromLatestSet) { - // Sometimes they read from decks things like "CardName|Set" - but we - // can handle it - - final boolean isFoil = this.isFoil(name0); - final String name = isFoil ? this.removeFoilSuffix(name0) : name0; - PaperCard result = null; - - final ImmutablePair nameWithSet = CardDb.splitCardName(name); - if (nameWithSet.right != null) { - result = this.getCard(nameWithSet.left, nameWithSet.right); - } else { - if (!fromLatestSet) { - result = this.uniqueCards.get(nameWithSet.left.toLowerCase()); - if (null == result) { - throw new NoSuchElementException(String.format("Card '%s' not found in our database.", name)); - } - } else { - // OK, plain name here - final Predicate predicate = IPaperCard.Predicates.name(nameWithSet.left); - final Iterable namedCards = Iterables.filter(this.allCardsFlat, predicate); - // Find card with maximal set index - result = Aggregates.itemWithMax(namedCards, PaperCard.FN_GET_EDITION_INDEX); - if (null == result) { - throw new NoSuchElementException(String.format("Card '%s' not found in our database.", name)); - } - } - } - if (isFoil) { - result = PaperCard.makeFoiled(result); - } - return result; - } - - private static class CardSorter{ - // 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(); - - public PaperCard addToLists(final CardRules card, final String cardName, final String set, CardInSet cs) { - PaperCard lastAdded = null; - - 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 = cs.getCopiesCount(); - final PaperCard[] cardCopies = new PaperCard[count]; - setMap.put(cardName, cardCopies); - for (int i = 0; i < count; i++) { - lastAdded = PaperCard.build(card, set, cs.getRarity(), i); - if (card.isTraditional()) { - this.allCommonCardsFlat.add(lastAdded); - } else { - this.allSpecialCardsFlat.add(lastAdded); - } - cardCopies[i] = lastAdded; - } - - return lastAdded; - } - - 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 - PaperCard lastAdded = null; - for (final String s : card.getSets()) { - lastAdded = this.addToLists(card, cardName, s, card.getEditionInfo(s)); - } - if ( lastAdded.getRules().isTraditional() ) - uniqueCommonCards.put(cardName, lastAdded); - else - uniqueSpecialCards.put(cardName, lastAdded); - } - - CardSorter(final Iterable parser) { - for (CardRules cr : parser) { - this.addNewCard(cr); - } - } - } -} diff --git a/src/main/java/forge/item/OpenablePack.java b/src/main/java/forge/item/OpenablePack.java index dcf2cef148d..5634b394cd8 100644 --- a/src/main/java/forge/item/OpenablePack.java +++ b/src/main/java/forge/item/OpenablePack.java @@ -28,6 +28,7 @@ import com.google.common.collect.Iterables; import forge.card.BoosterTemplate; import forge.card.BoosterGenerator; +import forge.card.CardDb; import forge.card.CardRulesPredicates; import forge.util.Aggregates; diff --git a/src/main/java/forge/item/PaperCard.java b/src/main/java/forge/item/PaperCard.java index 191a0efb48d..2606c340061 100644 --- a/src/main/java/forge/item/PaperCard.java +++ b/src/main/java/forge/item/PaperCard.java @@ -44,10 +44,10 @@ public final class PaperCard implements Comparable, InventoryItemFro private final transient CardRules card; // These fields are kinda PK for PrintedCard - private final String name; - private final String edition; - private final int artIndex; - private final boolean foiled; + public final String name; + public final String edition; + public final int artIndex; + public final boolean foil; // Calculated fields are below: private final transient CardRarity rarity; // rarity is given in ctor when set is assigned @@ -69,7 +69,7 @@ public final class PaperCard implements Comparable, InventoryItemFro @Override public boolean isFoil() { - return this.foiled; + return this.foil; } @Override @@ -117,59 +117,24 @@ public final class PaperCard implements Comparable, InventoryItemFro } }; - public static final Function FN_GET_EDITION_INDEX = new Function() { - @Override - public Integer apply(final PaperCard from) { - return Integer.valueOf(Singletons.getModel().getEditions().get(from.getEdition()).getIndex()); - } - }; - - // Constructor is private. All non-foiled instances are stored in CardDb - private PaperCard(final CardRules c, final String edition0, final CardRarity rare, final int index, final boolean foil) { + public PaperCard(final CardRules c, final String edition0, final CardRarity rare, final int index) { + this(c, edition0, rare, index, false); + } + + public PaperCard(final CardRules c, final String edition0, final CardRarity rare, final int index, final boolean foil) { this.card = c; this.name = c.getName(); this.edition = edition0; this.artIndex = index; - this.foiled = foil; + this.foil = foil; this.rarity = rare; } - /* package visibility */ - /** - * Builds the. - * - * @param c - * the c - * @param edition - * the set - * @param rare - * the rare - * @param index - * the index - * @return the card printed - */ - static PaperCard build(final CardRules c, final String edition, final CardRarity rare, final int index) { - return new PaperCard(c, edition, rare, index, false); - } - - /* foiled don't need to stay in CardDb's structures, so u'r free to create */ - /** - * Make foiled. - * - * @param c - * the c - * @return the card printed - */ public static PaperCard makeFoiled(final PaperCard c) { return new PaperCard(c.card, c.edition, c.rarity, c.artIndex, true); } - + // Want this class to be a key for HashTable - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(final Object obj) { if (this == obj) { @@ -189,7 +154,7 @@ public final class PaperCard implements Comparable, InventoryItemFro if (!this.edition.equals(other.edition)) { return false; } - if ((other.foiled != this.foiled) || (other.artIndex != this.artIndex)) { + if ((other.foil != this.foil) || (other.artIndex != this.artIndex)) { return false; } @@ -204,7 +169,7 @@ public final class PaperCard implements Comparable, InventoryItemFro @Override public int hashCode() { final int code = (this.name.hashCode() * 11) + (this.edition.hashCode() * 59) + (this.artIndex * 2); - if (this.foiled) { + if (this.foil) { return code + 1; } return code; diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index 263661889a1..d7823ded1ba 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -30,7 +30,7 @@ import forge.Constant.Preferences; import forge.FThreads; import forge.card.BoosterTemplate; import forge.card.CardBlock; -import forge.card.CardRulesReader; +import forge.card.CardDb; import forge.card.EditionCollection; import forge.card.FatPackTemplate; import forge.card.FormatCollection; @@ -41,7 +41,6 @@ import forge.error.BugReporter; import forge.error.ExceptionHandler; import forge.game.limited.GauntletMini; import forge.gauntlet.GauntletData; -import forge.item.CardDb; import forge.item.PrintSheet; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; @@ -143,7 +142,15 @@ public enum FModel { this.questPreferences = new QuestPreferences(); this.gauntletData = new GauntletData(); - this.editions = CardRulesReader.editions; // CardRules ctor cannot refer to FModel, since it is not yet build by that moment + this.editions = new EditionCollection(new File("res/cardeditions")); + + // Loads all cards (using progress bar). + FThreads.assertExecutedByEdt(false); + final CardStorageReader reader = new CardStorageReader(NewConstants.CARD_DATA_DIR, true); + // this fills in our map of card names to Card instances. + CardDb.setup(reader.loadCards(), editions); + + this.formats = new FormatCollection("res/blockdata/formats.txt"); this.boosters = new StorageView(new BoosterTemplate.Reader("res/blockdata/boosters.txt")); this.specialBoosters = new StorageView(new SealedProductTemplate.Reader("res/blockdata/boosters-special.txt")); @@ -157,16 +164,6 @@ public enum FModel { this.loadDynamicGamedata(); - // Loads all cards (using progress bar). - FThreads.assertExecutedByEdt(false); - final CardStorageReader reader = new CardStorageReader(NewConstants.CARD_DATA_DIR, true); - try { - // this fills in our map of card names to Card instances. - CardDb.setup(reader.loadCards()); - - } catch (final Exception ex) { - BugReporter.reportException(ex); - } this.decks = new CardCollections(); this.quest = new QuestController(); diff --git a/src/main/java/forge/quest/BoosterUtils.java b/src/main/java/forge/quest/BoosterUtils.java index 8d243a4f9a8..220df3bc545 100644 --- a/src/main/java/forge/quest/BoosterUtils.java +++ b/src/main/java/forge/quest/BoosterUtils.java @@ -29,11 +29,11 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import forge.Singletons; +import forge.card.CardDb; import forge.card.CardRules; import forge.card.CardRulesPredicates; import forge.card.MagicColor; import forge.item.BoosterPack; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.IPaperCard; import forge.item.InventoryItem; diff --git a/src/main/java/forge/quest/QuestRewardCardChooser.java b/src/main/java/forge/quest/QuestRewardCardChooser.java index 97940fb0554..e4b27626d20 100644 --- a/src/main/java/forge/quest/QuestRewardCardChooser.java +++ b/src/main/java/forge/quest/QuestRewardCardChooser.java @@ -9,7 +9,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import forge.Singletons; -import forge.item.CardDb; +import forge.card.CardDb; import forge.item.PaperCard; import forge.item.InventoryItem; import forge.item.ItemPool; diff --git a/src/main/java/forge/quest/QuestRewardCardFiltered.java b/src/main/java/forge/quest/QuestRewardCardFiltered.java index 529cc84c645..e8ca07cb787 100644 --- a/src/main/java/forge/quest/QuestRewardCardFiltered.java +++ b/src/main/java/forge/quest/QuestRewardCardFiltered.java @@ -7,7 +7,7 @@ import java.util.List; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import forge.item.CardDb; +import forge.card.CardDb; import forge.item.PaperCard; /** diff --git a/src/main/java/forge/quest/QuestUtil.java b/src/main/java/forge/quest/QuestUtil.java index d7e2babd6e5..75cd66a590e 100644 --- a/src/main/java/forge/quest/QuestUtil.java +++ b/src/main/java/forge/quest/QuestUtil.java @@ -21,9 +21,9 @@ import java.util.ArrayList; import java.util.List; import forge.Card; +import forge.card.CardDb; import forge.card.CardEdition; import forge.card.CardRulesReader; -import forge.item.CardDb; import forge.item.PaperToken; import forge.item.IPaperCard; import forge.quest.bazaar.QuestPetController; diff --git a/src/main/java/forge/quest/QuestUtilCards.java b/src/main/java/forge/quest/QuestUtilCards.java index 2485b80855e..733ca922b76 100644 --- a/src/main/java/forge/quest/QuestUtilCards.java +++ b/src/main/java/forge/quest/QuestUtilCards.java @@ -32,15 +32,16 @@ import com.google.common.collect.Lists; import forge.Constant; import forge.Singletons; import forge.card.BoosterGenerator; +import forge.card.CardDb; import forge.card.CardEdition; import forge.card.CardRarity; import forge.card.FormatCollection; +import forge.card.ICardDatabase; import forge.card.SealedProductTemplate; import forge.card.UnOpenedProduct; import forge.deck.Deck; import forge.deck.DeckSection; import forge.item.BoosterPack; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.FatPack; import forge.item.IPaperCard; @@ -89,7 +90,7 @@ public final class QuestUtilCards { * @return the item pool view */ public static ItemPoolView generateBasicLands(final int nBasic, final int nSnow, final GameFormatQuest usedFormat) { - final CardDb db = CardDb.instance(); + final ICardDatabase db = CardDb.instance(); final ItemPool pool = new ItemPool(PaperCard.class); List landCodes = new ArrayList(); diff --git a/src/main/java/forge/quest/QuestUtilUnlockSets.java b/src/main/java/forge/quest/QuestUtilUnlockSets.java index 6aa56d4d22e..9ef4ee0aa7e 100644 --- a/src/main/java/forge/quest/QuestUtilUnlockSets.java +++ b/src/main/java/forge/quest/QuestUtilUnlockSets.java @@ -136,7 +136,7 @@ public class QuestUtilUnlockSets { Collections.sort(excludedSets); // get a number of sets between an excluded and any included set - List> excludedWithDistances = new ArrayList>(); + List> excludedWithDistances = new ArrayList>(); for (CardEdition ex : excludedSets) { switch (ex.getType()) { case CORE: case EXPANSION: case REPRINT: case STARTER: break; @@ -147,9 +147,9 @@ public class QuestUtilUnlockSets { default: throw new RuntimeException("unhandled card edition type: " + ex.getType()); } - int distance = Integer.MAX_VALUE; + long distance = Integer.MAX_VALUE; for (CardEdition in : allowedSets) { - int d = Math.abs(ex.getIndex() - in.getIndex()); + long d = Math.abs(ex.getDate().getTime() - in.getDate().getTime()); if (d < distance) { distance = d; } @@ -158,16 +158,16 @@ public class QuestUtilUnlockSets { } // sort by distance, then by code desc - Collections.sort(excludedWithDistances, new Comparator>() { + Collections.sort(excludedWithDistances, new Comparator>() { @Override - public int compare(ImmutablePair o1, ImmutablePair o2) { - int d1 = o2.right - o1.right; - return d1 != 0 ? d1 : o1.left.getIndex() - o2.left.getIndex(); + public int compare(ImmutablePair o1, ImmutablePair o2) { + long delta = o2.right - o1.right; + return delta < 0 ? -1 : delta == 0 ? 0 : 1; } }); - for (ImmutablePair set : excludedWithDistances) { + for (ImmutablePair set : excludedWithDistances) { options.add(set.left); // System.out.println("Padded with: " + fillers.get(i).getName()); } diff --git a/src/main/java/forge/quest/io/QuestDataIO.java b/src/main/java/forge/quest/io/QuestDataIO.java index 3646ca378dd..a2dd7888d90 100644 --- a/src/main/java/forge/quest/io/QuestDataIO.java +++ b/src/main/java/forge/quest/io/QuestDataIO.java @@ -54,13 +54,13 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import forge.Singletons; +import forge.card.CardDb; import forge.card.CardEdition; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckSection; import forge.error.BugReporter; import forge.item.BoosterPack; -import forge.item.CardDb; import forge.item.PaperCard; import forge.item.FatPack; import forge.item.InventoryItem; diff --git a/src/main/java/forge/util/Aggregates.java b/src/main/java/forge/util/Aggregates.java index f0cf68f576d..ab025c89125 100644 --- a/src/main/java/forge/util/Aggregates.java +++ b/src/main/java/forge/util/Aggregates.java @@ -76,6 +76,8 @@ public class Aggregates { * @return the t */ public static final T random(final Iterable source) { + if( null == source ) + return null; Random rnd = MyRandom.getRandom(); if ( source instanceof List ) { diff --git a/src/test/java/forge/item/DeckHintsTest.java b/src/test/java/forge/item/DeckHintsTest.java index 9929fba4172..cd264a77d1b 100644 --- a/src/test/java/forge/item/DeckHintsTest.java +++ b/src/test/java/forge/item/DeckHintsTest.java @@ -138,7 +138,7 @@ public class DeckHintsTest { crr.parseLine(line); } // Don't care what the actual set or rarity is here. - return PaperCard.build(crr.getCard(), "M11", CardRarity.Common, 0); + return new PaperCard(crr.getCard(), "M11", CardRarity.Common, 0); } }