mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Merge branch 'historicformats' into 'master'
Formatting and preparation of historicformats See merge request core-developers/forge!342
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Nate
|
||||
*
|
||||
* 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.util.storage;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class treats every file in the given folder as a source for a named
|
||||
* object. The descendant should implement read method to deserialize a single
|
||||
* item. So that readAll will return a map of Name => Object as read from disk
|
||||
*
|
||||
* @param <T> the generic type
|
||||
*/
|
||||
public abstract class StorageReaderRecursiveFolderWithUserFolder<T> extends StorageReaderBase<T> {
|
||||
/**
|
||||
* @return the directory
|
||||
*/
|
||||
public File getDirectory() {
|
||||
return directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullPath() {
|
||||
return directory.getPath();
|
||||
}
|
||||
|
||||
protected final File directory;
|
||||
protected final File userDirectory;
|
||||
|
||||
/**
|
||||
* Instantiates a new storage reader folder.
|
||||
*
|
||||
* @param itemDir0 the item dir0
|
||||
*/
|
||||
public StorageReaderRecursiveFolderWithUserFolder(final File itemDir0, final File userItemDir0, Function<? super T, String> keySelector0) {
|
||||
super(keySelector0);
|
||||
|
||||
this.directory = itemDir0;
|
||||
this.userDirectory = userItemDir0;
|
||||
|
||||
if (this.directory == null) {
|
||||
throw new IllegalArgumentException("No directory specified");
|
||||
}
|
||||
try {
|
||||
if (this.directory.isFile()) {
|
||||
throw new IOException("Not a directory");
|
||||
} else {
|
||||
this.directory.mkdirs();
|
||||
if (!this.directory.isDirectory()) {
|
||||
throw new IOException("Directory can't be created");
|
||||
}
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
throw new RuntimeException("StorageReaderFolder.ctor() error, " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public final List<String> objectsThatFailedToLoad = new ArrayList<String>();
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.util.IItemReader#readAll()
|
||||
*/
|
||||
@Override
|
||||
public Map<String, T> readAll() {
|
||||
final Map<String, T> result = new TreeMap<String, T>();
|
||||
|
||||
Collection<File> forgeFormats = listFileTree(directory);
|
||||
Collection<File> customFormats = listFileTree(userDirectory);
|
||||
|
||||
forgeFormats.addAll(customFormats);
|
||||
|
||||
final File[] files = forgeFormats.toArray(new File[forgeFormats.size()]);
|
||||
|
||||
for (final File file : files) {
|
||||
try {
|
||||
final T newDeck = this.read(file);
|
||||
if (null == newDeck) {
|
||||
final String msg = "An object stored in " + file.getPath() + " failed to load.\nPlease submit this as a bug with the mentioned file/directory attached.";
|
||||
continue;//skip format completely - perhaps non format file
|
||||
}
|
||||
|
||||
String newKey = keySelector.apply(newDeck);
|
||||
if (result.containsKey(newKey)) {
|
||||
System.err.println("StorageReaderFolder: Overwriting an object with key " + newKey);
|
||||
}
|
||||
result.put(newKey, newDeck);
|
||||
} catch (final NoSuchElementException ex) {
|
||||
final String message = TextUtil.concatWithSpace( file.getName(),"failed to load because ----", ex.getMessage());
|
||||
objectsThatFailedToLoad.add(message);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Collection<File> listFileTree(File dir) {
|
||||
Set<File> fileTree = new HashSet<File>();
|
||||
if(dir==null||dir.listFiles(getFileFilter())==null){
|
||||
return fileTree;
|
||||
}
|
||||
for (File entry : dir.listFiles(getFileFilter())) {
|
||||
if (entry.isFile()) fileTree.add(entry);
|
||||
else fileTree.addAll(listFileTree(entry));
|
||||
}
|
||||
return fileTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the object from file.
|
||||
*
|
||||
* @param file the file
|
||||
* @return the object deserialized by inherited class
|
||||
*/
|
||||
protected abstract T read(File file);
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*
|
||||
* @return FilenameFilter to pick only relevant objects for deserialization
|
||||
*/
|
||||
protected abstract FilenameFilter getFileFilter();
|
||||
|
||||
@Override
|
||||
public String getItemKey(T item) {
|
||||
return keySelector.apply(item);
|
||||
}
|
||||
|
||||
// methods handling nested folders are provided. It's up to consumer whether to use these or not.
|
||||
@Override
|
||||
public Iterable<File> getSubFolders() {
|
||||
File[] list = this.directory.listFiles(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.isDirectory() && !file.isHidden();
|
||||
}
|
||||
});
|
||||
return Arrays.asList(list);
|
||||
}
|
||||
}
|
||||
@@ -34,28 +34,39 @@ import forge.item.PaperCard;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.storage.StorageBase;
|
||||
import forge.util.storage.StorageReaderFolder;
|
||||
import forge.util.storage.StorageReaderRecursiveFolderWithUserFolder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class GameFormat implements Comparable<GameFormat> {
|
||||
private final String name;
|
||||
public enum FormatType {Sanctioned, Casual, Historic, Custom}
|
||||
public enum FormatType {Sanctioned, Casual, Historic, Digital, Custom}
|
||||
public enum FormatSubType {Block, Standard, Extended, Modern, Legacy, Vintage, Commander, Planechase, Videogame, MTGO, Custom}
|
||||
|
||||
// contains allowed sets, when empty allows all sets
|
||||
private FormatType formatType;
|
||||
private FormatSubType formatSubType;
|
||||
|
||||
protected final List<String> allowedSetCodes; // this is mutable to support quest mode set unlocks
|
||||
protected final List<CardRarity> allowedRarities;
|
||||
protected final List<String> bannedCardNames;
|
||||
protected final List<String> restrictedCardNames;
|
||||
protected final List<String> additionalCardNames; // for cards that are legal but not reprinted in any of the allowed Sets
|
||||
protected boolean restrictedLegendary = false;
|
||||
private Date effectiveDate;
|
||||
private final static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private final static String DEFAULTDATE = "1990-01-01";
|
||||
|
||||
protected final transient List<String> allowedSetCodes_ro;
|
||||
protected final transient List<String> bannedCardNames_ro;
|
||||
protected final transient List<String> restrictedCardNames_ro;
|
||||
protected final transient List<String> additionalCardNames_ro;
|
||||
|
||||
protected final transient Predicate<PaperCard> filterRules;
|
||||
protected final transient Predicate<PaperCard> filterPrinted;
|
||||
@@ -63,24 +74,46 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
private final int index;
|
||||
|
||||
public GameFormat(final String fName, final Iterable<String> sets, final List<String> bannedCards) {
|
||||
this(fName, sets, bannedCards, null, null, 0, FormatType.Custom);
|
||||
this(fName, parseDate(DEFAULTDATE), sets, bannedCards, null, false, null, null, 0, FormatType.Custom, FormatSubType.Custom);
|
||||
}
|
||||
|
||||
public static final GameFormat NoFormat = new GameFormat("(none)", null, null, null, null, Integer.MAX_VALUE, FormatType.Custom);
|
||||
public static final GameFormat NoFormat = new GameFormat("(none)", parseDate(DEFAULTDATE) , null, null, null, false
|
||||
, null, null, Integer.MAX_VALUE, FormatType.Custom, FormatSubType.Custom);
|
||||
|
||||
public GameFormat(final String fName, final Iterable<String> sets, final List<String> bannedCards,
|
||||
final List<String> restrictedCards, final List<CardRarity> rarities, int compareIdx, FormatType formatType) {
|
||||
public GameFormat(final String fName, final Date effectiveDate, final Iterable<String> sets, final List<String> bannedCards,
|
||||
final List<String> restrictedCards, Boolean restrictedLegendary, final List<String> additionalCards,
|
||||
final List<CardRarity> rarities, int compareIdx, FormatType formatType, FormatSubType formatSubType) {
|
||||
this.index = compareIdx;
|
||||
this.formatType = formatType;
|
||||
this.formatSubType = formatSubType;
|
||||
this.name = fName;
|
||||
allowedSetCodes = sets == null ? new ArrayList<String>() : Lists.newArrayList(sets);
|
||||
this.effectiveDate = effectiveDate;
|
||||
|
||||
if(sets != null) {
|
||||
Set<String> parsedSets = new HashSet<>();
|
||||
for (String set : sets) {
|
||||
if (StaticData.instance().getEditions().get(set) == null) {
|
||||
System.out.println("Set " + set + " in format " + fName + " does not match any valid editions!");
|
||||
continue;
|
||||
}
|
||||
parsedSets.add(set);
|
||||
|
||||
}
|
||||
allowedSetCodes = Lists.newArrayList(parsedSets);
|
||||
}else{
|
||||
allowedSetCodes = new ArrayList<String>();
|
||||
}
|
||||
|
||||
bannedCardNames = bannedCards == null ? new ArrayList<String>() : Lists.newArrayList(bannedCards);
|
||||
restrictedCardNames = restrictedCards == null ? new ArrayList<String>() : Lists.newArrayList(restrictedCards);
|
||||
allowedRarities = rarities == null ? new ArrayList<CardRarity>() : rarities;
|
||||
this.restrictedLegendary = restrictedLegendary;
|
||||
additionalCardNames = additionalCards == null ? new ArrayList<String>() : Lists.newArrayList(additionalCards);
|
||||
|
||||
this.allowedSetCodes_ro = Collections.unmodifiableList(allowedSetCodes);
|
||||
this.bannedCardNames_ro = Collections.unmodifiableList(bannedCardNames);
|
||||
this.restrictedCardNames_ro = Collections.unmodifiableList(restrictedCardNames);
|
||||
this.additionalCardNames_ro = Collections.unmodifiableList(additionalCardNames);
|
||||
|
||||
this.filterRules = this.buildFilterRules();
|
||||
this.filterPrinted = this.buildFilterPrinted();
|
||||
@@ -99,6 +132,9 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
}
|
||||
p = Predicates.and(p, Predicates.or(crp));
|
||||
}
|
||||
if (!this.additionalCardNames_ro.isEmpty()) {
|
||||
p = Predicates.or(p, IPaperCard.Predicates.names(this.additionalCardNames_ro));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -114,10 +150,26 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
private static Date parseDate(String date) {
|
||||
if( date.length() <= 7 )
|
||||
date = date + "-01";
|
||||
try {
|
||||
return formatter.parse(date);
|
||||
} catch (ParseException e) {
|
||||
return new Date();
|
||||
}
|
||||
}
|
||||
|
||||
public Date getEffectiveDate() { return effectiveDate; }
|
||||
|
||||
public FormatType getFormatType() {
|
||||
return this.formatType;
|
||||
}
|
||||
|
||||
public FormatSubType getFormatSubType() {
|
||||
return this.formatSubType;
|
||||
}
|
||||
|
||||
public List<String> getAllowedSetCodes() {
|
||||
return this.allowedSetCodes_ro;
|
||||
}
|
||||
@@ -129,6 +181,15 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
public List<String> getRestrictedCards() {
|
||||
return restrictedCardNames_ro;
|
||||
}
|
||||
|
||||
public Boolean isRestrictedLegendary() {
|
||||
return restrictedLegendary;
|
||||
}
|
||||
|
||||
public List<String> getAdditionalCards() {
|
||||
return additionalCardNames_ro;
|
||||
}
|
||||
|
||||
public List<CardRarity> getAllowedRarities() {
|
||||
return allowedRarities;
|
||||
}
|
||||
@@ -171,9 +232,11 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
}
|
||||
}
|
||||
|
||||
if(!restrictedCardNames_ro.isEmpty() ) {
|
||||
if(!restrictedCardNames_ro.isEmpty() || restrictedLegendary ) {
|
||||
for (Entry<PaperCard, Integer> poolEntry : allCards) {
|
||||
if( poolEntry.getValue().intValue() > 1 && restrictedCardNames_ro.contains(poolEntry.getKey().getName()))
|
||||
if( poolEntry.getValue().intValue() > 1 && (restrictedCardNames_ro.contains(poolEntry.getKey().getName())
|
||||
|| (poolEntry.getKey().getRules().getType().isLegendary()
|
||||
&& !poolEntry.getKey().getRules().getType().isPlaneswalker() && restrictedLegendary)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -201,36 +264,80 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
if (null == other) {
|
||||
return 1;
|
||||
}
|
||||
return index - other.index;
|
||||
if (other.formatType != formatType){
|
||||
return formatType.compareTo(other.formatType);
|
||||
}else{
|
||||
if (other.formatSubType != formatSubType){
|
||||
return formatSubType.compareTo(other.formatSubType);
|
||||
}
|
||||
}
|
||||
if (formatType.equals(FormatType.Historic)){
|
||||
if(effectiveDate!=other.effectiveDate) {//for matching dates or default dates default to name sorting
|
||||
return other.effectiveDate.compareTo(effectiveDate);
|
||||
}
|
||||
}
|
||||
return name.compareTo(other.name);
|
||||
//return index - other.index;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public static class Reader extends StorageReaderFolder<GameFormat> {
|
||||
public static class Reader extends StorageReaderRecursiveFolderWithUserFolder<GameFormat> {
|
||||
List<GameFormat> naturallyOrdered = new ArrayList<GameFormat>();
|
||||
boolean includeHistoric;
|
||||
private List<String> coreFormats = new ArrayList<>();
|
||||
{
|
||||
coreFormats.add("Standard.txt");
|
||||
coreFormats.add("Modern.txt");
|
||||
coreFormats.add("Legacy.txt");
|
||||
coreFormats.add("Vintage.txt");
|
||||
coreFormats.add("Commander.txt");
|
||||
|
||||
public Reader(File file0) {
|
||||
super(file0, GameFormat.FN_GET_NAME);
|
||||
}
|
||||
|
||||
public Reader(File forgeFormats, File customFormats, boolean includeHistoric) {
|
||||
super(forgeFormats, customFormats, GameFormat.FN_GET_NAME);
|
||||
this.includeHistoric=includeHistoric;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GameFormat read(File file) {
|
||||
if(!includeHistoric && !coreFormats.contains(file.getName())){
|
||||
return null;
|
||||
}
|
||||
final Map<String, List<String>> contents = FileSection.parseSections(FileUtil.readFile(file));
|
||||
List<String> sets = null; // default: all sets allowed
|
||||
List<String> bannedCards = null; // default: nothing banned
|
||||
List<String> restrictedCards = null; // default: nothing restricted
|
||||
Boolean restrictedLegendary = false;
|
||||
List<String> additionalCards = null; // default: nothing additional
|
||||
List<CardRarity> rarities = null;
|
||||
FileSection section = FileSection.parse(contents.get("format"), ":");
|
||||
List<String> formatStrings = contents.get("format");
|
||||
if (formatStrings == null){
|
||||
return null;
|
||||
}
|
||||
FileSection section = FileSection.parse(formatStrings, ":");
|
||||
String title = section.get("name");
|
||||
FormatType formatType;
|
||||
try {
|
||||
formatType = FormatType.valueOf(section.get("type"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
formatType = FormatType.Custom;
|
||||
}
|
||||
FormatSubType formatsubType;
|
||||
try {
|
||||
formatsubType = FormatSubType.valueOf(section.get("subtype"));
|
||||
} catch (Exception e) {
|
||||
formatsubType = FormatSubType.Custom;
|
||||
}
|
||||
Integer idx = section.getInt("order");
|
||||
String dateStr = section.get("effective");
|
||||
if (dateStr == null){
|
||||
dateStr = DEFAULTDATE;
|
||||
}
|
||||
Date date = parseDate(dateStr);
|
||||
String strSets = section.get("sets");
|
||||
if ( null != strSets ) {
|
||||
sets = Arrays.asList(strSets.split(", "));
|
||||
@@ -245,6 +352,16 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
restrictedCards = Arrays.asList(strCars.split("; "));
|
||||
}
|
||||
|
||||
Boolean strRestrictedLegendary = section.getBoolean("restrictedlegendary");
|
||||
if ( strRestrictedLegendary != null ) {
|
||||
restrictedLegendary = strRestrictedLegendary;
|
||||
}
|
||||
|
||||
strCars = section.get("additional");
|
||||
if ( strCars != null ) {
|
||||
additionalCards = Arrays.asList(strCars.split("; "));
|
||||
}
|
||||
|
||||
strCars = section.get("rarities");
|
||||
if ( strCars != null ) {
|
||||
CardRarity cr;
|
||||
@@ -257,7 +374,7 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
}
|
||||
}
|
||||
|
||||
GameFormat result = new GameFormat(title, sets, bannedCards, restrictedCards, rarities, idx, formatType);
|
||||
GameFormat result = new GameFormat(title, date, sets, bannedCards, restrictedCards, restrictedLegendary, additionalCards, rarities, idx, formatType,formatsubType);
|
||||
naturallyOrdered.add(result);
|
||||
return result;
|
||||
}
|
||||
@@ -270,24 +387,31 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
public static final FilenameFilter TXT_FILE_FILTER = new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(final File dir, final String name) {
|
||||
return name.endsWith(".txt");
|
||||
return name.endsWith(".txt") || dir.isDirectory();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class Collection extends StorageBase<GameFormat> {
|
||||
private List<GameFormat> naturallyOrdered;
|
||||
private List<GameFormat> reverseDateOrdered;
|
||||
|
||||
public Collection(GameFormat.Reader reader) {
|
||||
super("Format collections", reader);
|
||||
naturallyOrdered = reader.naturallyOrdered;
|
||||
reverseDateOrdered = new ArrayList<>(naturallyOrdered);
|
||||
Collections.sort(naturallyOrdered);
|
||||
Collections.sort(reverseDateOrdered, new InverseDateComparator());
|
||||
}
|
||||
|
||||
public Iterable<GameFormat> getOrderedList() {
|
||||
return naturallyOrdered;
|
||||
}
|
||||
|
||||
public Iterable<GameFormat> getReverseDateOrderedList() {
|
||||
return reverseDateOrdered;
|
||||
}
|
||||
|
||||
public Iterable<GameFormat> getSanctionedList() {
|
||||
List<GameFormat> coreList = new ArrayList<>();
|
||||
for(GameFormat format: naturallyOrdered){
|
||||
@@ -298,6 +422,41 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
return coreList;
|
||||
}
|
||||
|
||||
public Iterable<GameFormat> getFilterList() {
|
||||
List<GameFormat> coreList = new ArrayList<>();
|
||||
for(GameFormat format: naturallyOrdered){
|
||||
if(!format.getFormatType().equals(FormatType.Historic)
|
||||
&&!format.getFormatType().equals(FormatType.Digital)){
|
||||
coreList.add(format);
|
||||
}
|
||||
}
|
||||
return coreList;
|
||||
}
|
||||
|
||||
public Iterable<GameFormat> getHistoricList() {
|
||||
List<GameFormat> coreList = new ArrayList<>();
|
||||
for(GameFormat format: naturallyOrdered){
|
||||
if(format.getFormatType().equals(FormatType.Historic)){
|
||||
coreList.add(format);
|
||||
}
|
||||
}
|
||||
return coreList;
|
||||
}
|
||||
|
||||
public Map<String, List<GameFormat>> getHistoricMap() {
|
||||
Map<String, List<GameFormat>> coreList = new HashMap<>();
|
||||
for(GameFormat format: naturallyOrdered){
|
||||
if(format.getFormatType().equals(FormatType.Historic)){
|
||||
String alpha = format.getName().substring(0,1);
|
||||
if(!coreList.containsKey(alpha)){
|
||||
coreList.put(alpha,new ArrayList<>());
|
||||
}
|
||||
coreList.get(alpha).add(format);
|
||||
}
|
||||
}
|
||||
return coreList;
|
||||
}
|
||||
|
||||
public GameFormat getStandard() {
|
||||
return this.map.get("Standard");
|
||||
}
|
||||
@@ -315,7 +474,7 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
}
|
||||
|
||||
public GameFormat getFormatOfDeck(Deck deck) {
|
||||
for(GameFormat gf : naturallyOrdered) {
|
||||
for(GameFormat gf : reverseDateOrdered) {
|
||||
if ( gf.isDeckLegal(deck) )
|
||||
return gf;
|
||||
}
|
||||
@@ -336,11 +495,26 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
}
|
||||
|
||||
public Set<GameFormat> getAllFormatsOfDeck(Deck deck) {
|
||||
return getAllFormatsOfDeck(deck, false);
|
||||
}
|
||||
|
||||
public Set<GameFormat> getAllFormatsOfDeck(Deck deck, Boolean exhaustive) {
|
||||
SortedSet<GameFormat> result = new TreeSet<GameFormat>();
|
||||
Set<FormatSubType> coveredTypes = new HashSet<>();
|
||||
CardPool allCards = deck.getAllCardsInASinglePool();
|
||||
for(GameFormat gf : naturallyOrdered) {
|
||||
for(GameFormat gf : reverseDateOrdered) {
|
||||
if (gf.getFormatType().equals(FormatType.Digital) && !exhaustive){
|
||||
//exclude Digital formats from lists for now
|
||||
continue;
|
||||
}
|
||||
if (gf.getFormatType().equals(FormatType.Historic) && coveredTypes.contains(gf.getFormatSubType())
|
||||
&& !exhaustive){
|
||||
//exclude duplicate formats - only keep first of e.g. Standard historical
|
||||
continue;
|
||||
}
|
||||
if (gf.isPoolLegal(allCards)) {
|
||||
result.add(gf);
|
||||
coveredTypes.add(gf.getFormatSubType());
|
||||
}
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
@@ -355,6 +529,27 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
}
|
||||
}
|
||||
|
||||
public static class InverseDateComparator implements Comparator<GameFormat> {
|
||||
public int compare(GameFormat gf1, GameFormat gf2){
|
||||
if ((null == gf1) || (null == gf2)) {
|
||||
return 1;
|
||||
}
|
||||
if (gf2.formatType != gf1.formatType){
|
||||
return gf1.formatType.compareTo(gf2.formatType);
|
||||
}else{
|
||||
if (gf2.formatSubType != gf1.formatSubType){
|
||||
return gf1.formatSubType.compareTo(gf2.formatSubType);
|
||||
}
|
||||
}
|
||||
if (gf1.formatType.equals(FormatType.Historic)){
|
||||
if(gf1.effectiveDate!=gf2.effectiveDate) {//for matching dates or default dates default to name sorting
|
||||
return gf1.effectiveDate.compareTo(gf2.effectiveDate);
|
||||
}
|
||||
}
|
||||
return gf1.name.compareTo(gf2.name);
|
||||
}
|
||||
}
|
||||
|
||||
public final Predicate<CardEdition> editionLegalPredicate = new Predicate<CardEdition>() {
|
||||
@Override
|
||||
public boolean apply(final CardEdition subject) {
|
||||
|
||||
@@ -7,10 +7,13 @@ import forge.itemmanager.filters.*;
|
||||
import forge.model.FModel;
|
||||
import forge.quest.QuestWorld;
|
||||
import forge.quest.data.QuestPreferences;
|
||||
import forge.screens.home.quest.DialogChooseFormats;
|
||||
import forge.screens.home.quest.DialogChooseSets;
|
||||
import forge.screens.match.controllers.CDetailPicture;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
@@ -82,7 +85,7 @@ public class CardManager extends ItemManager<PaperCard> {
|
||||
GuiUtils.addSeparator(menu); //separate from current search item
|
||||
|
||||
JMenu fmt = GuiUtils.createMenu("Format");
|
||||
for (final GameFormat f : FModel.getFormats().getOrderedList()) {
|
||||
for (final GameFormat f : FModel.getFormats().getFilterList()) {
|
||||
GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -92,6 +95,27 @@ public class CardManager extends ItemManager<PaperCard> {
|
||||
}
|
||||
menu.add(fmt);
|
||||
|
||||
GuiUtils.addMenuItem(menu, "Formats...", null, new Runnable() {
|
||||
@Override public void run() {
|
||||
final CardSetFilter existingFilter = itemManager.getFilter(CardSetFilter.class);
|
||||
if (existingFilter != null) {
|
||||
existingFilter.edit();
|
||||
} else {
|
||||
final DialogChooseFormats dialog = new DialogChooseFormats();
|
||||
dialog.setOkCallback(new Runnable() {
|
||||
@Override public void run() {
|
||||
final List<GameFormat> formats = dialog.getSelectedFormats();
|
||||
if (!formats.isEmpty()) {
|
||||
for(GameFormat format: formats) {
|
||||
itemManager.addFilter(new CardFormatFilter(itemManager, format));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
GuiUtils.addMenuItem(menu, "Sets...", null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
@@ -4,18 +4,15 @@ import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import forge.screens.home.quest.DialogChooseFormats;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.Singletons;
|
||||
@@ -176,7 +173,7 @@ public final class DeckManager extends ItemManager<DeckProxy> implements IHasGam
|
||||
menu.add(folder);
|
||||
|
||||
final JMenu fmt = GuiUtils.createMenu("Format");
|
||||
for (final GameFormat f : FModel.getFormats().getOrderedList()) {
|
||||
for (final GameFormat f : FModel.getFormats().getFilterList()) {
|
||||
GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -186,6 +183,29 @@ public final class DeckManager extends ItemManager<DeckProxy> implements IHasGam
|
||||
}
|
||||
menu.add(fmt);
|
||||
|
||||
|
||||
GuiUtils.addMenuItem(menu, "Formats...", null, new Runnable() {
|
||||
@Override public void run() {
|
||||
final DeckFormatFilter existingFilter = getFilter(DeckFormatFilter.class);
|
||||
if (existingFilter != null) {
|
||||
existingFilter.edit();
|
||||
} else {
|
||||
final DialogChooseFormats dialog = new DialogChooseFormats();
|
||||
dialog.setOkCallback(new Runnable() {
|
||||
@Override public void run() {
|
||||
final List<GameFormat> formats = dialog.getSelectedFormats();
|
||||
if (!formats.isEmpty()) {
|
||||
for(GameFormat format: formats) {
|
||||
addFilter(new DeckFormatFilter(DeckManager.this, format));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
GuiUtils.addMenuItem(menu, "Sets...", null, new Runnable() {
|
||||
@Override public void run() {
|
||||
final DeckSetFilter existingFilter = getFilter(DeckSetFilter.class);
|
||||
|
||||
@@ -6,6 +6,7 @@ import forge.game.GameFormat;
|
||||
import forge.deck.DeckProxy;
|
||||
import forge.itemmanager.ItemManager;
|
||||
import forge.itemmanager.SFilterUtil;
|
||||
import forge.screens.home.quest.DialogChooseFormats;
|
||||
|
||||
|
||||
public class DeckFormatFilter extends FormatFilter<DeckProxy> {
|
||||
@@ -27,4 +28,16 @@ public class DeckFormatFilter extends FormatFilter<DeckProxy> {
|
||||
protected final Predicate<DeckProxy> buildPredicate() {
|
||||
return DeckProxy.createPredicate(SFilterUtil.buildFormatFilter(this.formats, this.allowReprints));
|
||||
}
|
||||
|
||||
public void edit() {
|
||||
final DialogChooseFormats dialog = new DialogChooseFormats(this.formats);
|
||||
dialog.setOkCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
allowReprints = dialog.getWantReprints();
|
||||
formats.clear();
|
||||
formats.addAll(dialog.getSelectedFormats());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ public abstract class FormatFilter<T extends InventoryItem> extends ListLabelFil
|
||||
protected String getTooltip() {
|
||||
Set<String> sets = new HashSet<String>();
|
||||
Set<String> bannedCards = new HashSet<String>();
|
||||
Set<String> additionalCards = new HashSet<>();
|
||||
|
||||
for (GameFormat format : this.formats) {
|
||||
List<String> formatSets = format.getAllowedSetCodes();
|
||||
@@ -37,6 +38,10 @@ public abstract class FormatFilter<T extends InventoryItem> extends ListLabelFil
|
||||
if (formatBannedCards != null) {
|
||||
bannedCards.addAll(formatBannedCards);
|
||||
}
|
||||
List<String> formatAdditionalCards = format.getAdditionalCards();
|
||||
if (formatAdditionalCards != null) {
|
||||
additionalCards.addAll(formatAdditionalCards);
|
||||
}
|
||||
}
|
||||
|
||||
//use HTML tooltips so we can insert line breaks
|
||||
@@ -58,7 +63,9 @@ public abstract class FormatFilter<T extends InventoryItem> extends ListLabelFil
|
||||
}
|
||||
|
||||
CardEdition edition = editions.get(code);
|
||||
tooltip.append(" ").append(edition.getName()).append(" (").append(code).append("),");
|
||||
if(edition!=null) {
|
||||
tooltip.append(" ").append(edition.getName()).append(" (").append(code).append("),");
|
||||
}
|
||||
lineLen = tooltip.length() - lastLen;
|
||||
}
|
||||
|
||||
@@ -90,6 +97,27 @@ public abstract class FormatFilter<T extends InventoryItem> extends ListLabelFil
|
||||
// chop off last semicolon
|
||||
tooltip.delete(tooltip.length() - 1, tooltip.length());
|
||||
}
|
||||
|
||||
if (!additionalCards.isEmpty()) {
|
||||
tooltip.append("<br><br>Additional:");
|
||||
lastLen += lineLen;
|
||||
lineLen = 0;
|
||||
|
||||
for (String cardName : additionalCards) {
|
||||
// don't let a single line get too long
|
||||
if (50 < lineLen) {
|
||||
tooltip.append("<br>");
|
||||
lastLen += lineLen;
|
||||
lineLen = 0;
|
||||
}
|
||||
|
||||
tooltip.append(" ").append(cardName).append(";");
|
||||
lineLen = tooltip.length() - lastLen;
|
||||
}
|
||||
|
||||
// chop off last semicolon
|
||||
tooltip.delete(tooltip.length() - 1, tooltip.length());
|
||||
}
|
||||
tooltip.append("</html>");
|
||||
return tooltip.toString();
|
||||
}
|
||||
|
||||
@@ -90,6 +90,24 @@ public enum CSubmenuQuestData implements ICDoc {
|
||||
}
|
||||
});
|
||||
|
||||
view.getBtnSelectFormat().setCommand(new UiCommand() {
|
||||
@Override
|
||||
public void run() {
|
||||
final DialogChooseFormats dialog = new DialogChooseFormats();
|
||||
dialog.setOkCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
customFormatCodes.clear();
|
||||
Set<String> sets = new HashSet<String>();
|
||||
for(GameFormat format:dialog.getSelectedFormats()){
|
||||
sets.addAll(format.getAllowedSetCodes());
|
||||
}
|
||||
customFormatCodes.addAll(sets);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
view.getBtnPrizeCustomFormat().setCommand(new UiCommand() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -104,6 +122,24 @@ public enum CSubmenuQuestData implements ICDoc {
|
||||
}
|
||||
});
|
||||
|
||||
view.getBtnPrizeSelectFormat().setCommand(new UiCommand() {
|
||||
@Override
|
||||
public void run() {
|
||||
final DialogChooseFormats dialog = new DialogChooseFormats();
|
||||
dialog.setOkCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
customPrizeFormatCodes.clear();
|
||||
Set<String> sets = new HashSet<String>();
|
||||
for(GameFormat format:dialog.getSelectedFormats()){
|
||||
sets.addAll(format.getAllowedSetCodes());
|
||||
}
|
||||
customPrizeFormatCodes.addAll(sets);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
view.getBtnPreferredColors().setCommand(new UiCommand() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -197,10 +233,11 @@ public enum CSubmenuQuestData implements ICDoc {
|
||||
|
||||
if (worldFormat == null) {
|
||||
switch(view.getStartingPoolType()) {
|
||||
case Rotating:
|
||||
case Sanctioned:
|
||||
fmtStartPool = view.getRotatingFormat();
|
||||
break;
|
||||
|
||||
case Casual:
|
||||
case CustomFormat:
|
||||
if (customFormatCodes.isEmpty()) {
|
||||
if (!FOptionPane.showConfirmDialog("You have defined a custom format that doesn't contain any sets.\nThis will start a game without restriction.\n\nContinue?")) {
|
||||
@@ -257,6 +294,7 @@ public enum CSubmenuQuestData implements ICDoc {
|
||||
case Complete:
|
||||
fmtPrizes = null;
|
||||
break;
|
||||
case Casual:
|
||||
case CustomFormat:
|
||||
if (customPrizeFormatCodes.isEmpty()) {
|
||||
if (!FOptionPane.showConfirmDialog("You have defined custom format as containing no sets.\nThis will choose all editions without restriction as prizes.\n\nContinue?")) {
|
||||
@@ -265,7 +303,7 @@ public enum CSubmenuQuestData implements ICDoc {
|
||||
}
|
||||
fmtPrizes = customPrizeFormatCodes.isEmpty() ? null : new GameFormat("Custom Prizes", customPrizeFormatCodes, null); // chosen sets and no banned cards
|
||||
break;
|
||||
case Rotating:
|
||||
case Sanctioned:
|
||||
fmtPrizes = view.getPrizedRotatingFormat();
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
package forge.screens.home.quest;
|
||||
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.card.CardEdition;
|
||||
import forge.game.GameFormat;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.model.FModel;
|
||||
import forge.toolbox.*;
|
||||
import forge.util.TextUtil;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.*;
|
||||
|
||||
public class DialogChooseFormats {
|
||||
|
||||
private List<GameFormat> selectedFormats = new ArrayList<>() ;
|
||||
private boolean wantReprints = true;
|
||||
private Runnable okCallback;
|
||||
|
||||
private final List<FCheckBox> choices = new ArrayList<>();
|
||||
private final FCheckBox cbWantReprints = new FCheckBox("Allow compatible reprints from other sets");
|
||||
|
||||
public DialogChooseFormats(){
|
||||
this(null);
|
||||
}
|
||||
|
||||
public DialogChooseFormats(Set<GameFormat> preselectedFormats) {
|
||||
|
||||
List<FCheckBox> sanctioned = new ArrayList<>();
|
||||
List<FCheckBox> casual = new ArrayList<>();
|
||||
List<FCheckBox> historic = new ArrayList<>();
|
||||
|
||||
for (GameFormat format : FModel.getFormats().getOrderedList()){
|
||||
FCheckBox box = new FCheckBox(format.getName());
|
||||
box.setName(format.getName());
|
||||
switch (format.getFormatType()){
|
||||
case Sanctioned:
|
||||
sanctioned.add(box);
|
||||
break;
|
||||
case Historic:
|
||||
historic.add(box);
|
||||
break;
|
||||
case Custom:
|
||||
case Casual:
|
||||
case Digital:
|
||||
default:
|
||||
casual.add(box);
|
||||
break;
|
||||
|
||||
}
|
||||
box.setSelected(null != preselectedFormats && preselectedFormats.contains(format));
|
||||
}
|
||||
|
||||
FPanel panel = new FPanel(new MigLayout("insets 0, gap 0, center, wrap 3"));
|
||||
panel.setOpaque(false);
|
||||
panel.setBackgroundTexture(FSkin.getIcon(FSkinProp.BG_TEXTURE));
|
||||
|
||||
panel.add(new FLabel.Builder().text("Choose formats").fontSize(18).build(), "center, span, wrap, gaptop 10");
|
||||
|
||||
String constraints = "aligny top";
|
||||
panel.add(makeCheckBoxList(sanctioned, "Sanctioned", true), constraints);
|
||||
panel.add(makeCheckBoxList(casual, "Other", false), constraints);
|
||||
panel.add(makeCheckBoxList(historic, "Historic", false), constraints);
|
||||
|
||||
final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel();
|
||||
overlay.setLayout(new MigLayout("insets 0, gap 0, wrap, ax center, ay center"));
|
||||
|
||||
final Runnable cleanup = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SOverlayUtils.hideOverlay();
|
||||
}
|
||||
};
|
||||
|
||||
FButton btnOk = new FButton("OK");
|
||||
btnOk.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
cleanup.run();
|
||||
handleOk();
|
||||
}
|
||||
});
|
||||
|
||||
FButton btnCancel = new FButton("Cancel");
|
||||
btnCancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
cleanup.run();
|
||||
}
|
||||
});
|
||||
|
||||
JPanel southPanel = new JPanel(new MigLayout("insets 10, gap 20, ax center"));
|
||||
southPanel.setOpaque(false);
|
||||
southPanel.add(cbWantReprints, "center, span, wrap");
|
||||
southPanel.add(btnOk, "center, w 40%, h 20!");
|
||||
southPanel.add(btnCancel, "center, w 40%, h 20!");
|
||||
|
||||
panel.add(southPanel, "dock south, gapBottom 10");
|
||||
|
||||
overlay.add(panel);
|
||||
panel.getRootPane().setDefaultButton(btnOk);
|
||||
SOverlayUtils.showOverlay();
|
||||
|
||||
}
|
||||
|
||||
public void setOkCallback(Runnable onOk) {
|
||||
okCallback = onOk;
|
||||
}
|
||||
|
||||
public List<GameFormat> getSelectedFormats() {
|
||||
return selectedFormats;
|
||||
}
|
||||
|
||||
public boolean getWantReprints() {
|
||||
return wantReprints;
|
||||
}
|
||||
|
||||
private JPanel makeCheckBoxList(List<FCheckBox> formats, String title, boolean focused) {
|
||||
|
||||
choices.addAll(formats);
|
||||
final FCheckBoxList<FCheckBox> cbl = new FCheckBoxList<>(false);
|
||||
cbl.setListData(formats.toArray(new FCheckBox[formats.size()]));
|
||||
cbl.setVisibleRowCount(Math.min(20, formats.size()));
|
||||
|
||||
if (focused) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cbl.requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
JPanel pnl = new JPanel(new MigLayout("center, wrap"));
|
||||
pnl.setOpaque(false);
|
||||
pnl.add(new FLabel.Builder().text(title).build());
|
||||
pnl.add(new FScrollPane(cbl, true));
|
||||
return pnl;
|
||||
|
||||
}
|
||||
|
||||
private void handleOk() {
|
||||
|
||||
for (FCheckBox box : choices) {
|
||||
if (box.isSelected()) {
|
||||
selectedFormats.add(FModel.getFormats().getFormat(box.getName()));
|
||||
}
|
||||
wantReprints = cbWantReprints.isSelected();
|
||||
}
|
||||
|
||||
if (null != okCallback) {
|
||||
okCallback.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -82,6 +82,8 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
private final FComboBoxWrapper<Deck> cbxCustomDeck = new FComboBoxWrapper<>();
|
||||
|
||||
private final FLabel btnDefineCustomFormat = new FLabel.Builder().opaque(true).hoverable(true).text("Define custom format").build();
|
||||
private final FLabel btnSelectFormat = new FLabel.Builder().opaque(true).hoverable(true).text("Select format").build();
|
||||
|
||||
|
||||
private final FCheckBox boxCompleteSet = new FCheckBox("Start with all cards in selected sets");
|
||||
private final FCheckBox boxAllowDuplicates = new FCheckBox("Allow duplicate cards");
|
||||
@@ -91,6 +93,8 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
|
||||
private final FLabel btnPrizeDefineCustomFormat = new FLabel.Builder().opaque(true).hoverable(true).text("Define custom format").build();
|
||||
|
||||
private final FLabel btnPrizeSelectFormat = new FLabel.Builder().opaque(true).hoverable(true).text("Select format").build();
|
||||
|
||||
private final FLabel lblPrizedCards = new FLabel.Builder().text("Prized cards:").build();
|
||||
private final FComboBoxWrapper<Object> cbxPrizedCards = new FComboBoxWrapper<>();
|
||||
|
||||
@@ -116,10 +120,11 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
lblPreconDeck.setVisible(newVal == StartingPoolType.Precon);
|
||||
cbxPreconDeck.setVisible(newVal == StartingPoolType.Precon);
|
||||
|
||||
lblFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
cbxFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
lblFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
cbxFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
|
||||
btnDefineCustomFormat.setVisible(newVal == StartingPoolType.CustomFormat);
|
||||
btnSelectFormat.setVisible(newVal == StartingPoolType.Casual);
|
||||
|
||||
|
||||
final boolean usesDeckList = newVal == StartingPoolType.SealedDeck || newVal == StartingPoolType.DraftDeck || newVal == StartingPoolType.Cube;
|
||||
@@ -152,9 +157,10 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
lblPrizeUnrestricted.setVisible(newVal == StartingPoolType.Complete);
|
||||
cboAllowUnlocks.setVisible(newVal != StartingPoolType.Complete);
|
||||
|
||||
lblPrizeFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
cbxPrizeFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
lblPrizeFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
cbxPrizeFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
btnPrizeDefineCustomFormat.setVisible(newVal == StartingPoolType.CustomFormat);
|
||||
btnPrizeSelectFormat.setVisible(newVal == StartingPoolType.Casual);
|
||||
lblPrizeSameAsStarting.setVisible(newVal == null);
|
||||
}
|
||||
};
|
||||
@@ -200,7 +206,8 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
boxAllowDuplicates.setToolTipText("When your starting pool is generated, duplicates of cards may be included.");
|
||||
|
||||
cbxStartingPool.addItem(StartingPoolType.Complete);
|
||||
cbxStartingPool.addItem(StartingPoolType.Rotating);
|
||||
cbxStartingPool.addItem(StartingPoolType.Sanctioned);
|
||||
cbxStartingPool.addItem(StartingPoolType.Casual);
|
||||
cbxStartingPool.addItem(StartingPoolType.CustomFormat);
|
||||
cbxStartingPool.addItem(StartingPoolType.Precon);
|
||||
cbxStartingPool.addItem(StartingPoolType.DraftDeck);
|
||||
@@ -214,11 +221,12 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
|
||||
cbxPrizedCards.addItem("Same as starting pool");
|
||||
cbxPrizedCards.addItem(StartingPoolType.Complete);
|
||||
cbxPrizedCards.addItem(StartingPoolType.Rotating);
|
||||
cbxPrizedCards.addItem(StartingPoolType.Sanctioned);
|
||||
cbxPrizedCards.addItem(StartingPoolType.Casual);
|
||||
cbxPrizedCards.addItem(StartingPoolType.CustomFormat);
|
||||
cbxPrizedCards.addActionListener(alPrizesPool);
|
||||
|
||||
for (final GameFormat gf : FModel.getFormats().getOrderedList()) {
|
||||
for (final GameFormat gf : FModel.getFormats().getSanctionedList()) {
|
||||
cbxFormat.addItem(gf);
|
||||
cbxPrizeFormat.addItem(gf);
|
||||
}
|
||||
@@ -311,6 +319,7 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
cbxFormat.addTo(pnlRestrictions, constraints + cboWidthStart + " cell 1 1");
|
||||
|
||||
pnlRestrictions.add(btnDefineCustomFormat, btnStartingCustomFormatWidth + constraints + hidemode + " cell 1 1");
|
||||
pnlRestrictions.add(btnSelectFormat, btnStartingCustomFormatWidth + constraints + hidemode + " cell 1 1");
|
||||
|
||||
pnlRestrictions.add(boxAllowDuplicates, "h 15px!, cell 1 2");
|
||||
pnlRestrictions.add(boxCompleteSet, "h 15px!, cell 1 3");
|
||||
@@ -325,6 +334,7 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
pnlRestrictions.add(lblPrizeFormat, constraints + hidemode + "cell 0 6");
|
||||
cbxPrizeFormat.addTo(pnlRestrictions, constraints + cboWidthStart + "cell 1 6"); // , skip 1
|
||||
pnlRestrictions.add(btnPrizeDefineCustomFormat, btnStartingCustomFormatWidth + constraints + hidemode + "cell 1 6");
|
||||
pnlRestrictions.add(btnPrizeSelectFormat, btnStartingCustomFormatWidth + constraints + hidemode + "cell 1 6");
|
||||
pnlRestrictions.add(lblPrizeSameAsStarting, constraints + hidemode + "cell 1 6");
|
||||
pnlRestrictions.add(lblPrizeUnrestricted, constraints + hidemode + "cell 1 6");
|
||||
|
||||
@@ -498,9 +508,23 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
return cbxPrizeFormat.getSelectedItem();
|
||||
}
|
||||
|
||||
public GameFormat getCasualFormat() {
|
||||
return cbxFormat.getSelectedItem();
|
||||
}
|
||||
|
||||
public GameFormat getPrizedCasualFormat() {
|
||||
return cbxPrizeFormat.getSelectedItem();
|
||||
}
|
||||
|
||||
public FLabel getBtnCustomFormat() {
|
||||
return btnDefineCustomFormat;
|
||||
}
|
||||
public FLabel getBtnSelectFormat() {
|
||||
return btnSelectFormat;
|
||||
}
|
||||
public FLabel getBtnPrizeSelectFormat() {
|
||||
return btnPrizeSelectFormat;
|
||||
}
|
||||
public FLabel getBtnPrizeCustomFormat() {
|
||||
return btnPrizeDefineCustomFormat;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,9 @@ public enum CSubmenuPreferences implements ICDoc {
|
||||
|
||||
lstControls.add(Pair.of(view.getCbLoadCardsLazily(), FPref.LOAD_CARD_SCRIPTS_LAZILY));
|
||||
|
||||
lstControls.add(Pair.of(view.getCbLoadHistoricFormats(), FPref.LOAD_HISTORIC_FORMATS));
|
||||
|
||||
|
||||
for(final Pair<JCheckBox, FPref> kv : lstControls) {
|
||||
kv.getKey().addItemListener(new ItemListener() {
|
||||
@Override
|
||||
|
||||
@@ -65,6 +65,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
||||
private final JCheckBox cbManaLostPrompt = new OptionsCheckBox("Prompt Mana Pool Emptying");
|
||||
private final JCheckBox cbDevMode = new OptionsCheckBox("Developer Mode");
|
||||
private final JCheckBox cbLoadCardsLazily = new OptionsCheckBox("Load Card Scripts Lazily");
|
||||
private final JCheckBox cbLoadHistoricFormats = new OptionsCheckBox("Load Historic Formats");
|
||||
private final JCheckBox cbWorkshopSyntax = new OptionsCheckBox("Workshop Syntax Checker");
|
||||
private final JCheckBox cbEnforceDeckLegality = new OptionsCheckBox("Deck Conformance");
|
||||
private final JCheckBox cbImageFetcher = new OptionsCheckBox("Automatically Download Missing Card Art");
|
||||
@@ -239,6 +240,9 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
||||
pnlPrefs.add(cbLoadCardsLazily, titleConstraints);
|
||||
pnlPrefs.add(new NoteLabel("If turned on, Forge will load card scripts as they're needed instead of at start up. (Warning: Experimental)"), descriptionConstraints);
|
||||
|
||||
pnlPrefs.add(cbLoadHistoricFormats, titleConstraints);
|
||||
pnlPrefs.add(new NoteLabel("If turned on, Forge will load all historic format definitions, this may take slightly longer to load at startup."), descriptionConstraints);
|
||||
|
||||
// Graphic Options
|
||||
pnlPrefs.add(new SectionLabel("Graphic Options"), sectionConstraints + ", gaptop 2%");
|
||||
|
||||
@@ -586,6 +590,11 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
||||
return cbLoadCardsLazily;
|
||||
}
|
||||
|
||||
/** @return {@link javax.swing.JCheckBox} */
|
||||
public JCheckBox getCbLoadHistoricFormats() {
|
||||
return cbLoadHistoricFormats;
|
||||
}
|
||||
|
||||
public JCheckBox getCbWorkshopSyntax() {
|
||||
return cbWorkshopSyntax;
|
||||
}
|
||||
|
||||
@@ -22,11 +22,7 @@ import forge.util.Callback;
|
||||
import forge.util.TextUtil;
|
||||
import forge.util.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
||||
|
||||
@@ -42,9 +38,10 @@ public abstract class FormatFilter<T extends InventoryItem> extends ItemFilter<T
|
||||
|
||||
cbxFormats.setFont(FSkinFont.get(12));
|
||||
cbxFormats.addItem("All Sets/Formats");
|
||||
for (GameFormat format : FModel.getFormats().getOrderedList()) {
|
||||
for (GameFormat format : FModel.getFormats().getFilterList()) {
|
||||
cbxFormats.addItem(format);
|
||||
}
|
||||
cbxFormats.addItem("Other Formats...");
|
||||
cbxFormats.addItem("Choose Sets...");
|
||||
selectedFormat = cbxFormats.getText();
|
||||
|
||||
@@ -61,6 +58,21 @@ public abstract class FormatFilter<T extends InventoryItem> extends ItemFilter<T
|
||||
format = null;
|
||||
applyChange();
|
||||
}
|
||||
else if (index == cbxFormats.getItemCount() - 2) {
|
||||
preventHandling = true;
|
||||
cbxFormats.setText(selectedFormat); //restore previous selection by default
|
||||
preventHandling = false;
|
||||
HistoricFormatSelect historicFormatSelect = new HistoricFormatSelect();
|
||||
historicFormatSelect.setOnCloseCallBack(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
format = historicFormatSelect.getSelectedFormat();
|
||||
cbxFormats.setText(format.getName());
|
||||
applyChange();
|
||||
}
|
||||
});
|
||||
Forge.openScreen(historicFormatSelect);
|
||||
}
|
||||
else if (index == cbxFormats.getItemCount() - 1) {
|
||||
preventHandling = true;
|
||||
cbxFormats.setText(selectedFormat); //restore previous selection by default
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package forge.itemmanager.filters;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.game.GameFormat;
|
||||
import forge.model.FModel;
|
||||
import forge.screens.FScreen;
|
||||
import forge.screens.settings.SettingsScreen;
|
||||
import forge.toolbox.FGroupList;
|
||||
import forge.toolbox.FList;
|
||||
import forge.util.Callback;
|
||||
import forge.util.Utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by maustin on 16/04/2018.
|
||||
*/
|
||||
public class HistoricFormatSelect extends FScreen {
|
||||
|
||||
private GameFormat selectedFormat;
|
||||
private final FGroupList<GameFormat> lstFormats = add(new FGroupList<GameFormat>());
|
||||
private final Set<GameFormat.FormatSubType> historicSubTypes = new HashSet<>(Arrays.asList(GameFormat.FormatSubType.Block,
|
||||
GameFormat.FormatSubType.Standard,GameFormat.FormatSubType.Extended,GameFormat.FormatSubType.Modern,
|
||||
GameFormat.FormatSubType.Legacy, GameFormat.FormatSubType.Vintage));
|
||||
|
||||
private Runnable onCloseCallBack;
|
||||
|
||||
public HistoricFormatSelect() {
|
||||
super("Choose Format");
|
||||
for (GameFormat.FormatType group:GameFormat.FormatType.values()){
|
||||
if (group == GameFormat.FormatType.Historic){
|
||||
for (GameFormat.FormatSubType subgroup:GameFormat.FormatSubType.values()){
|
||||
if (historicSubTypes.contains(subgroup)){
|
||||
lstFormats.addGroup(group.name() + "-" + subgroup.name());
|
||||
}
|
||||
}
|
||||
}else {
|
||||
lstFormats.addGroup(group.name());
|
||||
}
|
||||
}
|
||||
for (GameFormat format: FModel.getFormats().getOrderedList()){
|
||||
switch(format.getFormatType()){
|
||||
case Sanctioned:
|
||||
lstFormats.addItem(format, 0);
|
||||
break;
|
||||
case Casual:
|
||||
lstFormats.addItem(format, 1);
|
||||
break;
|
||||
case Historic:
|
||||
switch (format.getFormatSubType()){
|
||||
case Block:
|
||||
lstFormats.addItem(format, 2);
|
||||
break;
|
||||
case Standard:
|
||||
lstFormats.addItem(format, 3);
|
||||
break;
|
||||
case Extended:
|
||||
lstFormats.addItem(format, 4);
|
||||
break;
|
||||
case Modern:
|
||||
lstFormats.addItem(format, 5);
|
||||
break;
|
||||
case Legacy:
|
||||
lstFormats.addItem(format, 6);
|
||||
break;
|
||||
case Vintage:
|
||||
lstFormats.addItem(format, 7);
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case Digital:
|
||||
lstFormats.addItem(format, 8);
|
||||
break;
|
||||
case Custom:
|
||||
lstFormats.addItem(format, 9);
|
||||
}
|
||||
}
|
||||
lstFormats.setListItemRenderer(new FormatRenderer());
|
||||
}
|
||||
|
||||
public GameFormat getSelectedFormat() {
|
||||
return selectedFormat;
|
||||
}
|
||||
|
||||
public void setOnCloseCallBack(Runnable onCloseCallBack) {
|
||||
this.onCloseCallBack = onCloseCallBack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(Callback<Boolean> canCloseCallback) {
|
||||
if (selectedFormat != null) {
|
||||
if (onCloseCallBack != null) {
|
||||
onCloseCallBack.run();
|
||||
}
|
||||
}
|
||||
super.onClose(canCloseCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLayout(float startY, float width, float height) {
|
||||
lstFormats.setBounds(0, startY, width, height - startY);
|
||||
}
|
||||
|
||||
private class FormatRenderer extends FList.ListItemRenderer<GameFormat>{
|
||||
@Override
|
||||
public float getItemHeight() {
|
||||
return Utils.AVG_FINGER_HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tap(Integer index, GameFormat value, float x, float y, int count) {
|
||||
selectedFormat=value;
|
||||
Forge.back();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Graphics g, Integer index, GameFormat value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) {
|
||||
float offset = SettingsScreen.getInsets(w) - FList.PADDING; //increase padding for settings items
|
||||
x += offset;
|
||||
y += offset;
|
||||
w -= 2 * offset;
|
||||
h -= 2 * offset;
|
||||
|
||||
float textHeight = h;
|
||||
h *= 0.66f;
|
||||
|
||||
g.drawText(value.toString(), font, foreColor, x, y, w - h - FList.PADDING, textHeight, false, BitmapFont.HAlignment.LEFT, true);
|
||||
|
||||
x += w - h;
|
||||
y += (textHeight - h) / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package forge.screens.quest;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.Forge;
|
||||
import forge.UiCommand;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.assets.FSkinImage;
|
||||
@@ -13,6 +14,7 @@ import forge.deck.DeckSection;
|
||||
import forge.game.GameFormat;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.itemmanager.filters.HistoricFormatSelect;
|
||||
import forge.model.CardCollections;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
@@ -123,13 +125,13 @@ public class NewQuestScreen extends FScreen {
|
||||
private final FLabel lblPreconDeck = scroller.add(new FLabel.Builder().text("Starter/Event deck:").build());
|
||||
private final FComboBox<String> cbxPreconDeck = scroller.add(new FComboBox<String>());
|
||||
|
||||
private final FLabel lblFormat = scroller.add(new FLabel.Builder().text("Sanctioned format:").build());
|
||||
private final FLabel lblFormat = scroller.add(new FLabel.Builder().text("Select format:").build());
|
||||
private final FComboBox<GameFormat> cbxFormat = scroller.add(new FComboBox<GameFormat>());
|
||||
|
||||
private final FLabel lblCustomDeck = scroller.add(new FLabel.Builder().text("Custom deck:").build());
|
||||
private final FComboBox<Deck> cbxCustomDeck = scroller.add(new FComboBox<Deck>());
|
||||
|
||||
private final FLabel btnDefineCustomFormat = scroller.add(new FLabel.ButtonBuilder().text("Define custom format").build());
|
||||
private final FLabel btnSelectFormat = scroller.add(new FLabel.ButtonBuilder().text("Choose format").build());
|
||||
|
||||
private final FLabel lblPoolDistribution = scroller.add(new FLabel.Builder().text("Starting pool distribution:").build());
|
||||
private final FRadioButton radBalanced = scroller.add(new FRadioButton("Balanced"));
|
||||
@@ -155,12 +157,12 @@ public class NewQuestScreen extends FScreen {
|
||||
private final FLabel lblPrizedCards = scroller.add(new FLabel.Builder().text("Prized cards:").build());
|
||||
private final FComboBox<Object> cbxPrizedCards = scroller.add(new FComboBox<>());
|
||||
|
||||
private final FLabel lblPrizeFormat = scroller.add(new FLabel.Builder().text("Sanctioned format:").build());
|
||||
private final FLabel lblPrizeFormat = scroller.add(new FLabel.Builder().text("Defined format:").build());
|
||||
private final FComboBox<GameFormat> cbxPrizeFormat = scroller.add(new FComboBox<GameFormat>());
|
||||
|
||||
private final FLabel lblPrizeUnrestricted = scroller.add(new FLabel.Builder().align(HAlignment.RIGHT).font(FSkinFont.get(12)).text("All cards will be available to win.").build());
|
||||
private final FLabel lblPrizeSameAsStarting = scroller.add(new FLabel.Builder().align(HAlignment.RIGHT).font(FSkinFont.get(12)).text("Only sets found in starting pool will be available.").build());
|
||||
private final FLabel btnPrizeDefineCustomFormat = scroller.add(new FLabel.ButtonBuilder().text("Define custom format").build());
|
||||
private final FLabel btnPrizeSelectFormat = scroller.add(new FLabel.ButtonBuilder().text("Choose format").build());
|
||||
|
||||
private final FCheckBox cbAllowUnlocks = scroller.add(new FCheckBox("Allow unlock of additional editions"));
|
||||
private final FCheckBox cbFantasy = scroller.add(new FCheckBox("Fantasy Mode"));
|
||||
@@ -183,8 +185,8 @@ public class NewQuestScreen extends FScreen {
|
||||
super(null, NewGameMenu.getMenu());
|
||||
|
||||
cbxStartingPool.addItem(StartingPoolType.Complete);
|
||||
cbxStartingPool.addItem(StartingPoolType.Rotating);
|
||||
cbxStartingPool.addItem(StartingPoolType.CustomFormat);
|
||||
cbxStartingPool.addItem(StartingPoolType.Sanctioned);
|
||||
cbxStartingPool.addItem(StartingPoolType.Casual);
|
||||
cbxStartingPool.addItem(StartingPoolType.Precon);
|
||||
cbxStartingPool.addItem(StartingPoolType.DraftDeck);
|
||||
cbxStartingPool.addItem(StartingPoolType.SealedDeck);
|
||||
@@ -199,8 +201,8 @@ public class NewQuestScreen extends FScreen {
|
||||
|
||||
cbxPrizedCards.addItem("Same as starting pool");
|
||||
cbxPrizedCards.addItem(StartingPoolType.Complete);
|
||||
cbxPrizedCards.addItem(StartingPoolType.Rotating);
|
||||
cbxPrizedCards.addItem(StartingPoolType.CustomFormat);
|
||||
cbxPrizedCards.addItem(StartingPoolType.Sanctioned);
|
||||
cbxPrizedCards.addItem(StartingPoolType.Casual);
|
||||
cbxPrizedCards.setChangedHandler(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
@@ -209,7 +211,7 @@ public class NewQuestScreen extends FScreen {
|
||||
}
|
||||
});
|
||||
|
||||
for (GameFormat gf : FModel.getFormats().getOrderedList()) {
|
||||
for (GameFormat gf : FModel.getFormats().getSanctionedList()) {
|
||||
cbxFormat.addItem(gf);
|
||||
cbxPrizeFormat.addItem(gf);
|
||||
}
|
||||
@@ -275,10 +277,6 @@ public class NewQuestScreen extends FScreen {
|
||||
preconDescriptions.put(name, description);
|
||||
}
|
||||
|
||||
//TODO: Support defining custom format
|
||||
btnDefineCustomFormat.setEnabled(false);
|
||||
btnPrizeDefineCustomFormat.setEnabled(false);
|
||||
|
||||
// disable the very powerful sets -- they can be unlocked later for a high price
|
||||
final List<String> unselectableSets = new ArrayList<>();
|
||||
unselectableSets.add("LEA");
|
||||
@@ -288,31 +286,45 @@ public class NewQuestScreen extends FScreen {
|
||||
unselectableSets.add("ARC");
|
||||
unselectableSets.add("PC2");
|
||||
|
||||
btnDefineCustomFormat.setCommand(new FEventHandler() {
|
||||
btnSelectFormat.setCommand(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
/*final DialogChooseSets dialog = new DialogChooseSets(customFormatCodes, unselectableSets, false);
|
||||
dialog.setOkCallback(new Runnable() {
|
||||
HistoricFormatSelect historicFormatSelect = new HistoricFormatSelect();
|
||||
historicFormatSelect.setOnCloseCallBack(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
customFormatCodes.clear();
|
||||
customFormatCodes.addAll(dialog.getSelectedSets());
|
||||
btnSelectFormat.setText(historicFormatSelect.getSelectedFormat().getName());
|
||||
List<String> setsToAdd = historicFormatSelect.getSelectedFormat().getAllowedSetCodes();
|
||||
for (String setName:setsToAdd){
|
||||
if(!unselectableSets.contains(setName)){
|
||||
customFormatCodes.add(setName);
|
||||
}
|
||||
}
|
||||
}
|
||||
});*/
|
||||
});
|
||||
Forge.openScreen(historicFormatSelect);
|
||||
}
|
||||
});
|
||||
|
||||
btnPrizeDefineCustomFormat.setCommand(new FEventHandler() {
|
||||
btnPrizeSelectFormat.setCommand(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
/*final DialogChooseSets dialog = new DialogChooseSets(customPrizeFormatCodes, unselectableSets, false);
|
||||
dialog.setOkCallback(new Runnable() {
|
||||
HistoricFormatSelect historicFormatSelect = new HistoricFormatSelect();
|
||||
historicFormatSelect.setOnCloseCallBack(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
customPrizeFormatCodes.clear();
|
||||
customPrizeFormatCodes.addAll(dialog.getSelectedSets());
|
||||
btnPrizeSelectFormat.setText(historicFormatSelect.getSelectedFormat().getName());
|
||||
List<String> setsToAdd = historicFormatSelect.getSelectedFormat().getAllowedSetCodes();
|
||||
for (String setName:setsToAdd){
|
||||
if(!unselectableSets.contains(setName)){
|
||||
customPrizeFormatCodes.add(setName);
|
||||
}
|
||||
}
|
||||
}
|
||||
});*/
|
||||
});
|
||||
Forge.openScreen(historicFormatSelect);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -329,10 +341,10 @@ public class NewQuestScreen extends FScreen {
|
||||
lblPreconDeck.setVisible(newVal == StartingPoolType.Precon);
|
||||
cbxPreconDeck.setVisible(newVal == StartingPoolType.Precon);
|
||||
|
||||
lblFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
cbxFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
lblFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
cbxFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
|
||||
btnDefineCustomFormat.setVisible(newVal == StartingPoolType.CustomFormat);
|
||||
btnSelectFormat.setVisible(newVal == StartingPoolType.Casual);
|
||||
|
||||
boolean usesDeckList = newVal == StartingPoolType.SealedDeck || newVal == StartingPoolType.DraftDeck || newVal == StartingPoolType.Cube;
|
||||
lblCustomDeck.setVisible(usesDeckList);
|
||||
@@ -368,9 +380,9 @@ public class NewQuestScreen extends FScreen {
|
||||
lblPrizeUnrestricted.setVisible(newVal == StartingPoolType.Complete);
|
||||
cbAllowUnlocks.setVisible(newVal != StartingPoolType.Complete);
|
||||
|
||||
lblPrizeFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
cbxPrizeFormat.setVisible(newVal == StartingPoolType.Rotating);
|
||||
btnPrizeDefineCustomFormat.setVisible(newVal == StartingPoolType.CustomFormat);
|
||||
lblPrizeFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
cbxPrizeFormat.setVisible(newVal == StartingPoolType.Sanctioned);
|
||||
btnPrizeSelectFormat.setVisible(newVal == StartingPoolType.Casual);
|
||||
lblPrizeSameAsStarting.setVisible(newVal == null);
|
||||
|
||||
scroller.revalidate();
|
||||
@@ -385,6 +397,8 @@ public class NewQuestScreen extends FScreen {
|
||||
cbxStartingPool.setEnabled(qw.getFormat() == null);
|
||||
cbxFormat.setEnabled(qw.getFormat() == null);
|
||||
cbxCustomDeck.setEnabled(qw.getFormat() == null);
|
||||
btnSelectFormat.setEnabled(qw.getFormat() == null);
|
||||
|
||||
// Do NOT disable the following...
|
||||
// cbxPrizeFormat.setEnabled(qw.getFormat() == null);
|
||||
// cboAllowUnlocks.setEnabled(qw.getFormat() == null);
|
||||
@@ -478,7 +492,7 @@ public class NewQuestScreen extends FScreen {
|
||||
|
||||
}
|
||||
|
||||
public GameFormat getRotatingFormat() {
|
||||
public GameFormat getSanctionedFormat() {
|
||||
return cbxFormat.getSelectedItem();
|
||||
}
|
||||
|
||||
@@ -503,10 +517,11 @@ public class NewQuestScreen extends FScreen {
|
||||
|
||||
if (worldFormat == null) {
|
||||
switch(getStartingPoolType()) {
|
||||
case Rotating:
|
||||
fmtStartPool = getRotatingFormat();
|
||||
case Sanctioned:
|
||||
fmtStartPool = getSanctionedFormat();
|
||||
break;
|
||||
|
||||
case Casual:
|
||||
case CustomFormat:
|
||||
if (customFormatCodes.isEmpty()) {
|
||||
if (!SOptionPane.showConfirmDialog(
|
||||
@@ -567,6 +582,7 @@ public class NewQuestScreen extends FScreen {
|
||||
case Complete:
|
||||
fmtPrizes = null;
|
||||
break;
|
||||
case Casual:
|
||||
case CustomFormat:
|
||||
if (customPrizeFormatCodes.isEmpty()) {
|
||||
if (!SOptionPane.showConfirmDialog(
|
||||
@@ -576,7 +592,7 @@ public class NewQuestScreen extends FScreen {
|
||||
}
|
||||
fmtPrizes = customPrizeFormatCodes.isEmpty() ? null : new GameFormat("Custom Prizes", customPrizeFormatCodes, null); // chosen sets and no banned cards
|
||||
break;
|
||||
case Rotating:
|
||||
case Sanctioned:
|
||||
fmtPrizes = getPrizedRotatingFormat();
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -187,6 +187,9 @@ public class SettingsPage extends TabPage<SettingsScreen> {
|
||||
lstSettings.addItem(new BooleanSetting(FPref.LOAD_CARD_SCRIPTS_LAZILY,
|
||||
"Load Card Scripts Lazily",
|
||||
"If turned on, Forge will load card scripts as they're needed instead of at start up. (Warning: Experimental)"), 3);
|
||||
lstSettings.addItem(new BooleanSetting(FPref.LOAD_HISTORIC_FORMATS,
|
||||
"Load Historic Formats",
|
||||
"If turned on, Forge will load all historic format definitions, this may take slightly longer to load at startup."), 3);
|
||||
|
||||
//Graphic Options
|
||||
lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_FOIL_EFFECT,
|
||||
|
||||
6
forge-gui/res/formats/Block/Amonkhet Block.txt
Normal file
6
forge-gui/res/formats/Block/Amonkhet Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Amonkhet Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:112
|
||||
Sets:HOU, AKH
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Battle for Zendikar Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:115
|
||||
Sets:OGW, BFZ
|
||||
7
forge-gui/res/formats/Block/Ice Age Block.txt
Normal file
7
forge-gui/res/formats/Block/Ice Age Block.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Ice Age Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:135
|
||||
Sets:CSP, ALL, ICE
|
||||
Banned:Amulet of Quoz; Thawing Glaciers; Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Innistrad-Avacyn Restored Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:119
|
||||
Sets:ISD, AVR, DKA
|
||||
Banned:Intangible Virtue; Lingering Souls
|
||||
6
forge-gui/res/formats/Block/Invasion Block.txt
Normal file
6
forge-gui/res/formats/Block/Invasion Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Invasion Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:130
|
||||
Sets:APC, PLS, INV
|
||||
6
forge-gui/res/formats/Block/Ixalan Block.txt
Normal file
6
forge-gui/res/formats/Block/Ixalan Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Ixalan Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:111
|
||||
Sets:XLN, RIX
|
||||
@@ -1,5 +1,6 @@
|
||||
[format]
|
||||
Name:Kaladesh Block
|
||||
Type:Historic
|
||||
Order:109
|
||||
Sets:KLD, AER
|
||||
Subtype:Block
|
||||
Order:113
|
||||
Sets:AER, KLD
|
||||
6
forge-gui/res/formats/Block/Kamigawa Block.txt
Normal file
6
forge-gui/res/formats/Block/Kamigawa Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Kamigawa Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:126
|
||||
Sets:SOK, BOK, CHK
|
||||
6
forge-gui/res/formats/Block/Khans of Tarkir Block.txt
Normal file
6
forge-gui/res/formats/Block/Khans of Tarkir Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Khans of Tarkir Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:116
|
||||
Sets:DTK, FRF, KTK
|
||||
6
forge-gui/res/formats/Block/Lorwyn-Shadowmoor Block.txt
Normal file
6
forge-gui/res/formats/Block/Lorwyn-Shadowmoor Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Lorwyn-Shadowmoor Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:123
|
||||
Sets:EVE, SHM, MOR, LRW
|
||||
7
forge-gui/res/formats/Block/Masques Block.txt
Normal file
7
forge-gui/res/formats/Block/Masques Block.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Masques Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:131
|
||||
Sets:PCY, NMS, MMA
|
||||
Banned:Lin Sivvi, Defiant Hero; Rishadan Port
|
||||
7
forge-gui/res/formats/Block/Mirage Block.txt
Normal file
7
forge-gui/res/formats/Block/Mirage Block.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Mirage Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:134
|
||||
Sets:VIS, WTH, MIR
|
||||
Banned:Squandered Resources
|
||||
7
forge-gui/res/formats/Block/Mirrodin Block.txt
Normal file
7
forge-gui/res/formats/Block/Mirrodin Block.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Mirrodin Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:127
|
||||
Sets:5DN, DST, MRD
|
||||
Banned:Aether Vial; Ancient Den; Arcbound Ravager; Darksteel Citadel; Disciple of the Vault; Great Furnace; Seat of the Synod; Tree of Tales; Vault of Whispers; Skullclamp
|
||||
6
forge-gui/res/formats/Block/Odyssey Block.txt
Normal file
6
forge-gui/res/formats/Block/Odyssey Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Odyssey Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:129
|
||||
Sets:JUD, TOR, ODY
|
||||
6
forge-gui/res/formats/Block/Onslaught Block.txt
Normal file
6
forge-gui/res/formats/Block/Onslaught Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Onslaught Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:128
|
||||
Sets:SCG, LGN, ONS
|
||||
6
forge-gui/res/formats/Block/Ravnica Block.txt
Normal file
6
forge-gui/res/formats/Block/Ravnica Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Ravnica Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:125
|
||||
Sets:DIS, GPT, RAV
|
||||
6
forge-gui/res/formats/Block/Return to Ravnica Block.txt
Normal file
6
forge-gui/res/formats/Block/Return to Ravnica Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Return to Ravnica Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:118
|
||||
Sets:DGM, GTC, RTR
|
||||
6
forge-gui/res/formats/Block/Scars of Mirrodin Block.txt
Normal file
6
forge-gui/res/formats/Block/Scars of Mirrodin Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Scars of Mirrodin Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:120
|
||||
Sets:NPH, MBS, SOM
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Shadows over Innistrad Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:114
|
||||
Sets:EMN, SOI
|
||||
6
forge-gui/res/formats/Block/Shards of Alara Block.txt
Normal file
6
forge-gui/res/formats/Block/Shards of Alara Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Shards of Alara Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:122
|
||||
Sets:ARB, CFX, ALA
|
||||
7
forge-gui/res/formats/Block/Tempest Block.txt
Normal file
7
forge-gui/res/formats/Block/Tempest Block.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Tempest Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:133
|
||||
Sets:EXO, STH, TMP
|
||||
Banned:Cursed Scroll
|
||||
6
forge-gui/res/formats/Block/Theros Block.txt
Normal file
6
forge-gui/res/formats/Block/Theros Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Theros Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:117
|
||||
Sets:JOU, BNG, THS
|
||||
6
forge-gui/res/formats/Block/Time Spiral Block.txt
Normal file
6
forge-gui/res/formats/Block/Time Spiral Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Time Spiral Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:124
|
||||
Sets:FUT, PLC, TSP, TSB
|
||||
7
forge-gui/res/formats/Block/Urza Block.txt
Normal file
7
forge-gui/res/formats/Block/Urza Block.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Urza Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:132
|
||||
Sets:UDS, ULG, USG
|
||||
Banned:Gaea's Cradle; Memory Jar; Serra's Sanctum; Time Spiral; Tolarian Academy; Voltaic Key; Windfall
|
||||
6
forge-gui/res/formats/Block/Zendikar Block.txt
Normal file
6
forge-gui/res/formats/Block/Zendikar Block.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Zendikar Block
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Order:121
|
||||
Sets:ROE, WWK, ZEN
|
||||
@@ -1,5 +1,6 @@
|
||||
[format]
|
||||
Name:Commander
|
||||
Type:Casual
|
||||
Order:106
|
||||
Banned:Adriana's Valor; Advantageous Proclamation; Ashnod's Coupon; Assemble the Rank and Vile; Backup Plan; Brago's Favor; Double Cross; Double Deal; Double Dip; Double Play; Double Stroke; Double Take; Echoing Boon; Emissary's Ploy; Enter the Dungeon; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Incendiary Dissent; Iterative Analysis; Magical Hacker; Mox Lotus; Muzzio's Preparations; Natural Unity; Once More with Feeling; Power Play; R&D's Secret Lair; Richard Garfield, Ph.D.; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Sovereign's Realm; Staying Power; Summoner's Bond; Time Machine; Unexpected Potential; Weight Advantage; Worldknit; Amulet of Quoz; Bronze Tablet; Contract from Below; Darkpact; Demonic Attorney; Jeweled Bird; Rebirth; Tempest Efreet; Timmerian Fiends; Ancestral Recall; Balance; Biorhythm; Black Lotus; Braids, Cabal Minion; Chaos Orb; Coalition Victory; Channel; Emrakul, the Aeons Torn; Erayo, Soratami Ascendant; Falling Star; Fastbond; Gifts Ungiven; Griselbrand; Karakas; Leovold, Emissary of Trest; Library of Alexandria; Limited Resources; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Painter's Servant; Panoptic Mirror; Primeval Titan; Prophet of Kruphix; Recurring Nightmare; Rofellos, Llanowar Emissary; Shahrazad; Staying Power; Sundering Titan; Sway of the Stars; Sylvan Primordial; Time Machine; Time Vault; Time Walk; Tinker; Tolarian Academy; Trade Secrets; Upheaval; Worldfire; Yawgmoth's Bargain
|
||||
Subtype:Commander
|
||||
Order:137
|
||||
Banned:Adriana's Valor; Advantageous Proclamation; Ashnod's Coupon; Assemble the Rank and Vile; Backup Plan; Brago's Favor; Double Cross; Double Deal; Double Dip; Double Play; Double Stroke; Double Take; Echoing Boon; Emissary's Ploy; Enter the Dungeon; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Incendiary Dissent; Iterative Analysis; Magical Hacker; Mox Lotus; Muzzio's Preparations; Natural Unity; Once More with Feeling; Power Play; R&D's Secret Lair; Richard Garfield, Ph.D.; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Sovereign's Realm; Staying Power; Summoner's Bond; Time Machine; Unexpected Potential; Weight Advantage; Worldknit; Amulet of Quoz; Bronze Tablet; Contract from Below; Darkpact; Demonic Attorney; Jeweled Bird; Rebirth; Tempest Efreet; Timmerian Fiends; Ancestral Recall; Balance; Biorhythm; Black Lotus; Braids, Cabal Minion; Chaos Orb; Coalition Victory; Channel; Emrakul, the Aeons Torn; Erayo, Soratami Ascendant; Falling Star; Fastbond; Gifts Ungiven; Griselbrand; Karakas; Leovold, Emissary of Trest; Library of Alexandria; Limited Resources; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Painter's Servant; Panoptic Mirror; Primeval Titan; Prophet of Kruphix; Recurring Nightmare; Rofellos, Llanowar Emissary; Shahrazad; Sundering Titan; Sway of the Stars; Sylvan Primordial; Time Vault; Time Walk; Tinker; Tolarian Academy; Trace Secrets; Upheaval; Worldfire; Yawgmoth's Bargain
|
||||
6
forge-gui/res/formats/Casual/Conspiracy.txt
Normal file
6
forge-gui/res/formats/Casual/Conspiracy.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Conspiracy
|
||||
Type:Historic
|
||||
Subtype:Custom
|
||||
Order:138
|
||||
Sets:CNS, CN2
|
||||
6
forge-gui/res/formats/Casual/Un-Sets.txt
Normal file
6
forge-gui/res/formats/Casual/Un-Sets.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Un-Sets
|
||||
Type:Historic
|
||||
Subtype:Custom
|
||||
Order:136
|
||||
Sets:UST, UNH, UGL
|
||||
@@ -1,5 +1,6 @@
|
||||
[format]
|
||||
Name:Pauper
|
||||
Order:108
|
||||
Subtype:Custom
|
||||
Type:Casual
|
||||
Rarities:L, C
|
||||
6
forge-gui/res/formats/Digital/Duels.txt
Normal file
6
forge-gui/res/formats/Digital/Duels.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Duels
|
||||
Type:Digital
|
||||
Subtype:Videogame
|
||||
Order:140
|
||||
Sets:ORI, BFZ, OGW, SOI, EMN, KLD, AER, AKH
|
||||
6
forge-gui/res/formats/Digital/MTGO.txt
Normal file
6
forge-gui/res/formats/Digital/MTGO.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:MTGO
|
||||
Type:Digital
|
||||
Subtype:MTGO
|
||||
Order:139
|
||||
Sets:ALL, MIR, VIS, WTH, TMP, STH, EXO, USG, UDS, MMQ, NMS, PCY, INV, PLS, 7ED, APC, ODY, TOR, JUD, 8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, MED, LRW, MOR, SHM, EVE, ME2, ALA, CFX, ARB, M10, TD0, FVE, ME3, ZEN, WWK, ROE, M11, SOM, TD1, MBED, ME4, MBS, NPH, M12, ISD, DKA, AVR, M13, RTR, TD2, GTC, DGM, M14, THS, BNG, JOU, VMA, M15, KTK, FRF, DTK, TPR, MM2, ORI, BFZ, OGW, PZ1, OGW, EMA, EMN, PZ2, YMC, AER, MM3, AKH, HOU, XLN
|
||||
8
forge-gui/res/formats/Digital/MicroProse.txt
Normal file
8
forge-gui/res/formats/Digital/MicroProse.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:MicroProse
|
||||
Type:Digital
|
||||
Subtype:Videogame
|
||||
Order:110
|
||||
Sets:MTG, STA, AST, DOTP, MTG_R, STA_R, DOTP_R
|
||||
Banned:Channel; Mind Twist; Bronze Tablet; Contract from Below; Darkpact; Demonic Attorney; Jeweled Bird; Rebirth; Tempest Efreet
|
||||
Restricted:Ancestral Recall; Balance; Berserk; Black Lotus; Black Vise; Braingeyser; Demonic Tutor; Fastbond; Fork; Ivory Tower; Library of Alexandria; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Regrowth; Sol Ring; Time Walk; Timetwister; Wheel of Fortune
|
||||
0
forge-gui/res/formats/Historic/.gitkeep
Normal file
0
forge-gui/res/formats/Historic/.gitkeep
Normal file
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Ice Age, 10/01/95
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1995-10-01
|
||||
Sets:ICE
|
||||
Restricted:Zuran Orb
|
||||
Banned:Amulet of Quoz
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Ice Age/Alliances, 10/01/96
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1996-10-01
|
||||
Sets:ICE, ALL
|
||||
Restricted:Zuran Orb
|
||||
Banned:Amulet of Quoz
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Ice Age, 05/01/97
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1997-05-01
|
||||
Sets:ICE
|
||||
Banned:Amulet of Quoz, Thawing Glaciers, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Ice Age/Homelands/Alliances, 07/01/97
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1997-07-01
|
||||
Sets:ICE, HML, ALL
|
||||
Banned:Amulet of Quoz, Thawing Glaciers, Timmerian Fiends, Zuran Orb
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Invasion Block, Invasion
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2000-11-01
|
||||
Sets:INV
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Invasion Block, Planeshift
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2001-03-01
|
||||
Sets:INV, PLS
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Invasion Block, Apocalypse
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2001-07-01
|
||||
Sets:INV, PLS, APC
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Kamigawa Block, Champions of Kamigawa
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2004-10-20
|
||||
Sets:CHK
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Kamigawa Block, Betrayers of Kamigawa
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2005-02-20
|
||||
Sets:CHK, BOK
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Kamigawa Block, Saviors of Kamigawa
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2005-06-20
|
||||
Sets:CHK, BOK, SOK
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Masques Block, Mercadian Masques
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1999-11-01
|
||||
Sets:MMQ
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Masques Block, Nemesis
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2000-03-01
|
||||
Sets:MMQ, NMS
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Masques Block, Prophecy
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2000-07-01
|
||||
Sets:MMQ, NMS, PCY
|
||||
Banned:Lin Sivvi, Defiant Hero; Rishadan Port
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Mirage/Visions/Weatherlight Block, Weatherlight
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1997-07-01
|
||||
Sets:MIR, VIS, WTH
|
||||
Banned:Squandered Resources
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Mirrodin Block, Mirrodin
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2003-10-20
|
||||
Sets:MRD
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Mirrodin Block, Darksteel
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2004-02-20
|
||||
Sets:MRD, DST
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Mirrodin Block, Fifth Dawn
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2004-06-20
|
||||
Sets:MRD, DST, 5DN
|
||||
Banned:Skullclamp
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Odyssey Block, Odyssey
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2001-11-01
|
||||
Sets:ODY
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Odyssey Block, Torment
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2002-03-01
|
||||
Sets:ODY, TOR
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Odyssey Block, Judgment
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2002-07-01
|
||||
Sets:ODY, TOR, JUD
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Onslaught Block, Onslaught
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2002-11-01
|
||||
Sets:ONS
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Onslaught Block, Legions
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2003-03-01
|
||||
Sets:ONS, LGN
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Onslaught Block, Scourge
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2003-07-01
|
||||
Sets:ONS, LGN, SCG
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Tempest Block, Tempest
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1997-11-01
|
||||
Sets:TMP
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Tempest/Stronghold Block, Stronghold
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1998-04-01
|
||||
Sets:TMP, STH
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Tempest/Stronghold/Exodus Block, Exodus
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1998-07-01
|
||||
Sets:TMP, STH, EXO
|
||||
Banned:Cursed Scroll
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Ravnica Block, Ravnica: City of Guilds
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:2005-10-20
|
||||
Sets:RAV
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Urza's Saga Standalone, 01/01/99
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1999-01-01
|
||||
Sets:USG
|
||||
@@ -0,0 +1,6 @@
|
||||
[format]
|
||||
Name:Urza's Saga/Urza's Legacy Standalone, Urza's Legacy
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1999-03-01
|
||||
Sets:USG, ULG
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Urza Block, 04/01/99
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1999-04-01
|
||||
Sets:USG, ULG
|
||||
Banned:Memory Jar, Time Spiral, Windfall
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Urza Block, Urza's Destiny
|
||||
Type:Historic
|
||||
Subtype:Block
|
||||
Effective:1999-07-01
|
||||
Sets:USG, ULG, UDS
|
||||
Banned:Gaea's Cradle, Memory Jar, Serra's Sanctum, Time Spiral, Tolarian Academy, Voltaic Key, Windfall
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Weatherlight
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1997-07-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Braingeyser, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Ivory Tower, Jeweled Bird, Juggernaut, Kird Ape, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Wheel of Fortune, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, 10/01/97
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1997-10-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Braingeyser, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Juggernaut, Kird Ape, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Wheel of Fortune, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Tempest
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1997-11-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Braingeyser, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Juggernaut, Kird Ape, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Wheel of Fortune, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Stronghold
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1998-04-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Braingeyser, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Juggernaut, Kird Ape, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Wheel of Fortune, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Exodus
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1998-07-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Braingeyser, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Wheel of Fortune, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Urza's Saga
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1998-11-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Braingeyser, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Wheel of Fortune, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, 01/01/99
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-01-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Tolarian Academy, Wheel of Fortune, Windfall, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Urza's Legacy
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-03-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Tolarian Academy, Wheel of Fortune, Windfall, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, 04/01/99
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-04-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Memory Jar, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Tolarian Academy, Wheel of Fortune, Windfall, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Classic Sixth Edition
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-06-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Memory Jar, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Timmerian Fiends, Tolarian Academy, Wheel of Fortune, Windfall, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, Urza's Destiny
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-07-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Memory Jar, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Time Spiral, Timmerian Fiends, Tolarian Academy, Wheel of Fortune, Windfall, Zuran Orb
|
||||
@@ -0,0 +1,7 @@
|
||||
[format]
|
||||
Name:Extended, 08/01/99
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-08-01
|
||||
Sets:3ED, DRK, ARENA, FEM, WW, SHC, FS, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS
|
||||
Banned:Amulet of Quoz, Balance, Black Vise, Bronze Tablet, Channel, Contract from Below, Darkpact, Demonic Attorney, Demonic Tutor, Fastbond, Hypnotic Specter, Ivory Tower, Jeweled Bird, Kird Ape, Land Tax, Mana Crypt, Maze of Ith, Memory Jar, Mind Twist, Rebirth, Regrowth, Serendib Efreet, Sol Ring, Strip Mine, Tempest Efreet, Time Spiral, Timmerian Fiends, Tolarian Academy, Wheel of Fortune, Windfall, Yawgmoth's Bargain, Zuran Orb
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, 10/01/99
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-10-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS
|
||||
Banned:Amulet of Quoz, Dream Halls, Earthcraft, Lotus Petal, Memory Jar, Mind Over Matter, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, Mercadian Masques
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:1999-11-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ
|
||||
Banned:Amulet of Quoz, Dream Halls, Earthcraft, Lotus Petal, Memory Jar, Mind Over Matter, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, Nemesis
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:2000-03-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS
|
||||
Banned:Amulet of Quoz, Dream Halls, Earthcraft, Lotus Petal, Memory Jar, Mind Over Matter, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, 04/01/00
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:2000-04-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS
|
||||
Banned:Amulet of Quoz, Dark Ritual, Dream Halls, Earthcraft, Lotus Petal, Mana Vault, Memory Jar, Mind Over Matter, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, Prophecy
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:2000-07-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS, PCY
|
||||
Banned:Amulet of Quoz, Dark Ritual, Dream Halls, Earthcraft, Lotus Petal, Mana Vault, Memory Jar, Mind Over Matter, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, Invasion
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:2000-11-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS, PCY, INV
|
||||
Banned:Amulet of Quoz, Dark Ritual, Dream Halls, Earthcraft, Lotus Petal, Mana Vault, Memory Jar, Mind Over Matter, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, Planeshift
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:2001-03-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS, PCY, INV, PLS
|
||||
Banned:Amulet of Quoz, Dark Ritual, Dream Halls, Earthcraft, Lotus Petal, Mana Vault, Memory Jar, Mind Over Matter, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, 04/01/01
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:2001-04-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS, PCY, INV, PLS
|
||||
Banned:Amulet of Quoz, Dark Ritual, Demonic Consultation, Dream Halls, Earthcraft, Lotus Petal, Mana Vault, Memory Jar, Mind Over Matter, Necropotence, Replenish, Survival of the Fittest, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
@@ -0,0 +1,8 @@
|
||||
[format]
|
||||
Name:Extended, Seventh Edition
|
||||
Type:Historic
|
||||
Subtype:Extended
|
||||
Effective:2001-05-01
|
||||
Sets:ICE, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS, PCY, INV, PLS, 7ED
|
||||
Banned:Amulet of Quoz, Dark Ritual, Demonic Consultation, Dream Halls, Earthcraft, Lotus Petal, Mana Vault, Memory Jar, Mind Over Matter, Necropotence, Replenish, Survival of the Fittest, Time Spiral, Timmerian Fiends, Tolarian Academy, Windfall, Yawgmoth's Bargain, Yawgmoth's Will, Zuran Orb
|
||||
Additional:Badlands, Bayou, Plateau, Savannah, Scrubland, Taiga, Tropical Island, Tundra, Underground Sea, Volcanic Island
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user