mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
moved all items to core, decks were included too.
This commit is contained in:
71
forge-gui/src/main/java/forge/Constant.java
Normal file
71
forge-gui/src/main/java/forge/Constant.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constant interface.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public final class Constant {
|
||||
// used to pass information between the GUI screens
|
||||
/**
|
||||
* The Class Runtime.
|
||||
*/
|
||||
public static class Preferences {
|
||||
/** The Constant DevMode. */
|
||||
// one for normal mode, one for quest mode
|
||||
public static boolean DEV_MODE;
|
||||
/** The Constant UpldDrft. */
|
||||
public static boolean UPLOAD_DRAFT;
|
||||
|
||||
}
|
||||
|
||||
public static class Runtime {
|
||||
/** The Constant NetConn. */
|
||||
public static volatile boolean NET_CONN = false;
|
||||
|
||||
/** The Constant width. */
|
||||
public static final int WIDTH = 300;
|
||||
|
||||
/** The Constant height. */
|
||||
public static final int HEIGHT = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The Interface Keywords.
|
||||
*/
|
||||
public static class Keywords {
|
||||
|
||||
/** The loaded. */
|
||||
public static final boolean[] LOADED = { false };
|
||||
|
||||
/** The Non stacking list. */
|
||||
public static final List<String> NON_STACKING_LIST = new ArrayList<String>();
|
||||
}
|
||||
|
||||
} // Constant
|
||||
|
||||
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.deck;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.card.CardDb;
|
||||
import forge.deck.io.DeckFileHeader;
|
||||
import forge.deck.io.DeckSerializer;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.ItemPoolSorter;
|
||||
import forge.util.ItemPoolView;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Deck class.
|
||||
* </p>
|
||||
*
|
||||
* The set of MTG legal cards that become player's library when the game starts.
|
||||
* Any other data is not part of a deck and should be stored elsewhere. Current
|
||||
* fields allowed for deck metadata are Name, Title, Description and Deck Type.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPool>> {
|
||||
private final Map<DeckSection, CardPool> parts = new EnumMap<DeckSection, CardPool>(DeckSection.class);
|
||||
private final Set<String> tags = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// gameType is from Constant.GameType, like GameType.Regular
|
||||
/**
|
||||
* <p>
|
||||
* Decks have their named finalled.
|
||||
* </p>
|
||||
*/
|
||||
public Deck() {
|
||||
this("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new deck.
|
||||
*
|
||||
* @param name0 the name0
|
||||
*/
|
||||
public Deck(final String name0) {
|
||||
super(name0);
|
||||
getOrCreate(DeckSection.Main);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getName().hashCode();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
public CardPool getMain() {
|
||||
return this.parts.get(DeckSection.Main);
|
||||
}
|
||||
|
||||
// may return nulls
|
||||
public CardPool get(DeckSection deckSection) {
|
||||
return this.parts.get(deckSection);
|
||||
}
|
||||
|
||||
public boolean has(DeckSection deckSection) {
|
||||
final CardPool cp = get(deckSection);
|
||||
return cp != null && !cp.isEmpty();
|
||||
}
|
||||
|
||||
// will return new if it was absent
|
||||
public CardPool getOrCreate(DeckSection deckSection) {
|
||||
CardPool p = get(deckSection);
|
||||
if ( p != null )
|
||||
return p;
|
||||
p = new CardPool();
|
||||
this.parts.put(deckSection, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.deck.DeckBase#cloneFieldsTo(forge.deck.DeckBase)
|
||||
*/
|
||||
@Override
|
||||
protected void cloneFieldsTo(final DeckBase clone) {
|
||||
super.cloneFieldsTo(clone);
|
||||
final Deck result = (Deck) clone;
|
||||
for(Entry<DeckSection, CardPool> kv : parts.entrySet()) {
|
||||
CardPool cp = new CardPool();
|
||||
result.parts.put(kv.getKey(), cp);
|
||||
cp.addAll(kv.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.deck.DeckBase#newInstance(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected DeckBase newInstance(final String name0) {
|
||||
return new Deck(name0);
|
||||
}
|
||||
|
||||
/**
|
||||
* From file.
|
||||
*
|
||||
* @param deckFile the deck file
|
||||
* @return the deck
|
||||
*/
|
||||
public static Deck fromFile(final File deckFile) {
|
||||
return Deck.fromSections(FileSection.parseSections(FileUtil.readFile(deckFile)));
|
||||
}
|
||||
|
||||
/**
|
||||
* From sections.
|
||||
*
|
||||
* @param sections the sections
|
||||
* @return the deck
|
||||
*/
|
||||
public static Deck fromSections(final Map<String, List<String>> sections) {
|
||||
return Deck.fromSections(sections, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* From sections.
|
||||
*
|
||||
* @param sections the sections
|
||||
* @param canThrowExtendedErrors the can throw extended errors
|
||||
* @return the deck
|
||||
*/
|
||||
public static Deck fromSections(final Map<String, List<String>> sections, final boolean canThrowExtendedErrors) {
|
||||
if ((sections == null) || sections.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final DeckFileHeader dh = DeckSerializer.readDeckMetadata(sections, canThrowExtendedErrors);
|
||||
if (dh == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Deck d = new Deck(dh.getName());
|
||||
d.setComment(dh.getComment());
|
||||
d.tags.addAll(dh.getTags());
|
||||
|
||||
for(Entry<String, List<String>> s : sections.entrySet()) {
|
||||
DeckSection sec = DeckSection.smartValueOf(s.getKey());
|
||||
if ( null == sec )
|
||||
continue;
|
||||
|
||||
CardPool pool = CardPool.fromCardList(s.getValue());
|
||||
// I used to store planes and schemes under sideboard header, so this will assign them to a correct section
|
||||
IPaperCard sample = pool.get(0);
|
||||
if ( sample != null && ( sample.getRules().getType().isPlane() || sample.getRules().getType().isPhenomenon() ) )
|
||||
sec = DeckSection.Planes;
|
||||
if ( sample != null && sample.getRules().getType().isScheme() )
|
||||
sec = DeckSection.Schemes;
|
||||
|
||||
d.parts.put(sec, pool);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static List<String> writeCardPool(final ItemPoolView<PaperCard> pool) {
|
||||
final List<Entry<PaperCard, Integer>> main2sort = pool.getOrderedList();
|
||||
Collections.sort(main2sort, ItemPoolSorter.BY_NAME_THEN_SET);
|
||||
final List<String> out = new ArrayList<String>();
|
||||
for (final Entry<PaperCard, Integer> e : main2sort) {
|
||||
out.add(serializeSingleCard(e.getKey(), e.getValue()));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private static String serializeSingleCard(PaperCard card, Integer n) {
|
||||
|
||||
final boolean hasBadSetInfo = "???".equals(card.getEdition()) || StringUtils.isBlank(card.getEdition());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(n).append(" ").append(card.getName());
|
||||
|
||||
if (!hasBadSetInfo) {
|
||||
sb.append("|").append(card.getEdition());
|
||||
}
|
||||
if(card.isFoil()) {
|
||||
sb.append(CardDb.foilSuffix);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* writeDeck.
|
||||
* </p>
|
||||
*
|
||||
* @return the list
|
||||
*/
|
||||
public List<String> save() {
|
||||
|
||||
final List<String> out = new ArrayList<String>();
|
||||
out.add(String.format("[metadata]"));
|
||||
|
||||
out.add(String.format("%s=%s", DeckFileHeader.NAME, this.getName().replaceAll("\n", "")));
|
||||
// these are optional
|
||||
if (this.getComment() != null) {
|
||||
out.add(String.format("%s=%s", DeckFileHeader.COMMENT, this.getComment().replaceAll("\n", "")));
|
||||
}
|
||||
if (!this.getTags().isEmpty()) {
|
||||
out.add(String.format("%s=%s", DeckFileHeader.TAGS, StringUtils.join(getTags(), DeckFileHeader.TAGS_SEPARATOR)));
|
||||
}
|
||||
|
||||
for(Entry<DeckSection, CardPool> s : parts.entrySet()) {
|
||||
out.add(String.format("[%s]", s.getKey().toString()));
|
||||
out.addAll(Deck.writeCardPool(s.getValue()));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
public static final Function<Deck, String> FN_NAME_SELECTOR = new Function<Deck, String>() {
|
||||
@Override
|
||||
public String apply(Deck arg1) {
|
||||
return arg1.getName();
|
||||
}
|
||||
};
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
@Override
|
||||
public Iterator<Entry<DeckSection, CardPool>> iterator() {
|
||||
return parts.entrySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the associated tags, a writable set
|
||||
*/
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.deck;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import forge.util.IHasName;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public abstract class DeckBase implements Serializable, Comparable<DeckBase>, IHasName {
|
||||
private static final long serialVersionUID = -7538150536939660052L;
|
||||
// gameType is from Constant.GameType, like GameType.Regular
|
||||
|
||||
private final String name;
|
||||
private String comment = null;
|
||||
|
||||
/**
|
||||
* Instantiates a new deck base.
|
||||
*
|
||||
* @param name0 the name0
|
||||
*/
|
||||
public DeckBase(final String name0) {
|
||||
this.name = name0.replace('/', '_');
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final DeckBase d) {
|
||||
return this.getName().compareTo(d.getName());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o instanceof Deck) {
|
||||
final Deck d = (Deck) o;
|
||||
return this.getName().equals(d.getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.name.hashCode() * 17) + this.name.hashCode();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.util.IHasName#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the comment.
|
||||
*
|
||||
* @param comment the new comment
|
||||
*/
|
||||
public void setComment(final String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getComment.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public String getComment() {
|
||||
return this.comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* New instance.
|
||||
*
|
||||
* @param name0 the name0
|
||||
* @return the deck base
|
||||
*/
|
||||
protected abstract DeckBase newInstance(String name0);
|
||||
|
||||
/**
|
||||
* Clone fields to.
|
||||
*
|
||||
* @param clone the clone
|
||||
*/
|
||||
protected void cloneFieldsTo(final DeckBase clone) {
|
||||
clone.comment = this.comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy to.
|
||||
*
|
||||
* @param name0 the name0
|
||||
* @return the deck base
|
||||
*/
|
||||
public DeckBase copyTo(final String name0) {
|
||||
final DeckBase obj = this.newInstance(name0);
|
||||
this.cloneFieldsTo(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the best file name.
|
||||
*
|
||||
* @return the best file name
|
||||
*/
|
||||
public final String getBestFileName() {
|
||||
return this.getName().replaceAll("[^-_$#@.,{[()]} a-zA-Z0-9]", "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.deck;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang.math.IntRange;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.CardCoreType;
|
||||
import forge.card.ColorSet;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
/**
|
||||
* GameType is an enum to determine the type of current game. :)
|
||||
*/
|
||||
public enum DeckFormat {
|
||||
|
||||
// Main board: allowed size SB: restriction Max distinct non basic cards
|
||||
Constructed ( new IntRange(60, Integer.MAX_VALUE), new IntRange(0, 15), 4),
|
||||
QuestDeck ( new IntRange(40, Integer.MAX_VALUE), new IntRange(0, 15), 4),
|
||||
Limited ( new IntRange(40, Integer.MAX_VALUE), null, Integer.MAX_VALUE),
|
||||
Commander ( new IntRange(99), new IntRange(0, 10), 1),
|
||||
Vanguard ( new IntRange(60, Integer.MAX_VALUE), new IntRange(0), 4),
|
||||
Planechase ( new IntRange(60, Integer.MAX_VALUE), new IntRange(0), 4),
|
||||
Archenemy ( new IntRange(60, Integer.MAX_VALUE), new IntRange(0), 4);
|
||||
|
||||
private final IntRange mainRange;
|
||||
private final IntRange sideRange; // null => no check
|
||||
private final int maxCardCopies;
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new game type.
|
||||
*
|
||||
* @param isLimited
|
||||
* the is limited
|
||||
*/
|
||||
DeckFormat(IntRange main, IntRange side, int maxCopies) {
|
||||
mainRange = main;
|
||||
sideRange = side;
|
||||
maxCardCopies = maxCopies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Smart value of.
|
||||
*
|
||||
* @param value the value
|
||||
* @param defaultValue the default value
|
||||
* @return the game type
|
||||
*/
|
||||
public static DeckFormat smartValueOf(final String value, DeckFormat defaultValue) {
|
||||
if (null == value) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
final String valToCompate = value.trim();
|
||||
for (final DeckFormat v : DeckFormat.values()) {
|
||||
if (v.name().compareToIgnoreCase(valToCompate) == 0) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("No element named " + value + " in enum GameType");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the sideRange
|
||||
*/
|
||||
public IntRange getSideRange() {
|
||||
return sideRange;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the mainRange
|
||||
*/
|
||||
public IntRange getMainRange() {
|
||||
return mainRange;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the maxCardCopies
|
||||
*/
|
||||
public int getMaxCardCopies() {
|
||||
return maxCardCopies;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
public String getDeckConformanceProblem(Deck deck) {
|
||||
if(deck == null) {
|
||||
return "is not selected";
|
||||
}
|
||||
|
||||
// That's really a bad dependence
|
||||
if (!Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int deckSize = deck.getMain().countAll();
|
||||
|
||||
int min = getMainRange().getMinimumInteger();
|
||||
int max = getMainRange().getMaximumInteger();
|
||||
|
||||
if (deckSize < min) {
|
||||
return String.format("should have a minimum of %d cards", min);
|
||||
}
|
||||
|
||||
if (deckSize > max) {
|
||||
return String.format("should not exceed a maximum of %d cards", max);
|
||||
}
|
||||
|
||||
switch(this) {
|
||||
case Commander: //Must contain exactly 1 legendary Commander and a sideboard of 10 or zero cards.
|
||||
|
||||
final CardPool cmd = deck.get(DeckSection.Commander);
|
||||
if (null == cmd || cmd.isEmpty()) {
|
||||
return "is missing a commander";
|
||||
}
|
||||
if (!cmd.get(0).getRules().getType().isLegendary()
|
||||
|| !cmd.get(0).getRules().getType().isCreature()) {
|
||||
return "has a commander that is not a legendary creature";
|
||||
}
|
||||
|
||||
ColorSet cmdCI = cmd.get(0).getRules().getColorIdentity();
|
||||
List<PaperCard> erroneousCI = new ArrayList<PaperCard>();
|
||||
|
||||
for(Entry<PaperCard, Integer> cp : deck.get(DeckSection.Main)) {
|
||||
if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor()))
|
||||
{
|
||||
erroneousCI.add(cp.getKey());
|
||||
}
|
||||
}
|
||||
if(deck.has(DeckSection.Sideboard))
|
||||
{
|
||||
for(Entry<PaperCard, Integer> cp : deck.get(DeckSection.Sideboard)) {
|
||||
if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor()))
|
||||
{
|
||||
erroneousCI.add(cp.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(erroneousCI.size() > 0)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("contains card that do not match the commanders color identity:");
|
||||
|
||||
for(PaperCard cp : erroneousCI)
|
||||
{
|
||||
sb.append("\n").append(cp.getName());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Planechase: //Must contain at least 10 planes/phenomenons, but max 2 phenomenons. Singleton.
|
||||
final CardPool planes = deck.get(DeckSection.Planes);
|
||||
if (planes == null || planes.countAll() < 10) {
|
||||
return "should have at least 10 planes";
|
||||
}
|
||||
int phenoms = 0;
|
||||
for (Entry<PaperCard, Integer> cp : planes) {
|
||||
|
||||
if (cp.getKey().getRules().getType().typeContains(CardCoreType.Phenomenon)) {
|
||||
phenoms++;
|
||||
}
|
||||
if (cp.getValue() > 1) {
|
||||
return "must not contain multiple copies of any Plane or Phenomena";
|
||||
}
|
||||
|
||||
}
|
||||
if (phenoms > 2) {
|
||||
return "must not contain more than 2 Phenomena";
|
||||
}
|
||||
break;
|
||||
|
||||
case Archenemy: //Must contain at least 20 schemes, max 2 of each.
|
||||
final CardPool schemes = deck.get(DeckSection.Schemes);
|
||||
if (schemes == null || schemes.countAll() < 20) {
|
||||
return "must contain at least 20 schemes";
|
||||
}
|
||||
|
||||
for (Entry<PaperCard, Integer> cp : schemes) {
|
||||
if (cp.getValue() > 2) {
|
||||
return String.format("must not contain more than 2 copies of any Scheme, but has %d of '%s'", cp.getValue(), cp.getKey().getName());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int maxCopies = getMaxCardCopies();
|
||||
if (maxCopies < Integer.MAX_VALUE) {
|
||||
//Must contain no more than 4 of the same card
|
||||
//shared among the main deck and sideboard, except
|
||||
//basic lands, Shadowborn Apostle and Relentless Rats
|
||||
|
||||
CardPool tmp = new CardPool(deck.getMain());
|
||||
if ( deck.has(DeckSection.Sideboard))
|
||||
tmp.addAll(deck.get(DeckSection.Sideboard));
|
||||
if ( deck.has(DeckSection.Commander) && this == Commander)
|
||||
tmp.addAll(deck.get(DeckSection.Commander));
|
||||
|
||||
List<String> limitExceptions = Arrays.asList(new String[]{"Relentless Rats", "Shadowborn Apostle"});
|
||||
|
||||
// should group all cards by name, so that different editions of same card are really counted as the same card
|
||||
for (Entry<String, Integer> cp : Aggregates.groupSumBy(tmp, PaperCard.FN_GET_NAME)) {
|
||||
|
||||
IPaperCard simpleCard = Singletons.getMagicDb().getCommonCards().getCard(cp.getKey());
|
||||
boolean canHaveMultiple = simpleCard.getRules().getType().isBasicLand() || limitExceptions.contains(cp.getKey());
|
||||
|
||||
if (!canHaveMultiple && cp.getValue() > maxCopies) {
|
||||
return String.format("must not contain more than %d of '%s' card", maxCopies, cp.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The sideboard must contain either 0 or 15 cards
|
||||
int sideboardSize = deck.has(DeckSection.Sideboard) ? deck.get(DeckSection.Sideboard).countAll() : 0;
|
||||
IntRange sbRange = getSideRange();
|
||||
if (sbRange != null && sideboardSize > 0 && !sbRange.containsInteger(sideboardSize)) {
|
||||
return sbRange.getMinimumInteger() == sbRange.getMaximumInteger()
|
||||
? String.format("must have a sideboard of %d cards or no sideboard at all", sbRange.getMaximumInteger())
|
||||
: String.format("must have a sideboard of %d to %d cards or no sideboard at all", sbRange.getMinimumInteger(), sbRange.getMaximumInteger());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package forge.deck;
|
||||
|
||||
public enum DeckSection {
|
||||
Avatar(1),
|
||||
Commander(1),
|
||||
Main(60),
|
||||
Sideboard(15),
|
||||
Planes(10),
|
||||
Schemes(20);
|
||||
|
||||
private final int typicalSize; // Rules enforcement is done in DeckFormat class, this is for reference only
|
||||
private DeckSection(int commonSize) {
|
||||
typicalSize = commonSize;
|
||||
}
|
||||
|
||||
public boolean isSingleCard() { return typicalSize == 1; }
|
||||
|
||||
public static DeckSection smartValueOf(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String valToCompate = value.trim();
|
||||
for (final DeckSection v : DeckSection.values()) {
|
||||
if (v.name().compareToIgnoreCase(valToCompate) == 0) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.deck.io;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.deck.DeckFormat;
|
||||
import forge.game.player.PlayerType;
|
||||
import forge.util.FileSection;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class DeckFileHeader {
|
||||
|
||||
/** The Constant NAME. */
|
||||
public static final String NAME = "Name";
|
||||
|
||||
/** The Constant DECK_TYPE. */
|
||||
public static final String DECK_TYPE = "Deck Type";
|
||||
public static final String TAGS = "Tags";
|
||||
|
||||
public static final String TAGS_SEPARATOR = ",";
|
||||
|
||||
/** The Constant COMMENT. */
|
||||
public static final String COMMENT = "Comment";
|
||||
private static final String PLAYER = "Player";
|
||||
private static final String CSTM_POOL = "Custom Pool";
|
||||
private static final String PLAYER_TYPE = "PlayerType";
|
||||
|
||||
private final DeckFormat deckType;
|
||||
private final PlayerType playerType;
|
||||
private final boolean customPool;
|
||||
|
||||
private final String name;
|
||||
private final String comment;
|
||||
|
||||
private final Set<String> tags;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
*
|
||||
* @param kvPairs
|
||||
* the kv pairs
|
||||
*/
|
||||
public DeckFileHeader(final FileSection kvPairs) {
|
||||
this.name = kvPairs.get(DeckFileHeader.NAME);
|
||||
this.comment = kvPairs.get(DeckFileHeader.COMMENT);
|
||||
this.deckType = DeckFormat.smartValueOf(kvPairs.get(DeckFileHeader.DECK_TYPE), DeckFormat.Constructed);
|
||||
this.customPool = kvPairs.getBoolean(DeckFileHeader.CSTM_POOL);
|
||||
boolean isForAi = "computer".equalsIgnoreCase(kvPairs.get(DeckFileHeader.PLAYER)) || "ai".equalsIgnoreCase(kvPairs.get(DeckFileHeader.PLAYER_TYPE));
|
||||
this.playerType = isForAi ? PlayerType.COMPUTER : PlayerType.HUMAN;
|
||||
this.tags = new TreeSet<String>();
|
||||
|
||||
String rawTags = kvPairs.get(DeckFileHeader.TAGS);
|
||||
if( StringUtils.isNotBlank(rawTags) ) {
|
||||
for( String t: rawTags.split(TAGS_SEPARATOR))
|
||||
if ( StringUtils.isNotBlank(t))
|
||||
tags.add(t.trim());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player type.
|
||||
*
|
||||
* @return the player type
|
||||
*/
|
||||
public final PlayerType getPlayerType() {
|
||||
return this.playerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is custom pool.
|
||||
*
|
||||
* @return true, if is custom pool
|
||||
*/
|
||||
public final boolean isCustomPool() {
|
||||
return this.customPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public final String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the comment.
|
||||
*
|
||||
* @return the comment
|
||||
*/
|
||||
public final String getComment() {
|
||||
return this.comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the deck type.
|
||||
*
|
||||
* @return the deck type
|
||||
*/
|
||||
public final DeckFormat getDeckType() {
|
||||
return this.deckType;
|
||||
}
|
||||
|
||||
public final Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
106
forge-gui/src/main/java/forge/deck/io/DeckHtmlSerializer.java
Normal file
106
forge-gui/src/main/java/forge/deck/io/DeckHtmlSerializer.java
Normal file
@@ -0,0 +1,106 @@
|
||||
package forge.deck.io;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.deck.Deck;
|
||||
import forge.item.PaperCard;
|
||||
import forge.properties.NewConstants;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.DefaultObjectWrapper;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
||||
public class DeckHtmlSerializer {
|
||||
public static void writeDeckHtml(final Deck d, final File f) {
|
||||
try {
|
||||
final BufferedWriter writer = new BufferedWriter(new FileWriter(f));
|
||||
writeDeckHtml(d, writer);
|
||||
writer.close();
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* writeDeck.
|
||||
* </p>
|
||||
*
|
||||
* @param d
|
||||
* a {@link forge.deck.Deck} object.
|
||||
* @param out
|
||||
* a {@link java.io.BufferedWriter} object.
|
||||
* @throws java.io.IOException
|
||||
* if any.
|
||||
*/
|
||||
private static void writeDeckHtml(final Deck d, final BufferedWriter out) throws IOException {
|
||||
Template temp = null;
|
||||
final int cardBorder = 0;
|
||||
final int height = 319;
|
||||
final int width = 222;
|
||||
|
||||
/* Create and adjust the configuration */
|
||||
final Configuration cfg = new Configuration();
|
||||
try {
|
||||
cfg.setClassForTemplateLoading(d.getClass(), "/");
|
||||
cfg.setObjectWrapper(new DefaultObjectWrapper());
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------------------
|
||||
* -
|
||||
*/
|
||||
/*
|
||||
* You usually do these for many times in the application
|
||||
* life-cycle:
|
||||
*/
|
||||
|
||||
/* Get or create a template */
|
||||
temp = cfg.getTemplate("proxy-template.ftl");
|
||||
|
||||
/* Create a data-model */
|
||||
final Map<String, Object> root = new HashMap<String, Object>();
|
||||
root.put("title", d.getName());
|
||||
final List<String> list = new ArrayList<String>();
|
||||
for (final Entry<PaperCard, Integer> card : d.getMain()) {
|
||||
// System.out.println(card.getSets().get(card.getSets().size() - 1).URL);
|
||||
for (int i = card.getValue().intValue(); i > 0; --i ) {
|
||||
PaperCard r = card.getKey();
|
||||
String url = NewConstants.URL_PIC_DOWNLOAD + ImageCache.getDownloadUrl(r, false);
|
||||
list.add(url);
|
||||
}
|
||||
}
|
||||
|
||||
final TreeMap<String, Integer> map = new TreeMap<String, Integer>();
|
||||
for (final Entry<PaperCard, Integer> entry : d.getMain().getOrderedList()) {
|
||||
map.put(entry.getKey().getName(), entry.getValue());
|
||||
// System.out.println(entry.getValue() + " " +
|
||||
// entry.getKey().getName());
|
||||
}
|
||||
|
||||
root.put("urls", list);
|
||||
root.put("cardBorder", cardBorder);
|
||||
root.put("height", height);
|
||||
root.put("width", width);
|
||||
root.put("cardlistWidth", width - 11);
|
||||
root.put("cardList", map);
|
||||
|
||||
/* Merge data-model with template */
|
||||
temp.process(root, out);
|
||||
out.flush();
|
||||
} catch (final IOException e) {
|
||||
System.out.println(e.toString());
|
||||
} catch (final TemplateException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.deck.io;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.deck.Deck;
|
||||
import forge.item.PaperCard;
|
||||
import forge.properties.NewConstants;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileSectionManual;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.IItemReader;
|
||||
import forge.util.IItemSerializer;
|
||||
import forge.util.storage.StorageReaderFolder;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.DefaultObjectWrapper;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
||||
/**
|
||||
* This class knows how to make a file out of a deck object and vice versa.
|
||||
*/
|
||||
public class DeckSerializer extends StorageReaderFolder<Deck> implements IItemSerializer<Deck> {
|
||||
private final boolean moveWronglyNamedDecks;
|
||||
public static final String FILE_EXTENSION = ".dck";
|
||||
|
||||
public DeckSerializer(final File deckDir0) {
|
||||
this(deckDir0, false);
|
||||
}
|
||||
|
||||
public DeckSerializer(final File deckDir0, boolean moveWrongDecks) {
|
||||
super(deckDir0, Deck.FN_NAME_SELECTOR);
|
||||
moveWronglyNamedDecks = moveWrongDecks;
|
||||
}
|
||||
|
||||
/** Constant <code>DCKFileFilter</code>. */
|
||||
public static final FilenameFilter DCK_FILE_FILTER = new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(final File dir, final String name) {
|
||||
return name.endsWith(FILE_EXTENSION);
|
||||
}
|
||||
};
|
||||
/** The Constant DCK_FILTER. */
|
||||
public static final FileFilter DCK_FILTER = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(final File f) {
|
||||
return f.getName().endsWith(FILE_EXTENSION) || f.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Simple Deck File .dck";
|
||||
}
|
||||
};
|
||||
|
||||
/** The Constant HTML_FILTER. */
|
||||
public static final FileFilter HTML_FILTER = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(final File f) {
|
||||
return f.getName().endsWith(".html") || f.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Proxy File .html";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* writeDeck.
|
||||
* </p>
|
||||
*
|
||||
* @param d
|
||||
* a {@link forge.deck.Deck} object.
|
||||
* @param out
|
||||
* a {@link java.io.BufferedWriter} object.
|
||||
* @throws java.io.IOException
|
||||
* if any.
|
||||
*/
|
||||
private static void writeDeckHtml(final Deck d, final BufferedWriter out) throws IOException {
|
||||
Template temp = null;
|
||||
final int cardBorder = 0;
|
||||
final int height = 319;
|
||||
final int width = 222;
|
||||
|
||||
/* Create and adjust the configuration */
|
||||
final Configuration cfg = new Configuration();
|
||||
try {
|
||||
cfg.setClassForTemplateLoading(d.getClass(), "/");
|
||||
cfg.setObjectWrapper(new DefaultObjectWrapper());
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------------------
|
||||
* -
|
||||
*/
|
||||
/*
|
||||
* You usually do these for many times in the application
|
||||
* life-cycle:
|
||||
*/
|
||||
|
||||
/* Get or create a template */
|
||||
temp = cfg.getTemplate("proxy-template.ftl");
|
||||
|
||||
/* Create a data-model */
|
||||
final Map<String, Object> root = new HashMap<String, Object>();
|
||||
root.put("title", d.getName());
|
||||
final List<String> list = new ArrayList<String>();
|
||||
for (final Entry<PaperCard, Integer> card : d.getMain()) {
|
||||
// System.out.println(card.getSets().get(card.getSets().size() - 1).URL);
|
||||
for (int i = card.getValue().intValue(); i > 0; --i ) {
|
||||
PaperCard r = card.getKey();
|
||||
String url = NewConstants.URL_PIC_DOWNLOAD + ImageCache.getDownloadUrl(r, false);
|
||||
list.add(url);
|
||||
}
|
||||
}
|
||||
|
||||
final TreeMap<String, Integer> map = new TreeMap<String, Integer>();
|
||||
for (final Entry<PaperCard, Integer> entry : d.getMain().getOrderedList()) {
|
||||
map.put(entry.getKey().getName(), entry.getValue());
|
||||
// System.out.println(entry.getValue() + " " +
|
||||
// entry.getKey().getName());
|
||||
}
|
||||
|
||||
root.put("urls", list);
|
||||
root.put("cardBorder", cardBorder);
|
||||
root.put("height", height);
|
||||
root.put("width", width);
|
||||
root.put("cardlistWidth", width - 11);
|
||||
root.put("cardList", map);
|
||||
|
||||
/* Merge data-model with template */
|
||||
temp.process(root, out);
|
||||
out.flush();
|
||||
} catch (final IOException e) {
|
||||
System.out.println(e.toString());
|
||||
} catch (final TemplateException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeDeck(final Deck d, final File f) {
|
||||
FileUtil.writeFile(f, d.save());
|
||||
}
|
||||
|
||||
public static void writeDeckHtml(final Deck d, final File f) {
|
||||
try {
|
||||
final BufferedWriter writer = new BufferedWriter(new FileWriter(f));
|
||||
DeckSerializer.writeDeckHtml(d, writer);
|
||||
writer.close();
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(final Deck unit) {
|
||||
FileUtil.writeFile(this.makeFileFor(unit), unit.save());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void erase(final Deck unit) {
|
||||
this.makeFileFor(unit).delete();
|
||||
}
|
||||
|
||||
public File makeFileFor(final Deck deck) {
|
||||
return new File(this.directory, deck.getBestFileName() + FILE_EXTENSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Deck read(final File file) {
|
||||
final Map<String, List<String>> sections = FileSection.parseSections(FileUtil.readFile(file));
|
||||
Deck result = Deck.fromSections(sections, true);
|
||||
|
||||
if (moveWronglyNamedDecks) {
|
||||
adjustFileLocation(file, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void adjustFileLocation(final File file, final Deck result) {
|
||||
if (result == null) {
|
||||
file.delete();
|
||||
} else {
|
||||
String destFilename = result.getBestFileName() + FILE_EXTENSION;
|
||||
if (!file.getName().equals(destFilename)) {
|
||||
file.renameTo(new File(file.getParentFile().getParentFile(), destFilename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FilenameFilter getFileFilter() {
|
||||
return DeckSerializer.DCK_FILE_FILTER;
|
||||
}
|
||||
|
||||
public static DeckFileHeader readDeckMetadata(final Map<String, List<String>> map, final boolean canThrow) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
final List<String> metadata = map.get("metadata");
|
||||
if (metadata != null) {
|
||||
return new DeckFileHeader(FileSection.parse(metadata, "="));
|
||||
}
|
||||
final List<String> general = map.get("general");
|
||||
if (general != null) {
|
||||
if (canThrow) {
|
||||
throw new OldDeckFileFormatException();
|
||||
}
|
||||
final FileSectionManual fs = new FileSectionManual();
|
||||
fs.put(DeckFileHeader.NAME, StringUtils.join(map.get(""), " "));
|
||||
fs.put(DeckFileHeader.DECK_TYPE, StringUtils.join(general, " "));
|
||||
return new DeckFileHeader(fs);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.util.storage.StorageReaderBase#getReaderForFolder(java.io.File)
|
||||
*/
|
||||
@Override
|
||||
public IItemReader<Deck> getReaderForFolder(File subfolder) {
|
||||
if ( !subfolder.getParentFile().equals(directory) )
|
||||
throw new UnsupportedOperationException("Only child folders of " + directory + " may be processed");
|
||||
return new DeckSerializer(subfolder, false);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package forge.deck.io;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class OldDeckFileFormatException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 4107122821742791123L;
|
||||
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.game.player.PlayerType;
|
||||
import forge.properties.NewConstants;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
@@ -216,7 +215,6 @@ public class OldDeckParser {
|
||||
break;
|
||||
|
||||
case Limited:
|
||||
final boolean isAi = dh.getPlayerType() == PlayerType.COMPUTER;
|
||||
name = name.startsWith("AI_") ? name.replace("AI_", "") : name;
|
||||
|
||||
Pair<DeckGroup, MutablePair<File, File>> stored = sealedDecks.get(name);
|
||||
@@ -225,7 +223,7 @@ public class OldDeckParser {
|
||||
}
|
||||
|
||||
final Deck deck = Deck.fromSections(sections);
|
||||
if (isAi) {
|
||||
if (dh.isIntendedForAi()) {
|
||||
stored.getLeft().addAiDeck(deck);
|
||||
stored.getRight().setRight(f);
|
||||
} else {
|
||||
|
||||
@@ -15,7 +15,7 @@ import javax.swing.MenuElement;
|
||||
import javax.swing.MenuSelectionManager;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.apache.commons.lang.math.IntRange;
|
||||
import org.apache.commons.lang3.Range;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -188,10 +188,10 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
int sbSize = sideboard.countAll();
|
||||
int combinedDeckSize = mainSize + sbSize;
|
||||
|
||||
int deckMinSize = Math.min(mainSize, gameType.getDecksFormat().getMainRange().getMinimumInteger());
|
||||
IntRange sbRange = gameType.getDecksFormat().getSideRange();
|
||||
int deckMinSize = Math.min(mainSize, gameType.getDecksFormat().getMainRange().getMinimum());
|
||||
Range<Integer> sbRange = gameType.getDecksFormat().getSideRange();
|
||||
// Limited doesn't have a sideboard max, so let the Main min take care of things.
|
||||
int sbMax = sbRange == null ? combinedDeckSize : sbRange.getMaximumInteger();
|
||||
int sbMax = sbRange == null ? combinedDeckSize : sbRange.getMaximum();
|
||||
|
||||
CardPool newSb = new CardPool();
|
||||
List<PaperCard> newMain = null;
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckBase;
|
||||
import forge.deck.io.DeckHtmlSerializer;
|
||||
import forge.deck.io.DeckSerializer;
|
||||
import forge.error.BugReporter;
|
||||
import forge.gui.deckeditor.CDeckEditorUI;
|
||||
@@ -45,7 +46,19 @@ public enum CCurrentDeck implements ICDoc {
|
||||
fileChooser.removeChoosableFileFilter(defFilter);
|
||||
}
|
||||
|
||||
fileChooser.addChoosableFileFilter(DeckSerializer.DCK_FILTER);
|
||||
FileFilter DCK_FILTER = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(final File f) {
|
||||
return f.getName().endsWith(DeckSerializer.FILE_EXTENSION) || f.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Simple Deck File .dck";
|
||||
}
|
||||
};
|
||||
|
||||
fileChooser.addChoosableFileFilter(DCK_FILTER);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -202,7 +215,7 @@ public enum CCurrentDeck implements ICDoc {
|
||||
}
|
||||
|
||||
try {
|
||||
DeckSerializer.writeDeckHtml(
|
||||
DeckHtmlSerializer.writeDeckHtml(
|
||||
((DeckController<Deck>) CDeckEditorUI.SINGLETON_INSTANCE
|
||||
.getCurrentEditorController().getDeckController()).getModel(), filename);
|
||||
} catch (final Exception ex) {
|
||||
@@ -231,7 +244,7 @@ public enum CCurrentDeck implements ICDoc {
|
||||
final JFileChooser save = new JFileChooser(previousDirectory);
|
||||
save.setDialogTitle("Print Proxies");
|
||||
save.setDialogType(JFileChooser.SAVE_DIALOG);
|
||||
save.setFileFilter(DeckSerializer.HTML_FILTER);
|
||||
save.setFileFilter(HTML_FILTER);
|
||||
|
||||
if (save.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
final File file = save.getSelectedFile();
|
||||
@@ -244,4 +257,16 @@ public enum CCurrentDeck implements ICDoc {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The Constant HTML_FILTER. */
|
||||
public static final FileFilter HTML_FILTER = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(final File f) {
|
||||
return f.getName().endsWith(".html") || f.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Proxy File .html";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
|
||||
} else if (card instanceof FatPack) {
|
||||
value = 2365;
|
||||
} else if (card instanceof PreconDeck) {
|
||||
value = ((PreconDeck) card).getRecommendedDeals().getCost();
|
||||
value = QuestController.getPreconDeals((PreconDeck) card).getCost();
|
||||
}
|
||||
|
||||
// TODO: make this changeable via a user-definable property?
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.gui.framework.FScreen;
|
||||
import forge.gui.toolbox.FSkin;
|
||||
import forge.net.FServer;
|
||||
import forge.net.Lobby;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.QuestController;
|
||||
import forge.quest.QuestEvent;
|
||||
import forge.quest.QuestEventChallenge;
|
||||
@@ -374,10 +375,12 @@ public class SSubmenuQuestUtil {
|
||||
return;
|
||||
}
|
||||
|
||||
String errorMessage = GameType.Quest.getDecksFormat().getDeckConformanceProblem(deck);
|
||||
if (null != errorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
String errorMessage = GameType.Quest.getDecksFormat().getDeckConformanceProblem(deck);
|
||||
if (null != errorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@@ -268,7 +268,7 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
|
||||
IStorage<PreconDeck> preconDecks = QuestController.getPrecons();
|
||||
|
||||
for (PreconDeck preconDeck : preconDecks) {
|
||||
if (preconDeck.getRecommendedDeals().getMinWins() > 0) {
|
||||
if (QuestController.getPreconDeals(preconDeck).getMinWins() > 0) {
|
||||
continue;
|
||||
}
|
||||
String name = preconDeck.getName();
|
||||
|
||||
@@ -106,16 +106,18 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
String leftDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(pscLeft.getOriginalDeck());
|
||||
if (null != leftDeckErrorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Left-side deck " + leftDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String rightDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(pscRight.getOriginalDeck());
|
||||
if (null != rightDeckErrorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Right-side deck " + rightDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
String leftDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(pscLeft.getOriginalDeck());
|
||||
if (null != leftDeckErrorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Left-side deck " + leftDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String rightDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(pscRight.getOriginalDeck());
|
||||
if (null != rightDeckErrorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Right-side deck " + rightDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Lobby lobby = FServer.instance.getLobby();
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.net.FServer;
|
||||
import forge.net.Lobby;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
|
||||
/**
|
||||
* Controls the draft submenu in the home UI.
|
||||
@@ -103,10 +104,13 @@ public enum CSubmenuDraft implements ICDoc {
|
||||
"No deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
String errorMessage = gameType.getDecksFormat().getDeckConformanceProblem(humanDeck);
|
||||
if (null != errorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
|
||||
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
String errorMessage = gameType.getDecksFormat().getDeckConformanceProblem(humanDeck);
|
||||
if (null != errorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Singletons.getModel().getGauntletMini().resetGauntletDraft();
|
||||
|
||||
@@ -34,6 +34,7 @@ import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.ItemPool;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
@@ -129,10 +130,12 @@ public enum CSubmenuSealed implements ICDoc {
|
||||
return;
|
||||
}
|
||||
|
||||
String errorMessage = gameType.getDecksFormat().getDeckConformanceProblem(human);
|
||||
if (null != errorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
String errorMessage = gameType.getDecksFormat().getDeckConformanceProblem(human);
|
||||
if (null != errorMessage) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int matches = Singletons.getModel().getDecks().getSealed().get(human.getName()).getAiDecks().size();
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.gui.framework.ICDoc;
|
||||
import forge.gui.toolbox.FList;
|
||||
import forge.net.FServer;
|
||||
import forge.net.Lobby;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
/**
|
||||
@@ -125,12 +126,14 @@ public enum CSubmenuCommander implements ICDoc {
|
||||
GuiDialog.message("No deck selected for player " + (i + 1));
|
||||
return;
|
||||
}
|
||||
String errorMessage = GameType.Commander.getDecksFormat().getDeckConformanceProblem(d);
|
||||
if (null != errorMessage) {
|
||||
if(!problemDecks.contains(d))
|
||||
{
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "The deck " + d.getName() + " " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
problemDecks.add(d);
|
||||
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
String errorMessage = GameType.Commander.getDecksFormat().getDeckConformanceProblem(d);
|
||||
if (null != errorMessage) {
|
||||
if(!problemDecks.contains(d))
|
||||
{
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "The deck " + d.getName() + " " + errorMessage + " Please edit or choose a different deck.", "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||
problemDecks.add(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
playerDecks.add(d);
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package forge.item;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.SealedProductTemplate;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class BoosterPack extends OpenablePack {
|
||||
private final int artIndex;
|
||||
private final int hash;
|
||||
|
||||
public static final Function<CardEdition, BoosterPack> FN_FROM_SET = new Function<CardEdition, BoosterPack>() {
|
||||
@Override
|
||||
public BoosterPack apply(final CardEdition arg1) {
|
||||
SealedProductTemplate d = Singletons.getMagicDb().getBoosters().get(arg1.getCode());
|
||||
return new BoosterPack(arg1.getName(), d);
|
||||
}
|
||||
};
|
||||
|
||||
public BoosterPack(final String name0, final SealedProductTemplate boosterData) {
|
||||
super(name0, boosterData);
|
||||
int maxIdx = Singletons.getMagicDb().getEditions().get(boosterData.getEdition()).getCntBoosterPictures();
|
||||
artIndex = MyRandom.getRandom().nextInt(maxIdx) + 1;
|
||||
hash = super.hashCode() ^ artIndex;
|
||||
}
|
||||
|
||||
public final int getArtIndex() {
|
||||
return artIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getItemType() {
|
||||
return "Booster Pack";
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object clone() {
|
||||
return new BoosterPack(name, contents);
|
||||
}
|
||||
|
||||
public SealedProductTemplate getBoosterData() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
BoosterPack other = (BoosterPack)obj;
|
||||
return artIndex == other.artIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package forge.item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.BoosterGenerator;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.FatPackTemplate;
|
||||
|
||||
public class FatPack extends OpenablePack {
|
||||
public static final Function<CardEdition, FatPack> FN_FROM_SET = new Function<CardEdition, FatPack>() {
|
||||
@Override
|
||||
public FatPack apply(final CardEdition arg1) {
|
||||
FatPackTemplate d = Singletons.getMagicDb().getFatPacks().get(arg1.getCode());
|
||||
return new FatPack(arg1.getName(), d);
|
||||
}
|
||||
};
|
||||
|
||||
private final FatPackTemplate fpData;
|
||||
|
||||
public FatPack(final String name0, final FatPackTemplate fpData0) {
|
||||
super(name0, Singletons.getMagicDb().getBoosters().get(fpData0.getEdition()));
|
||||
fpData = fpData0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return fpData.toString() + contents.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getItemType() {
|
||||
return "Fat Pack";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PaperCard> generate() {
|
||||
List<PaperCard> result = new ArrayList<PaperCard>();
|
||||
for (int i = 0; i < fpData.getCntBoosters(); i++) {
|
||||
result.addAll(super.generate());
|
||||
}
|
||||
result.addAll(BoosterGenerator.getBoosterPack(fpData));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object clone() {
|
||||
return new FatPack(name, fpData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalCards() {
|
||||
return super.getTotalCards() * fpData.getCntBoosters() + fpData.getNumberOfCardsExpected();
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package forge.item;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Filtering conditions for miscellaneous InventoryItems.
|
||||
*/
|
||||
public abstract class ItemPredicate {
|
||||
|
||||
// Static builder methods - they choose concrete implementation by
|
||||
// themselves
|
||||
|
||||
public static final Predicate<Object> IsBoosterPack = Predicates.instanceOf(BoosterPack.class);
|
||||
public static final Predicate<Object> IsPrebuiltDeck = Predicates.instanceOf(PreconDeck.class);
|
||||
public static final Predicate<Object> IsFatPack = Predicates.instanceOf(FatPack.class);
|
||||
|
||||
/**
|
||||
* Checks that the inventory item is a Tournament Pack.
|
||||
*
|
||||
* @return the predicate
|
||||
*/
|
||||
public static final Predicate<InventoryItem> IsTournamentPack = new Predicate<InventoryItem>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(final InventoryItem card) {
|
||||
return card instanceof TournamentPack && !((TournamentPack) card).isStarterDeck();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks that the inventory item is a Starter Deck.
|
||||
*
|
||||
* @return the predicate
|
||||
*/
|
||||
public static final Predicate<InventoryItem> IsStarterDeck = new Predicate<InventoryItem>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(final InventoryItem card) {
|
||||
return card instanceof TournamentPack && ((TournamentPack) card).isStarterDeck();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks that the inventory item is a Prebuilt Deck.
|
||||
*
|
||||
* @return the predicate
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The Class Presets.
|
||||
*/
|
||||
public static class Presets {
|
||||
/** The Item IsPack. */
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final Predicate<InventoryItem> IS_PACK = Predicates.or(IsBoosterPack, IsFatPack, IsTournamentPack);
|
||||
|
||||
/** The Item IsDeck. */
|
||||
public static final Predicate<InventoryItem> IS_DECK = Predicates.or(IsStarterDeck, IsPrebuiltDeck);
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package forge.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.NullArgumentException;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.BoosterGenerator;
|
||||
import forge.card.CardRulesPredicates;
|
||||
import forge.card.SealedProductTemplate;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
public abstract class OpenablePack implements InventoryItemFromSet {
|
||||
protected final SealedProductTemplate contents;
|
||||
protected final String name;
|
||||
private final int hash;
|
||||
private List<PaperCard> cards = null;
|
||||
|
||||
public OpenablePack(String name0, SealedProductTemplate boosterData) {
|
||||
if (null == name0) { throw new NullArgumentException("name0"); }
|
||||
if (null == boosterData) { throw new NullArgumentException("boosterData"); }
|
||||
contents = boosterData;
|
||||
name = name0;
|
||||
hash = name.hashCode() ^ getClass().hashCode() ^ contents.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getName() {
|
||||
return name + " " + getItemType();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return contents.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getEdition() {
|
||||
return contents.getEdition();
|
||||
}
|
||||
|
||||
public final List<PaperCard> getCards() {
|
||||
if (null == cards) {
|
||||
cards = generate();
|
||||
}
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
public int getTotalCards() {
|
||||
return contents.getNumberOfCardsExpected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OpenablePack other = (OpenablePack)obj;
|
||||
return name.equals(other.name) && contents.equals(other.contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected List<PaperCard> generate() {
|
||||
return BoosterGenerator.getBoosterPack(contents);
|
||||
}
|
||||
|
||||
protected PaperCard getRandomBasicLand(final String setCode) {
|
||||
return this.getRandomBasicLands(setCode, 1).get(0);
|
||||
}
|
||||
|
||||
protected List<PaperCard> getRandomBasicLands(final String setCode, final int count) {
|
||||
Predicate<PaperCard> cardsRule = Predicates.and(
|
||||
IPaperCard.Predicates.printedInSet(setCode),
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, PaperCard.FN_GET_RULES));
|
||||
return Aggregates.random(Iterables.filter(Singletons.getMagicDb().getCommonCards().getAllCards(), cardsRule), count);
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* 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.item;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.deck.Deck;
|
||||
import forge.quest.SellRules;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class PreconDeck implements InventoryItemFromSet {
|
||||
|
||||
private final Deck deck;
|
||||
private final String imageFilename;
|
||||
private final String set;
|
||||
private final String description;
|
||||
|
||||
private final SellRules recommendedDeals;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.item.InventoryItemFromSet#getName()
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.deck.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.item.InventoryItem#getType()
|
||||
*/
|
||||
@Override
|
||||
public String getItemType() {
|
||||
return "Prebuilt Deck";
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new precon deck.
|
||||
*
|
||||
* @param f
|
||||
* the f
|
||||
*/
|
||||
public PreconDeck(final File f) {
|
||||
final List<String> deckLines = FileUtil.readFile(f);
|
||||
final Map<String, List<String>> sections = FileSection.parseSections(deckLines);
|
||||
this.deck = Deck.fromSections(sections);
|
||||
|
||||
|
||||
|
||||
FileSection kv = FileSection.parse(sections.get("metadata"), "=");
|
||||
|
||||
imageFilename = kv.get("Image");
|
||||
description = kv.get("Description");
|
||||
String deckEdition = kv.get("set");
|
||||
this.set = deckEdition == null || Singletons.getMagicDb().getEditions().get(deckEdition.toUpperCase()) == null ? "n/a" : deckEdition;
|
||||
this.recommendedDeals = new SellRules(sections.get("shop"));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the deck.
|
||||
*
|
||||
* @return the deck
|
||||
*/
|
||||
public final Deck getDeck() {
|
||||
return this.deck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recommended deals.
|
||||
*
|
||||
* @return the recommended deals
|
||||
*/
|
||||
public final SellRules getRecommendedDeals() {
|
||||
return this.recommendedDeals;
|
||||
}
|
||||
|
||||
public final String getImageFilename() {
|
||||
return imageFilename;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.item.InventoryItemFromSet#getSet()
|
||||
*/
|
||||
@Override
|
||||
public String getEdition() {
|
||||
return this.set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the description.
|
||||
*
|
||||
* @return the description
|
||||
*/
|
||||
public final String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public static final Function<PreconDeck, String> FN_NAME_SELECTOR = new Function<PreconDeck, String>() {
|
||||
@Override
|
||||
public String apply(PreconDeck arg1) {
|
||||
return arg1.getName();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.BoosterGenerator;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.SealedProductTemplate;
|
||||
|
||||
public class TournamentPack extends OpenablePack {
|
||||
|
||||
/** The Constant fnFromSet. */
|
||||
public static final Function<CardEdition, TournamentPack> FN_FROM_SET = new Function<CardEdition, TournamentPack>() {
|
||||
@Override
|
||||
public TournamentPack apply(final CardEdition arg1) {
|
||||
SealedProductTemplate d = Singletons.getMagicDb().getTournamentPacks().get(arg1.getCode());
|
||||
return new TournamentPack(arg1.getName(), d);
|
||||
}
|
||||
};
|
||||
|
||||
public TournamentPack(final String name0, final SealedProductTemplate boosterData) {
|
||||
super(name0, boosterData);
|
||||
}
|
||||
|
||||
public final boolean isStarterDeck() {
|
||||
return contents.getSlots().get(0).getRight() < 30; // hack - getting number of commons, they are first in list
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getItemType() {
|
||||
return !isStarterDeck() ? "Tournament Pack" : "Starter Deck";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PaperCard> generate() {
|
||||
return BoosterGenerator.getBoosterPack(this.contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object clone() {
|
||||
return new TournamentPack(name, contents);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
/** Forge Card Game. */
|
||||
package forge.item;
|
||||
|
||||
@@ -21,6 +21,8 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
@@ -43,7 +45,6 @@ import forge.quest.data.QuestAchievements;
|
||||
import forge.quest.data.QuestAssets;
|
||||
import forge.quest.data.QuestData;
|
||||
import forge.quest.data.QuestPreferences.DifficultyPrefs;
|
||||
import forge.quest.io.PreconReader;
|
||||
import forge.quest.io.QuestChallengeReader;
|
||||
import forge.util.storage.IStorage;
|
||||
import forge.util.storage.StorageBase;
|
||||
@@ -169,19 +170,25 @@ public class QuestController {
|
||||
this.currentEvent = currentEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the precons.
|
||||
*
|
||||
* @return QuestPreconManager
|
||||
*/
|
||||
public static IStorage<PreconDeck> getPrecons() {
|
||||
if (null == preconManager) {
|
||||
preconManager = new StorageBase<PreconDeck>("Quest shop decks", new PreconReader(new File(NewConstants.QUEST_PRECON_DIR)));
|
||||
// read with a special class, that will fill sell rules as it processes each PreconDeck
|
||||
preconManager = new StorageBase<PreconDeck>("Quest shop decks", new PreconDeck.Reader(new File(NewConstants.QUEST_PRECON_DIR)){
|
||||
@Override
|
||||
protected PreconDeck getPreconDeckFromSections(java.util.Map<String,java.util.List<String>> sections) {
|
||||
PreconDeck result = super.getPreconDeckFromSections(sections);
|
||||
preconDeals.put(result.getName(), new SellRules(sections.get("shop")));
|
||||
return result;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return QuestController.preconManager;
|
||||
}
|
||||
|
||||
private final static Map<String, SellRules> preconDeals = new TreeMap<String, SellRules>();
|
||||
public static SellRules getPreconDeals(PreconDeck deck) {
|
||||
return preconDeals.get(deck.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.BoosterGenerator;
|
||||
import forge.card.BoosterSlots;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardEditionPredicates;
|
||||
@@ -516,7 +515,7 @@ public final class QuestUtilCards {
|
||||
private void generatePreconsInShop(final int count) {
|
||||
final List<PreconDeck> meetRequirements = new ArrayList<PreconDeck>();
|
||||
for (final PreconDeck deck : QuestController.getPrecons()) {
|
||||
if (deck.getRecommendedDeals().meetsRequiremnts(this.qc.getAchievements())
|
||||
if (QuestController.getPreconDeals(deck).meetsRequiremnts(this.qc.getAchievements())
|
||||
&& (null == qc.getFormat() || qc.getFormat().isSetLegal(deck.getEdition()))) {
|
||||
meetRequirements.add(deck);
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.quest.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
import forge.deck.io.DeckSerializer;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.util.storage.StorageReaderFolder;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class PreconReader extends StorageReaderFolder<PreconDeck> {
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
*
|
||||
* @param deckDir0 the deck dir0
|
||||
*/
|
||||
public PreconReader(final File deckDir0) {
|
||||
super(deckDir0, PreconDeck.FN_NAME_SELECTOR);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.deck.io.DeckSerializerBase#read(java.io.File)
|
||||
*/
|
||||
@Override
|
||||
protected PreconDeck read(final File file) {
|
||||
return new PreconDeck(file);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.deck.io.DeckSerializerBase#getFileFilter()
|
||||
*/
|
||||
@Override
|
||||
protected FilenameFilter getFileFilter() {
|
||||
return DeckSerializer.DCK_FILE_FILTER;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.util.IItemReader#readAll()
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package forge.view;
|
||||
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.cardfactory.CardStorageReader;
|
||||
import forge.net.FServer;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user