mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
CardDb moved to forge.card package,
CardDb is initialized with list of CardRules and CardEditions. Rules no longer aware of sets they were issued in
This commit is contained in:
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
349
src/main/java/forge/card/CardDb.java
Normal file
349
src/main/java/forge/card/CardDb.java
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<CardRules> rules, Iterable<CardEdition> 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<String, PaperCard> allCardsByName = new TreeMapOfLists<String, PaperCard>(String.CASE_INSENSITIVE_ORDER, CollectionSuppliers.<PaperCard>arrayLists());
|
||||
private final Map<String, PaperCard> uniqueCardsByName = new TreeMap<String, PaperCard>(String.CASE_INSENSITIVE_ORDER);
|
||||
private final Map<String, CardRules> rulesByName;
|
||||
|
||||
private final List<PaperCard> allCards = new ArrayList<PaperCard>();
|
||||
private final List<PaperCard> roAllCards = Collections.unmodifiableList(allCards);
|
||||
private final Collection<PaperCard> roUniqueCards = Collections.unmodifiableCollection(uniqueCardsByName.values());
|
||||
|
||||
// Lambda to get rules for selects from list of printed cards
|
||||
/** The Constant fnGetCardPrintedByForgeCard. */
|
||||
public static final Function<Card, PaperCard> FN_GET_CARD_PRINTED_BY_FORGE_CARD = new Function<Card, PaperCard>() {
|
||||
@Override
|
||||
public PaperCard apply(final Card from) {
|
||||
return CardDb.instance().getCard(from.getName());
|
||||
}
|
||||
};
|
||||
|
||||
private CardDb(Map<String, CardRules> rules, Iterable<CardEdition> 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<String, Collection<PaperCard>> 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<String, String> 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<String, String>(cardName, setName);
|
||||
}
|
||||
}
|
||||
return new ImmutablePair<String, String>(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<String, String> 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<PaperCard> 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<PaperCard> getUniqueCards() {
|
||||
return roUniqueCards;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PaperCard> getAllCards() {
|
||||
return roAllCards;
|
||||
}
|
||||
|
||||
/** Returns a modifiable list of cards matching the given predicate */
|
||||
@Override
|
||||
public List<PaperCard> getAllCards(Predicate<PaperCard> predicate) {
|
||||
return Lists.newArrayList(Iterables.filter(this.roAllCards, predicate));
|
||||
}
|
||||
|
||||
private static class CardSorter{
|
||||
// Here are refs, get them by name
|
||||
public final Map<String, CardRules> regularCards = new TreeMap<String, CardRules>(String.CASE_INSENSITIVE_ORDER);
|
||||
public final Map<String, CardRules> variantsCards = new TreeMap<String, CardRules>(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<CardRules> parser) {
|
||||
for (CardRules cr : parser) {
|
||||
this.addNewCard(cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Predicate<? super PaperCard> wasPrintedInSets(List<String> setCodes) {
|
||||
return new PredicateExistsInSets(setCodes);
|
||||
}
|
||||
|
||||
private class PredicateExistsInSets implements Predicate<PaperCard> {
|
||||
private final List<String> sets;
|
||||
|
||||
public PredicateExistsInSets(final List<String> wantSets) {
|
||||
this.sets = wantSets; // maybe should make a copy here?
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(final PaperCard subject) {
|
||||
Collection<PaperCard> cc = allCardsByName.get(subject.getName());
|
||||
for(PaperCard c : cc) if (sets.contains(c.getEdition())) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<CardEdition> { // 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<CardEdition> { // 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<CardEdition, String> FN_GET_CODE = new Function<CardEdition, String>() {
|
||||
@@ -101,7 +141,7 @@ public final class CardEdition implements Comparable<CardEdition> { // 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<CardEdition> { // immutable
|
||||
|
||||
}
|
||||
|
||||
public static class Reader extends StorageReaderFile<CardEdition> {
|
||||
public Reader(String pathname) {
|
||||
super(pathname, CardEdition.FN_GET_CODE);
|
||||
public static class EditionReader extends StorageReaderFolder<CardEdition> {
|
||||
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<String, List<String>> 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<CardEdition> { // immutable
|
||||
}
|
||||
}
|
||||
|
||||
// if( !code2.equals(code) ) System.out.printf("%s->%s|", code, code);
|
||||
List<CardEdition.CardInSet> processedCards = new ArrayList<CardEdition.CardInSet>();
|
||||
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");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.card;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* CardInSet class.
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, CardInSet> setsPrinted = new TreeMap<String, CardInSet>(String.CASE_INSENSITIVE_ORDER);
|
||||
//private final Map<String, CardInSet> setsPrinted = new TreeMap<String, CardInSet>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
private CardAiHints aiHints;
|
||||
|
||||
private ColorSet colorIdentity = null;
|
||||
|
||||
public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah, Map<String, CardInSet> 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<String, CardInSet> 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<String, CardInSet> 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<String> 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<String> 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;
|
||||
|
||||
@@ -159,17 +159,6 @@ public final class CardRulesPredicates {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Was printed in sets.
|
||||
*
|
||||
* @param setCodes
|
||||
* the set codes
|
||||
* @return the predicate
|
||||
*/
|
||||
public static Predicate<CardRules> wasPrintedInSets(final List<String> setCodes) {
|
||||
return new PredicateExistsInSets(setCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Core type.
|
||||
*
|
||||
@@ -439,22 +428,6 @@ public final class CardRulesPredicates {
|
||||
}
|
||||
}
|
||||
|
||||
private static class PredicateExistsInSets implements Predicate<CardRules> {
|
||||
private final List<String> sets;
|
||||
|
||||
public PredicateExistsInSets(final List<String> 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<CardRules> {
|
||||
private final CardSplitType cst;
|
||||
|
||||
|
||||
@@ -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<String,CardInSet> sets = new TreeMap<String, CardInSet>(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
|
||||
|
||||
@@ -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<CardEdition> {
|
||||
|
||||
private final Map<String, CardEdition> aliasToEdition = new TreeMap<String, CardEdition>();
|
||||
|
||||
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<CardEdition> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sets the by code or throw.
|
||||
* Gets the sets by code or throw.
|
||||
*
|
||||
* @param code
|
||||
* the code
|
||||
|
||||
27
src/main/java/forge/card/ICardDatabase.java
Normal file
27
src/main/java/forge/card/ICardDatabase.java
Normal file
@@ -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<PaperCard> getUniqueCards();
|
||||
List<PaperCard> getAllCards();
|
||||
List<PaperCard> getAllCards(Predicate<PaperCard> predicate);
|
||||
|
||||
Predicate<? super PaperCard> wasPrintedInSets(List<String> allowedSetCodes);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<PaperCard> 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<GameFormat> {
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<CardRules> 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<String, PaperCard> uniqueCards;
|
||||
|
||||
|
||||
// need this to obtain cardReference by name+set+artindex
|
||||
private final Map<String, Map<String, PaperCard[]>> allCardsBySet;
|
||||
// this is the same list in flat storage
|
||||
private final List<PaperCard> allCardsFlat;
|
||||
|
||||
// Lambda to get rules for selects from list of printed cards
|
||||
/** The Constant fnGetCardPrintedByForgeCard. */
|
||||
public static final Function<Card, PaperCard> FN_GET_CARD_PRINTED_BY_FORGE_CARD = new Function<Card, PaperCard>() {
|
||||
@Override
|
||||
public PaperCard apply(final Card from) {
|
||||
return CardDb.instance().getCard(from.getName());
|
||||
}
|
||||
};
|
||||
|
||||
private CardDb(Map<String, PaperCard> uniqueCards, List<PaperCard> cardsFlat, Map<String, Map<String, PaperCard[]>> 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<String, String> 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<String, String>(cardName, setName);
|
||||
}
|
||||
}
|
||||
return new ImmutablePair<String, String>(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<String, String> 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<String, PaperCard[]> 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<String, PaperCard[]> 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<PaperCard> getUniqueCards() {
|
||||
return this.uniqueCards.values();
|
||||
}
|
||||
|
||||
public List<PaperCard> getAllCards() {
|
||||
return this.allCardsFlat;
|
||||
}
|
||||
|
||||
/** Returns a modifiable list of cards matching the given predicate */
|
||||
public List<PaperCard> getAllCards(Predicate<PaperCard> 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<String, String> 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<PaperCard> predicate = IPaperCard.Predicates.name(nameWithSet.left);
|
||||
final Iterable<PaperCard> 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<String, Map<String, PaperCard[]>> allCommonCardsBySet = new TreeMap<String, Map<String, PaperCard[]>>(String.CASE_INSENSITIVE_ORDER);
|
||||
public final Map<String, Map<String, PaperCard[]>> allSpecialCardsBySet = new TreeMap<String, Map<String, PaperCard[]>>(String.CASE_INSENSITIVE_ORDER);
|
||||
// Here are refs, get them by name
|
||||
public final Map<String, PaperCard> uniqueCommonCards = new TreeMap<String, PaperCard>(String.CASE_INSENSITIVE_ORDER);
|
||||
public final Map<String, PaperCard> uniqueSpecialCards = new TreeMap<String, PaperCard>(String.CASE_INSENSITIVE_ORDER);
|
||||
// this is the same list in flat storage
|
||||
public final List<PaperCard> allCommonCardsFlat = new ArrayList<PaperCard>();
|
||||
public final List<PaperCard> allSpecialCardsFlat = new ArrayList<PaperCard>();
|
||||
|
||||
public PaperCard addToLists(final CardRules card, final String cardName, final String set, CardInSet cs) {
|
||||
PaperCard lastAdded = null;
|
||||
|
||||
final Map<String, Map<String, PaperCard[]>> allCardsBySet = card.isTraditional() ? allCommonCardsBySet : allSpecialCardsBySet;
|
||||
// get this set storage, if not found, create it!
|
||||
Map<String, PaperCard[]> setMap = allCardsBySet.get(set);
|
||||
if (null == setMap) {
|
||||
setMap = new TreeMap<String, PaperCard[]>(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<CardRules> parser) {
|
||||
for (CardRules cr : parser) {
|
||||
this.addNewCard(cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@ public final class PaperCard implements Comparable<IPaperCard>, 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<IPaperCard>, InventoryItemFro
|
||||
|
||||
@Override
|
||||
public boolean isFoil() {
|
||||
return this.foiled;
|
||||
return this.foil;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,59 +117,24 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function<PaperCard, Integer> FN_GET_EDITION_INDEX = new Function<PaperCard, Integer>() {
|
||||
@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<IPaperCard>, 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<IPaperCard>, 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;
|
||||
|
||||
@@ -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<BoosterTemplate>(new BoosterTemplate.Reader("res/blockdata/boosters.txt"));
|
||||
this.specialBoosters = new StorageView<SealedProductTemplate>(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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<PaperCard> generateBasicLands(final int nBasic, final int nSnow, final GameFormatQuest usedFormat) {
|
||||
final CardDb db = CardDb.instance();
|
||||
final ICardDatabase db = CardDb.instance();
|
||||
final ItemPool<PaperCard> pool = new ItemPool<PaperCard>(PaperCard.class);
|
||||
|
||||
List<String> landCodes = new ArrayList<String>();
|
||||
|
||||
@@ -136,7 +136,7 @@ public class QuestUtilUnlockSets {
|
||||
Collections.sort(excludedSets);
|
||||
|
||||
// get a number of sets between an excluded and any included set
|
||||
List<ImmutablePair<CardEdition, Integer>> excludedWithDistances = new ArrayList<ImmutablePair<CardEdition, Integer>>();
|
||||
List<ImmutablePair<CardEdition, Long>> excludedWithDistances = new ArrayList<ImmutablePair<CardEdition, Long>>();
|
||||
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<ImmutablePair<CardEdition, Integer>>() {
|
||||
Collections.sort(excludedWithDistances, new Comparator<ImmutablePair<CardEdition, Long>>() {
|
||||
@Override
|
||||
public int compare(ImmutablePair<CardEdition, Integer> o1, ImmutablePair<CardEdition, Integer> o2) {
|
||||
int d1 = o2.right - o1.right;
|
||||
return d1 != 0 ? d1 : o1.left.getIndex() - o2.left.getIndex();
|
||||
public int compare(ImmutablePair<CardEdition, Long> o1, ImmutablePair<CardEdition, Long> o2) {
|
||||
long delta = o2.right - o1.right;
|
||||
return delta < 0 ? -1 : delta == 0 ? 0 : 1;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
for (ImmutablePair<CardEdition, Integer> set : excludedWithDistances) {
|
||||
for (ImmutablePair<CardEdition, Long> set : excludedWithDistances) {
|
||||
options.add(set.left);
|
||||
// System.out.println("Padded with: " + fillers.get(i).getName());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -76,6 +76,8 @@ public class Aggregates {
|
||||
* @return the t
|
||||
*/
|
||||
public static final <T> T random(final Iterable<T> source) {
|
||||
if( null == source )
|
||||
return null;
|
||||
Random rnd = MyRandom.getRandom();
|
||||
if ( source instanceof List<?> )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user