mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Support loading more information into model
This commit is contained in:
9
.gitattributes
vendored
9
.gitattributes
vendored
@@ -189,6 +189,7 @@ forge-core/src/main/java/forge/deck/generation/DeckGeneratorBase.java -text
|
||||
forge-core/src/main/java/forge/deck/generation/DeckGeneratorMonoColor.java -text
|
||||
forge-core/src/main/java/forge/deck/generation/package-info.java svneol=native#text/plain
|
||||
forge-core/src/main/java/forge/deck/io/DeckFileHeader.java -text
|
||||
forge-core/src/main/java/forge/deck/io/DeckGroupSerializer.java -text
|
||||
forge-core/src/main/java/forge/deck/io/DeckSerializer.java -text
|
||||
forge-core/src/main/java/forge/deck/io/DeckStorage.java -text
|
||||
forge-core/src/main/java/forge/deck/io/OldDeckFileFormatException.java -text
|
||||
@@ -15450,7 +15451,6 @@ forge-gui/src/main/java/forge/control/InputQueue.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/control/KeyboardShortcuts.java -text
|
||||
forge-gui/src/main/java/forge/control/RestartUtil.java -text
|
||||
forge-gui/src/main/java/forge/control/package-info.java -text
|
||||
forge-gui/src/main/java/forge/deck/io/DeckGroupSerializer.java -text
|
||||
forge-gui/src/main/java/forge/deck/io/DeckHtmlSerializer.java -text
|
||||
forge-gui/src/main/java/forge/deck/io/DeckPreferences.java -text
|
||||
forge-gui/src/main/java/forge/deck/io/OldDeckParser.java -text
|
||||
@@ -16024,9 +16024,15 @@ forge-m-base/src/forge/assets/FSkinTexture.java -text
|
||||
forge-m-base/src/forge/assets/FTextureImage.java -text
|
||||
forge-m-base/src/forge/assets/ImageCache.java -text
|
||||
forge-m-base/src/forge/assets/ImageLoader.java -text
|
||||
forge-m-base/src/forge/deck/io/OldDeckParser.java -text
|
||||
forge-m-base/src/forge/error/BugReporter.java -text
|
||||
forge-m-base/src/forge/error/ExceptionHandler.java -text
|
||||
forge-m-base/src/forge/limited/CustomLimited.java -text
|
||||
forge-m-base/src/forge/model/CardBlock.java -text
|
||||
forge-m-base/src/forge/model/CardCollections.java -text
|
||||
forge-m-base/src/forge/model/FModel.java -text
|
||||
forge-m-base/src/forge/model/MetaSet.java -text
|
||||
forge-m-base/src/forge/model/UnOpenedMeta.java -text
|
||||
forge-m-base/src/forge/player/LobbyPlayerHuman.java -text
|
||||
forge-m-base/src/forge/player/PlayerControllerHuman.java -text
|
||||
forge-m-base/src/forge/screens/FScreen.java -text
|
||||
@@ -16060,6 +16066,7 @@ forge-m-base/src/forge/toolbox/FOptionPane.java -text
|
||||
forge-m-base/src/forge/toolbox/FOverlay.java -text
|
||||
forge-m-base/src/forge/toolbox/FProgressBar.java -text
|
||||
forge-m-base/src/forge/toolbox/FScrollPane.java -text
|
||||
forge-m-base/src/forge/toolbox/GuiChoose.java -text
|
||||
forge-m-base/src/forge/utils/Constants.java -text
|
||||
forge-m-base/src/forge/utils/ForgePreferences.java -text
|
||||
forge-m-base/src/forge/utils/ForgeProfileProperties.java -text
|
||||
|
||||
275
forge-m-base/src/forge/deck/io/OldDeckParser.java
Normal file
275
forge-m-base/src/forge/deck/io/OldDeckParser.java
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* 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 forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.storage.IStorage;
|
||||
import forge.utils.Constants;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class OldDeckParser {
|
||||
|
||||
/** Constant <code>BDKFileFilter</code>. */
|
||||
public static final FilenameFilter BDK_FILE_FILTER = new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(final File dir, final String name) {
|
||||
return name.endsWith(".bdk");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
*
|
||||
* @param file the file
|
||||
* @param constructed2 the constructed2
|
||||
* @param draft2 the draft2
|
||||
* @param sealed2 the sealed2
|
||||
* @param cube2 the cube2
|
||||
*/
|
||||
public OldDeckParser(final IStorage<Deck> constructed2, final IStorage<DeckGroup> draft2,
|
||||
final IStorage<DeckGroup> sealed2, final IStorage<Deck> cube2) {
|
||||
this.deckDir = new File(Constants.DECK_BASE_DIR);
|
||||
this.sealed = sealed2;
|
||||
this.constructed = constructed2;
|
||||
this.cube = cube2;
|
||||
this.draft = draft2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sealed.
|
||||
*
|
||||
* @return the sealed
|
||||
*/
|
||||
protected final IStorage<DeckGroup> getSealed() {
|
||||
return this.sealed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constructed.
|
||||
*
|
||||
* @return the constructed
|
||||
*/
|
||||
protected final IStorage<Deck> getConstructed() {
|
||||
return this.constructed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the draft.
|
||||
*
|
||||
* @return the draft
|
||||
*/
|
||||
protected final IStorage<DeckGroup> getDraft() {
|
||||
return this.draft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cube.
|
||||
*
|
||||
* @return the cube
|
||||
*/
|
||||
protected final IStorage<Deck> getCube() {
|
||||
return this.cube;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the deck dir.
|
||||
*
|
||||
* @return the deck dir
|
||||
*/
|
||||
protected final File getDeckDir() {
|
||||
return this.deckDir;
|
||||
}
|
||||
|
||||
private final IStorage<DeckGroup> sealed;
|
||||
private final IStorage<Deck> constructed;
|
||||
private final IStorage<DeckGroup> draft;
|
||||
private final IStorage<Deck> cube;
|
||||
private final File deckDir;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*/
|
||||
public void tryParse() {
|
||||
this.convertConstructedAndSealed();
|
||||
this.convertDrafts();
|
||||
}
|
||||
|
||||
private void convertDrafts() {
|
||||
for (final File f : this.deckDir.listFiles(OldDeckParser.BDK_FILE_FILTER)) {
|
||||
boolean gotError = false;
|
||||
final Deck human = DeckSerializer.fromFile(new File(f, "0.dck"));
|
||||
final DeckGroup d = new DeckGroup(human.getName());
|
||||
d.setHumanDeck(human);
|
||||
|
||||
for (int i = 1; i < DeckGroupSerializer.MAX_DRAFT_PLAYERS; i++) {
|
||||
final Deck nextAi = DeckSerializer.fromFile(new File(f, i + ".dck"));
|
||||
if (nextAi == null) {
|
||||
gotError = true;
|
||||
break;
|
||||
}
|
||||
d.addAiDeck(nextAi);
|
||||
}
|
||||
|
||||
boolean mayDelete = !gotError;
|
||||
if (!gotError) {
|
||||
this.draft.add(d);
|
||||
} else {
|
||||
final String msg = String.format("Draft '%s' lacked some decks.%n%nShould it be deleted?");
|
||||
mayDelete = FOptionPane.showConfirmDialog(msg, "Draft loading error");
|
||||
}
|
||||
|
||||
if (mayDelete) {
|
||||
for (final File f1 : f.listFiles()) {
|
||||
f1.delete();
|
||||
}
|
||||
f.delete();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void convertConstructedAndSealed() {
|
||||
boolean allowDeleteUnsupportedConstructed = false;
|
||||
final Map<String, Pair<DeckGroup, MutablePair<File, File>>> sealedDecks = new TreeMap<String, Pair<DeckGroup, MutablePair<File, File>>>(
|
||||
String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
for (final File f : this.deckDir.listFiles(DeckStorage.DCK_FILE_FILTER)) {
|
||||
boolean importedOk = false;
|
||||
|
||||
final List<String> fileLines = FileUtil.readFile(f);
|
||||
final Map<String, List<String>> sections = FileSection.parseSections(fileLines);
|
||||
final DeckFileHeader dh = DeckSerializer.readDeckMetadata(sections);
|
||||
String name = dh.getName();
|
||||
|
||||
if (dh.isCustomPool()) {
|
||||
try {
|
||||
this.cube.add(DeckSerializer.fromSections(sections));
|
||||
importedOk = true;
|
||||
}
|
||||
catch (final NoSuchElementException ex) {
|
||||
if (!allowDeleteUnsupportedConstructed) {
|
||||
final String msg = String
|
||||
.format("Can not convert deck '%s' for some unsupported cards it contains. %n%s%n%nMay Forge delete all such decks?",
|
||||
name, ex.getMessage());
|
||||
allowDeleteUnsupportedConstructed = FOptionPane.showConfirmDialog(msg, "Problem converting decks");
|
||||
}
|
||||
}
|
||||
if (importedOk || allowDeleteUnsupportedConstructed) {
|
||||
f.delete();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (dh.getDeckType()) {
|
||||
case Constructed:
|
||||
try {
|
||||
this.constructed.add(DeckSerializer.fromSections(sections));
|
||||
importedOk = true;
|
||||
} catch (final NoSuchElementException ex) {
|
||||
if (!allowDeleteUnsupportedConstructed) {
|
||||
final String msg = String
|
||||
.format("Can not convert deck '%s' for some unsupported cards it contains. %n%s%n%nMay Forge delete all such decks?",
|
||||
name, ex.getMessage());
|
||||
allowDeleteUnsupportedConstructed = FOptionPane.showConfirmDialog(msg, "Problem converting decks");
|
||||
}
|
||||
}
|
||||
if (importedOk || allowDeleteUnsupportedConstructed) {
|
||||
f.delete();
|
||||
}
|
||||
break;
|
||||
|
||||
case Limited:
|
||||
name = name.startsWith("AI_") ? name.replace("AI_", "") : name;
|
||||
|
||||
Pair<DeckGroup, MutablePair<File, File>> stored = sealedDecks.get(name);
|
||||
if (null == stored) {
|
||||
stored = ImmutablePair.of(new DeckGroup(name), MutablePair.of((File) null, (File) null));
|
||||
}
|
||||
|
||||
final Deck deck = DeckSerializer.fromSections(sections);
|
||||
if (dh.isIntendedForAi()) {
|
||||
stored.getLeft().addAiDeck(deck);
|
||||
stored.getRight().setRight(f);
|
||||
} else {
|
||||
stored.getLeft().setHumanDeck(deck);
|
||||
stored.getRight().setLeft(f);
|
||||
}
|
||||
|
||||
if ((stored.getLeft().getHumanDeck() != null) && !stored.getLeft().getAiDecks().isEmpty()) {
|
||||
// have both parts of sealed deck, may convert
|
||||
this.sealed.add(stored.getLeft());
|
||||
stored.getRight().getLeft().delete();
|
||||
stored.getRight().getRight().delete();
|
||||
|
||||
// there stay only orphans
|
||||
sealedDecks.remove(name);
|
||||
} else {
|
||||
sealedDecks.put(name, stored);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// advise to kill orphaned decks
|
||||
if (!sealedDecks.isEmpty()) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (final Pair<DeckGroup, MutablePair<File, File>> s : sealedDecks.values()) {
|
||||
final String missingPart = s.getRight().getLeft() == null ? "human" : "computer";
|
||||
sb.append(String.format("Sealed deck '%s' has no matching '%s' deck.%n", s.getKey().getName(),
|
||||
missingPart));
|
||||
}
|
||||
sb.append(System.getProperty("line.separator"));
|
||||
sb.append("May Forge delete these decks?");
|
||||
if (FOptionPane.showConfirmDialog(sb.toString(), "Some of your sealed decks are orphaned")) {
|
||||
for (final Pair<DeckGroup, MutablePair<File, File>> s : sealedDecks.values()) {
|
||||
if (s.getRight().getLeft() != null) {
|
||||
s.getRight().getLeft().delete();
|
||||
}
|
||||
if (s.getRight().getRight() != null) {
|
||||
s.getRight().getRight().delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deckDir
|
||||
*/
|
||||
|
||||
}
|
||||
180
forge-m-base/src/forge/limited/CustomLimited.java
Normal file
180
forge-m-base/src/forge/limited/CustomLimited.java
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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.limited;
|
||||
|
||||
import forge.card.CardEdition;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.model.FModel;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.ItemPool;
|
||||
import forge.util.TextUtil;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* CustomDraft class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: CustomLimited.java 24769 2014-02-09 13:56:04Z Hellfish $
|
||||
*/
|
||||
public class CustomLimited extends DeckBase {
|
||||
private final SealedProduct.Template tpl;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
*
|
||||
* @param name0 the name0
|
||||
* @param slots
|
||||
*/
|
||||
public CustomLimited(final String name0, List<Pair<String, Integer>> slots) {
|
||||
super(name0);
|
||||
tpl = new SealedProduct.Template(slots);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 7435640939026612173L;
|
||||
|
||||
/** The Num packs. */
|
||||
private int numPacks = 3;
|
||||
|
||||
private transient ItemPool<PaperCard> cardPool;
|
||||
|
||||
/** The Land set code. */
|
||||
private String landSetCode = CardEdition.Predicates.getRandomSetWithAllBasicLands(FModel.getMagicDb().getEditions()).getCode();
|
||||
|
||||
private boolean singleton;
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemType() {
|
||||
return "Limited deck";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the.
|
||||
*
|
||||
* @param dfData the df data
|
||||
* @param cubes the cubes
|
||||
* @return the custom limited
|
||||
*/
|
||||
public static CustomLimited parse(final List<String> dfData, final IStorage<Deck> cubes) {
|
||||
|
||||
final FileSection data = FileSection.parse(dfData, ":");
|
||||
|
||||
List<Pair<String, Integer>> slots = new ArrayList<Pair<String,Integer>>();
|
||||
String boosterData = data.get("Booster");
|
||||
if(StringUtils.isNotEmpty(boosterData)){
|
||||
final String[] booster = TextUtil.splitWithParenthesis(boosterData, ',');
|
||||
for(String slotDesc : booster) {
|
||||
String[] kv = TextUtil.splitWithParenthesis(slotDesc, ' ', 2);
|
||||
slots.add(ImmutablePair.of(kv[1], Integer.parseInt(kv[0])));
|
||||
}
|
||||
} else
|
||||
slots = SealedProduct.Template.genericBooster.getSlots();
|
||||
|
||||
final CustomLimited cd = new CustomLimited(data.get("Name"), slots);
|
||||
cd.landSetCode = data.get("LandSetCode");
|
||||
cd.numPacks = data.getInt("NumPacks");
|
||||
cd.singleton = data.getBoolean("Singleton");
|
||||
final Deck deckCube = cubes.get(data.get("DeckFile"));
|
||||
cd.cardPool = deckCube == null ? ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getUniqueCards(), PaperCard.class) : deckCube.getMain();
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the num packs.
|
||||
*
|
||||
* @return the numPacks
|
||||
*/
|
||||
public int getNumPacks() {
|
||||
return this.numPacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the num packs.
|
||||
*
|
||||
* @param numPacksIn
|
||||
* the numPacks to set
|
||||
*/
|
||||
public void setNumPacks(final int numPacksIn) {
|
||||
this.numPacks = numPacksIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the land set code.
|
||||
*
|
||||
* @return the landSetCode
|
||||
*/
|
||||
public String getLandSetCode() {
|
||||
return this.landSetCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.item.CardCollectionBase#getCardPool()
|
||||
*/
|
||||
public ItemPool<PaperCard> getCardPool() {
|
||||
return this.cardPool;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.deck.DeckBase#getInstance(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected DeckBase newInstance(final String name0) {
|
||||
return new CustomLimited(name0, tpl.getSlots());
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @return
|
||||
*/
|
||||
public SealedProduct.Template getSealedProductTemplate() {
|
||||
return tpl;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return singleton;
|
||||
}
|
||||
}
|
||||
302
forge-m-base/src/forge/model/CardBlock.java
Normal file
302
forge-m-base/src/forge/model/CardBlock.java
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.IUnOpenedProduct;
|
||||
import forge.card.UnOpenedProduct;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.TextUtil;
|
||||
import forge.util.storage.StorageReaderFile;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
// import forge.deck.Deck;
|
||||
|
||||
/**
|
||||
* This is a CardBlock class.
|
||||
*/
|
||||
public final class CardBlock implements Comparable<CardBlock> {
|
||||
private static final CardEdition[] EMPTY_SET_ARRAY = new CardEdition[] {};
|
||||
|
||||
private final int orderNum;
|
||||
private final String name;
|
||||
private final CardEdition[] sets;
|
||||
private final Map<String, MetaSet> metaSets = new TreeMap<String, MetaSet>();
|
||||
private final CardEdition landSet;
|
||||
private final int cntBoostersDraft;
|
||||
private final int cntBoostersSealed;
|
||||
private Predicate<PaperCard> filter = null;
|
||||
|
||||
/**
|
||||
* Instantiates a new card block.
|
||||
*
|
||||
* @param index
|
||||
* the index
|
||||
* @param name
|
||||
* the name
|
||||
* @param sets
|
||||
* the sets
|
||||
* @param metas
|
||||
* the included meta-sets
|
||||
* @param landSet
|
||||
* the land set
|
||||
* @param cntBoostersDraft
|
||||
* the cnt boosters draft
|
||||
* @param cntBoostersSealed
|
||||
* the cnt boosters sealed
|
||||
*/
|
||||
public CardBlock(final int index, final String name, final List<CardEdition> sets, final List<MetaSet> metas,
|
||||
final CardEdition landSet, final int cntBoostersDraft, final int cntBoostersSealed) {
|
||||
this.orderNum = index;
|
||||
this.name = name;
|
||||
this.sets = sets.toArray(CardBlock.EMPTY_SET_ARRAY);
|
||||
for(MetaSet m : metas) {
|
||||
this.metaSets.put(m.getCode(), m);
|
||||
}
|
||||
this.landSet = landSet;
|
||||
this.cntBoostersDraft = cntBoostersDraft;
|
||||
this.cntBoostersSealed = cntBoostersSealed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sets.
|
||||
*
|
||||
* @return the sets
|
||||
*/
|
||||
public CardEdition[] getSets() {
|
||||
return this.sets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the land set.
|
||||
*
|
||||
* @return the land set
|
||||
*/
|
||||
public CardEdition getLandSet() {
|
||||
return this.landSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cnt boosters draft.
|
||||
*
|
||||
* @return the cnt boosters draft
|
||||
*/
|
||||
public int getCntBoostersDraft() {
|
||||
return this.cntBoostersDraft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cnt boosters sealed.
|
||||
*
|
||||
* @return the cnt boosters sealed
|
||||
*/
|
||||
public int getCntBoostersSealed() {
|
||||
return this.cntBoostersSealed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filter.
|
||||
*
|
||||
* @return the filter
|
||||
*/
|
||||
public Predicate<PaperCard> getFilter() {
|
||||
if (this.filter == null) {
|
||||
this.filter = this.buildFilter();
|
||||
}
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
private Predicate<PaperCard> buildFilter() {
|
||||
final List<String> setCodes = new ArrayList<String>();
|
||||
for (final CardEdition set : this.sets) {
|
||||
setCodes.add(set.getCode());
|
||||
}
|
||||
return IPaperCard.Predicates.printedInSets(setCodes, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = (prime * result) + ((this.landSet == null) ? 0 : this.landSet.hashCode());
|
||||
result = (prime * result) + ((this.name == null) ? 0 : this.name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final CardBlock other = (CardBlock) obj;
|
||||
if (!this.landSet.equals(other.landSet)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final CardBlock o) {
|
||||
return this.orderNum - o.orderNum;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.metaSets.isEmpty() && this.sets.length < 1) {
|
||||
return this.name + " (empty)";
|
||||
} else if (this.metaSets.size() + this.getNumberSets() < 2) {
|
||||
return this.name + " (set)";
|
||||
}
|
||||
return this.name + " (block)";
|
||||
}
|
||||
|
||||
public static final Function<CardBlock, String> FN_GET_NAME = new Function<CardBlock, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(CardBlock arg1) {
|
||||
return arg1.getName();
|
||||
}
|
||||
};
|
||||
|
||||
public static class Reader extends StorageReaderFile<CardBlock> {
|
||||
|
||||
private final CardEdition.Collection editions;
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param pathname
|
||||
* @param keySelector0
|
||||
*/
|
||||
public Reader(String pathname, CardEdition.Collection editions0) {
|
||||
super(pathname, CardBlock.FN_GET_NAME);
|
||||
editions = editions0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.util.StorageReaderFile#read(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected CardBlock read(String line, int i) {
|
||||
final String[] sParts = TextUtil.splitWithParenthesis(line.trim(), ',', 3);
|
||||
String name = sParts[0];
|
||||
|
||||
String[] numbers = sParts[1].trim().split("/");
|
||||
int draftBoosters = StringUtils.isNumeric(numbers[0]) ? Integer.parseInt(numbers[0]) : 0;
|
||||
int sealedBoosters = StringUtils.isNumeric(numbers[1]) ? Integer.parseInt(numbers[1]) : 0;
|
||||
CardEdition landSet = editions.getEditionByCodeOrThrow(numbers[2]);
|
||||
|
||||
List<CardEdition> sets = new ArrayList<CardEdition>();
|
||||
List<MetaSet> metas = new ArrayList<MetaSet>();
|
||||
|
||||
String[] setNames = TextUtil.splitWithParenthesis(sParts[2], ' ' );
|
||||
for(final String set : setNames ) {
|
||||
if(set.startsWith("Meta-")) {
|
||||
String metaSpec = set.substring(5);
|
||||
boolean noDraft = metaSpec.startsWith("NoDraft-");
|
||||
if( noDraft ) metaSpec = metaSpec.substring(8);
|
||||
metas.add(new MetaSet(metaSpec, noDraft));
|
||||
} else {
|
||||
sets.add(editions.getEditionByCodeOrThrow(set));
|
||||
}
|
||||
}
|
||||
|
||||
return new CardBlock(i+1, name, sets, metas, landSet, draftBoosters, sealedBoosters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of normal sets in the block.
|
||||
*
|
||||
* @return int, number of sets.
|
||||
*/
|
||||
public int getNumberSets() {
|
||||
if (sets == null || sets.length < 1) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return sets.length;
|
||||
}
|
||||
}
|
||||
|
||||
public Iterable<String> getMetaSetNames() {
|
||||
return metaSets.keySet();
|
||||
}
|
||||
|
||||
public MetaSet getMetaSet(String key) {
|
||||
return metaSets.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to create a booster for the selected meta-set code.
|
||||
*
|
||||
* @param code
|
||||
* String, the MetaSet code
|
||||
* @return UnOpenedProduct, the created booster.
|
||||
*/
|
||||
public IUnOpenedProduct getBooster(final String code) {
|
||||
MetaSet ms = metaSets.get(code);
|
||||
return ms == null ? new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(code)) : ms.getBooster();
|
||||
}
|
||||
}
|
||||
129
forge-m-base/src/forge/model/CardCollections.java
Normal file
129
forge-m-base/src/forge/model/CardCollections.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.deck.io.DeckGroupSerializer;
|
||||
import forge.deck.io.DeckStorage;
|
||||
import forge.deck.io.OldDeckParser;
|
||||
import forge.util.storage.IStorage;
|
||||
import forge.util.storage.StorageImmediatelySerialized;
|
||||
import forge.utils.Constants;
|
||||
|
||||
import org.apache.commons.lang3.time.StopWatch;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Holds editable maps of decks saved to disk. Adding or removing items to(from)
|
||||
* such map turns into immediate file update
|
||||
*/
|
||||
public class CardCollections {
|
||||
private final IStorage<Deck> constructed;
|
||||
private final IStorage<DeckGroup> draft;
|
||||
private final IStorage<DeckGroup> sealed;
|
||||
private final IStorage<Deck> cube;
|
||||
private final IStorage<Deck> scheme;
|
||||
private final IStorage<Deck> plane;
|
||||
private final IStorage<Deck> commander;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
*
|
||||
* @param file the file
|
||||
*/
|
||||
public CardCollections() {
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start();
|
||||
this.constructed = new StorageImmediatelySerialized<Deck>("Constructed decks", new DeckStorage(new File(Constants.DECK_CONSTRUCTED_DIR), true), true);
|
||||
this.draft = new StorageImmediatelySerialized<DeckGroup>("Draft deck sets", new DeckGroupSerializer(new File(Constants.DECK_DRAFT_DIR)));
|
||||
this.sealed = new StorageImmediatelySerialized<DeckGroup>("Sealed deck sets", new DeckGroupSerializer(new File(Constants.DECK_SEALED_DIR)));
|
||||
this.cube = new StorageImmediatelySerialized<Deck>("Cubes", new DeckStorage(new File(Constants.DECK_CUBE_DIR)));
|
||||
this.scheme = new StorageImmediatelySerialized<Deck>("Archenemy decks", new DeckStorage(new File(Constants.DECK_SCHEME_DIR)));
|
||||
this.plane = new StorageImmediatelySerialized<Deck>("Planechase decks", new DeckStorage(new File(Constants.DECK_PLANE_DIR)));
|
||||
this.commander = new StorageImmediatelySerialized<Deck>("Commander decks", new DeckStorage(new File(Constants.DECK_COMMANDER_DIR)));
|
||||
|
||||
sw.stop();
|
||||
System.out.printf("Read decks (%d ms): %d constructed, %d sealed, %d draft, %d cubes, %d scheme, %d planar, %d commander.%n", sw.getTime(), constructed.size(), sealed.size(), draft.size(), cube.size(), scheme.size(), plane.size(),commander.size());
|
||||
// int sum = constructed.size() + sealed.size() + draft.size() + cube.size() + scheme.size() + plane.size();
|
||||
// FSkin.setProgessBarMessage(String.format("Loaded %d decks in %f sec", sum, sw.getTime() / 1000f ));
|
||||
// remove this after most people have been switched to new layout
|
||||
final OldDeckParser oldParser = new OldDeckParser(this.constructed, this.draft, this.sealed, this.cube);
|
||||
oldParser.tryParse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constructed.
|
||||
*
|
||||
* @return the constructed
|
||||
*/
|
||||
public final IStorage<Deck> getConstructed() {
|
||||
return this.constructed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the draft.
|
||||
*
|
||||
* @return the draft
|
||||
*/
|
||||
public final IStorage<DeckGroup> getDraft() {
|
||||
return this.draft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cubes.
|
||||
*
|
||||
* @return the cubes
|
||||
*/
|
||||
public final IStorage<Deck> getCubes() {
|
||||
return this.cube;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sealed.
|
||||
*
|
||||
* @return the sealed
|
||||
*/
|
||||
public IStorage<DeckGroup> getSealed() {
|
||||
return this.sealed;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @return
|
||||
*/
|
||||
public IStorage<Deck> getScheme() {
|
||||
return this.scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the plane
|
||||
*/
|
||||
public IStorage<Deck> getPlane() {
|
||||
return plane;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the plane
|
||||
*/
|
||||
public IStorage<Deck> getCommander() {
|
||||
return commander;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,8 @@ import forge.game.GameFormat;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.toolbox.FProgressBar;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.storage.IStorage;
|
||||
import forge.util.storage.StorageBase;
|
||||
import forge.utils.Constants;
|
||||
import forge.utils.ForgePreferences;
|
||||
|
||||
@@ -53,15 +55,15 @@ public class FModel {
|
||||
private static ForgePreferences preferences;
|
||||
|
||||
// Someone should take care of 2 gauntlets here
|
||||
/*private static GauntletData gauntletData;
|
||||
private static GauntletMini gauntlet;
|
||||
//private static GauntletData gauntletData;
|
||||
//private static GauntletMini gauntlet;
|
||||
|
||||
private static QuestController quest;
|
||||
//private static QuestController quest;
|
||||
private static CardCollections decks;
|
||||
|
||||
private static IStorage<CardBlock> blocks;
|
||||
private static IStorage<CardBlock> fantasyBlocks;
|
||||
private static IStorage<QuestWorld> worlds;*/
|
||||
//private static IStorage<QuestWorld> worlds;
|
||||
private static GameFormat.Collection formats;
|
||||
|
||||
public static void initialize(final FProgressBar progressBar) {
|
||||
@@ -138,18 +140,18 @@ public class FModel {
|
||||
}
|
||||
|
||||
formats = new GameFormat.Collection(new GameFormat.Reader(new File(Constants.BLOCK_DATA_DIR + "formats.txt")));
|
||||
/*blocks = new StorageBase<CardBlock>("Block definitions", new CardBlock.Reader(Constants.BLOCK_DATA_DIR + "blocks.txt", magicDb.getEditions()));
|
||||
questPreferences = new QuestPreferences();
|
||||
gauntletData = new GauntletData();
|
||||
blocks = new StorageBase<CardBlock>("Block definitions", new CardBlock.Reader(Constants.BLOCK_DATA_DIR + "blocks.txt", magicDb.getEditions()));
|
||||
//questPreferences = new QuestPreferences();
|
||||
//gauntletData = new GauntletData();
|
||||
fantasyBlocks = new StorageBase<CardBlock>("Custom blocks", new CardBlock.Reader(Constants.BLOCK_DATA_DIR + "fantasyblocks.txt", magicDb.getEditions()));
|
||||
worlds = new StorageBase<QuestWorld>("Quest worlds", new QuestWorld.Reader(Constants.QUEST_WORLD_DIR + "worlds.txt"));*/
|
||||
//worlds = new StorageBase<QuestWorld>("Quest worlds", new QuestWorld.Reader(Constants.QUEST_WORLD_DIR + "worlds.txt"));
|
||||
|
||||
loadDynamicGamedata();
|
||||
|
||||
progressBar.setDescription("Loading decks");
|
||||
|
||||
/*decks = new CardCollections();
|
||||
quest = new QuestController();*/
|
||||
decks = new CardCollections();
|
||||
//quest = new QuestController();
|
||||
|
||||
//preload AI profiles
|
||||
AiProfileUtil.loadAllProfiles(Constants.AI_PROFILE_DIR);
|
||||
@@ -272,23 +274,23 @@ public class FModel {
|
||||
return preferences;
|
||||
}
|
||||
|
||||
/*public static IStorage<CardBlock> getBlocks() {
|
||||
public static IStorage<CardBlock> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
public static QuestPreferences getQuestPreferences() {
|
||||
/*public static QuestPreferences getQuestPreferences() {
|
||||
return questPreferences;
|
||||
}
|
||||
|
||||
public static GauntletData getGauntletData() {
|
||||
return gauntletData;
|
||||
}
|
||||
}*/
|
||||
|
||||
public static CardCollections getDecks() {
|
||||
return decks;
|
||||
}
|
||||
|
||||
public static IStorage<QuestWorld> getWorlds() {
|
||||
/*public static IStorage<QuestWorld> getWorlds() {
|
||||
return worlds;
|
||||
}*/
|
||||
|
||||
@@ -296,6 +298,10 @@ public class FModel {
|
||||
return formats;
|
||||
}
|
||||
|
||||
public static IStorage<CardBlock> getFantasyBlocks() {
|
||||
return fantasyBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizer, generally should be avoided, but here closes the log file
|
||||
* stream and resets the system output streams.
|
||||
@@ -308,13 +314,9 @@ public class FModel {
|
||||
|
||||
/*public static void setGauntletData(GauntletData data0) {
|
||||
gauntletData = data0;
|
||||
}
|
||||
}*/
|
||||
|
||||
public static IStorage<CardBlock> getFantasyBlocks() {
|
||||
return fantasyBlocks;
|
||||
}
|
||||
|
||||
public static GauntletMini getGauntletMini() {
|
||||
/*public static GauntletMini getGauntletMini() {
|
||||
if (gauntlet == null) {
|
||||
gauntlet = new GauntletMini();
|
||||
}
|
||||
|
||||
214
forge-m-base/src/forge/model/MetaSet.java
Normal file
214
forge-m-base/src/forge/model/MetaSet.java
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import forge.card.IUnOpenedProduct;
|
||||
import forge.card.UnOpenedProduct;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.limited.CustomLimited;
|
||||
import forge.util.FileUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The class MetaSet. This class is used to define 'special'
|
||||
* sets within a (fantasy) block, like custom sets (cubes),
|
||||
* combination sets (sub-blocks), and full cardpool.
|
||||
*
|
||||
* NOTE: The format of a MetaSet definition is as follows
|
||||
* (in a blocks definition file):
|
||||
*
|
||||
* "metaX A/B/C"
|
||||
*
|
||||
* where "X" is an integer from 0...8 (just like for sets)
|
||||
*
|
||||
* "A" is either "cube", "meta", "full", "choose1", "random1",
|
||||
* "set", "pack", or "combo".
|
||||
*
|
||||
* "full" uses all available cards for this booster, just like
|
||||
* the full cardpool option. The values of "B" and "C" are not
|
||||
* relevant ("B" is not used at all, and the displayed name is
|
||||
* always "*FULL").
|
||||
*
|
||||
* "meta" uses a cardpool that is combined from several
|
||||
* editions. The parameter "B" is a list of 3-letter
|
||||
* edition codes, separated with commas, e.g.
|
||||
* "2ED,ARN,ATQ". The parameter "C" is the name
|
||||
* that is displayed for this meta-booster in the
|
||||
* set selection menu.
|
||||
*
|
||||
* "cube" uses a previously defined custom sealed deck
|
||||
* deck cube as the cardpool for this booster. The cube
|
||||
* definition file must be in res/sealed/ and have a
|
||||
* ".sealed" extension. The related .dck file must be
|
||||
* in the res/decks/cube directory.
|
||||
* "B" is the name of the cube definition file without
|
||||
* the ".sealed" extension, e.g. "juzamjedi".
|
||||
* "C" is the name that is displayed for this meta-booster
|
||||
* in the set selection menu.
|
||||
*
|
||||
* The new types added after beta 1.2.14:
|
||||
*
|
||||
* "choose1": define several metasets in a semicolon-separated (;)
|
||||
* list in value B, the player will choose one of them.
|
||||
*
|
||||
* "random1": like choose1, except that the player will get a
|
||||
* random pack.
|
||||
*
|
||||
* "combo": define several metasets in a semicolon-separated (;)
|
||||
* list in value B, the booster will be based on the combined
|
||||
* cardpool of all these. Note that if one of the metasets is
|
||||
* a "full", the rest are irrelevant.
|
||||
*
|
||||
* "booster": generate a single booster based on value B set. (You
|
||||
* should use this only for combo, choose1 and random1 metasets,
|
||||
* otherwise use normal Sets instead of MetaSets in the block
|
||||
* definition!)
|
||||
*
|
||||
* "pack": like set, but attempts to generate a starter pack instead
|
||||
* of a booster. If starter packs are not available for value B set,
|
||||
* a booster is generated instead.
|
||||
*
|
||||
*/
|
||||
public class MetaSet {
|
||||
|
||||
private enum MetaSetType {
|
||||
Full("F", "All cards"),
|
||||
Cube("C", "Cube"),
|
||||
JoinedSet("J", "Joined set"),
|
||||
Choose("Select", "Choose from list"),
|
||||
Combo("All", "Combined booster"),
|
||||
Random("Any", "Randomly selected"),
|
||||
Booster("B", "Booster"),
|
||||
SpecialBooster("S", "Special Booster"),
|
||||
Pack("T", "Tournament/Starter");
|
||||
|
||||
private final String shortHand;
|
||||
public final String descriptiveName;
|
||||
private MetaSetType(String shortname, String descName) {
|
||||
shortHand = shortname;
|
||||
descriptiveName = descName;
|
||||
}
|
||||
|
||||
public static MetaSetType smartValueOf(String trim) {
|
||||
for(MetaSetType mt : MetaSetType.values()) {
|
||||
if( mt.name().equalsIgnoreCase(trim) || mt.shortHand.equalsIgnoreCase(trim))
|
||||
return mt;
|
||||
}
|
||||
throw new IllegalArgumentException(trim + " not recognized as Meta Set");
|
||||
}
|
||||
}
|
||||
|
||||
private final MetaSetType type;
|
||||
private final String data;
|
||||
private final String code;
|
||||
private final boolean draftable;
|
||||
// private BoosterGenerator boosterGen;
|
||||
|
||||
/**
|
||||
* The constructor. A new MetaSet is currently only instantiated in CardBlock.java
|
||||
* when CardBlock information is read.
|
||||
*
|
||||
* @param creationString
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
public MetaSet(final String creationString, boolean canDraft) {
|
||||
int idxFirstPar = creationString.indexOf('(');
|
||||
int idxLastPar = creationString.lastIndexOf(')');
|
||||
|
||||
draftable = canDraft;
|
||||
type = MetaSetType.smartValueOf(creationString.substring(0, idxFirstPar).trim());
|
||||
data = creationString.substring(idxFirstPar + 1, idxLastPar);
|
||||
String description = creationString.substring(idxLastPar + 1);
|
||||
code = description + "\u00A0(" + type.descriptiveName + ")"; // u00A0 (nbsp) will not be equal to simple space
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the code.
|
||||
*
|
||||
* @return
|
||||
* String, code
|
||||
*/
|
||||
public final String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Attempt to get a booster.
|
||||
*
|
||||
* @return UnOpenedProduct, the generated booster.
|
||||
*/
|
||||
public IUnOpenedProduct getBooster() {
|
||||
|
||||
switch(type) {
|
||||
case Full:
|
||||
return new UnOpenedProduct(SealedProduct.Template.genericBooster);
|
||||
|
||||
case Booster:
|
||||
return new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(data));
|
||||
|
||||
case SpecialBooster:
|
||||
return new UnOpenedProduct(FModel.getMagicDb().getSpecialBoosters().get(data));
|
||||
|
||||
case Pack:
|
||||
return new UnOpenedProduct(FModel.getMagicDb().getTournamentPacks().get(data));
|
||||
|
||||
case JoinedSet:
|
||||
Predicate<PaperCard> predicate = IPaperCard.Predicates.printedInSets(data.split(" "));
|
||||
return new UnOpenedProduct(SealedProduct.Template.genericBooster, predicate);
|
||||
|
||||
case Choose: return UnOpenedMeta.choose(data);
|
||||
case Random: return UnOpenedMeta.random(data);
|
||||
case Combo: return UnOpenedMeta.selectAll(data);
|
||||
|
||||
case Cube:
|
||||
final File dFolder = new File("res/sealed/");
|
||||
|
||||
if (!dFolder.exists()) {
|
||||
throw new RuntimeException("GenerateSealed : folder not found -- folder is " + dFolder.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (!dFolder.isDirectory()) {
|
||||
throw new RuntimeException("GenerateSealed : not a folder -- " + dFolder.getAbsolutePath());
|
||||
}
|
||||
|
||||
List<String> dfData = FileUtil.readFile("res/sealed/" + data + ".sealed");
|
||||
final CustomLimited myCube = CustomLimited.parse(dfData, FModel.getDecks().getCubes());
|
||||
|
||||
SealedProduct.Template fnPick = myCube.getSealedProductTemplate();
|
||||
return new UnOpenedProduct(fnPick, myCube.getCardPool());
|
||||
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public boolean isDraftable() {
|
||||
return draftable;
|
||||
}
|
||||
}
|
||||
126
forge-m-base/src/forge/model/UnOpenedMeta.java
Normal file
126
forge-m-base/src/forge/model/UnOpenedMeta.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import forge.card.IUnOpenedProduct;
|
||||
import forge.item.PaperCard;
|
||||
import forge.toolbox.GuiChoose;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* This type extends UnOpenedProduct to support booster choice or random boosters
|
||||
* in sealed deck games. See MetaSet.java for further information.
|
||||
*/
|
||||
|
||||
public class UnOpenedMeta implements IUnOpenedProduct {
|
||||
|
||||
private enum JoinOperation {
|
||||
RandomOne,
|
||||
ChooseOne,
|
||||
SelectAll,
|
||||
}
|
||||
|
||||
private final ArrayList<MetaSet> metaSets;
|
||||
private final JoinOperation operation;
|
||||
private final Random generator = MyRandom.getRandom();
|
||||
|
||||
/**
|
||||
* Constructor for UnOpenedMeta.
|
||||
* @param creationString
|
||||
* String, is parsed for MetaSet info.
|
||||
* @param choose
|
||||
* sets the random/choice status.
|
||||
*/
|
||||
private UnOpenedMeta(final String creationString, final JoinOperation op) {
|
||||
metaSets = new ArrayList<MetaSet>();
|
||||
operation = op;
|
||||
|
||||
for (String m : TextUtil.splitWithParenthesis(creationString, ';')) {
|
||||
metaSets.add(new MetaSet(m, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the booster pack, return contents.
|
||||
* @return List, list of cards.
|
||||
*/
|
||||
@Override
|
||||
public List<PaperCard> get() {
|
||||
return this.open(true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like open, can define whether is human or not.
|
||||
* @param isHuman
|
||||
* boolean, is human player?
|
||||
* @param partialities
|
||||
* known partialities for the AI.
|
||||
* @return List, list of cards.
|
||||
*/
|
||||
public List<PaperCard> open(final boolean isHuman, final boolean allowCancel) {
|
||||
if (metaSets.isEmpty()) {
|
||||
throw new RuntimeException("Empty UnOpenedMetaset, cannot generate booster.");
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case ChooseOne:
|
||||
if (isHuman) {
|
||||
final MetaSet ms;
|
||||
if (allowCancel) {
|
||||
ms = GuiChoose.oneOrNone("Choose Booster", metaSets);
|
||||
if (ms == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ms = GuiChoose.one("Choose Booster", metaSets);
|
||||
}
|
||||
return ms.getBooster().get();
|
||||
}
|
||||
|
||||
case RandomOne: // AI should fall though here from the case above
|
||||
int selected = generator.nextInt(metaSets.size());
|
||||
final IUnOpenedProduct newBooster = metaSets.get(selected).getBooster();
|
||||
return newBooster.get();
|
||||
|
||||
case SelectAll:
|
||||
List<PaperCard> allCards = new ArrayList<PaperCard>();
|
||||
for (MetaSet ms : metaSets) {
|
||||
allCards.addAll(ms.getBooster().get());
|
||||
}
|
||||
return allCards;
|
||||
}
|
||||
throw new IllegalStateException("Got wrong operation type in unopenedMeta - execution should never reach this point");
|
||||
}
|
||||
|
||||
public static UnOpenedMeta choose(String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.ChooseOne);
|
||||
}
|
||||
public static UnOpenedMeta random(String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.RandomOne);
|
||||
}
|
||||
public static UnOpenedMeta selectAll(String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.SelectAll);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package forge.player;
|
||||
|
||||
import forge.ai.PlayerControllerAi;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.model.FModel;
|
||||
import forge.utils.ForgePreferences.FPref;
|
||||
|
||||
public class LobbyPlayerHuman extends LobbyPlayer {
|
||||
public LobbyPlayerHuman(String name) {
|
||||
@@ -18,17 +19,18 @@ public class LobbyPlayerHuman extends LobbyPlayer {
|
||||
|
||||
@Override
|
||||
public PlayerController createControllerFor(Player human) {
|
||||
return new PlayerControllerAi(human.getGame(), human, this); //TODO new PlayerControllerHuman(human.getGame(), human, this);
|
||||
return new PlayerControllerHuman(human.getGame(), human, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player createIngamePlayer(Game game) { //TODO
|
||||
Player player = new Player(/*GuiDisplayUtil.personalizeHuman(*/getName()/*)*/, game);
|
||||
player.setFirstController(new PlayerControllerAi(game, player, this)/*new PlayerControllerHuman(game, player, this)*/);
|
||||
player.setFirstController(new PlayerControllerHuman(game, player, this));
|
||||
|
||||
/*if (ForgePreferences.DEV_MODE && Singletons.getModel().getPreferences().getPrefBoolean(FPref.DEV_UNLIMITED_LAND)) {
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.DEV_MODE_ENABLED) &&
|
||||
FModel.getPreferences().getPrefBoolean(FPref.DEV_UNLIMITED_LAND)) {
|
||||
player.canCheatPlayUnlimitedLands = true;
|
||||
}*/
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
package forge.player;
|
||||
|
||||
/*import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostShard;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.GameType;
|
||||
import forge.game.ability.effects.CharmEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardShields;
|
||||
import forge.game.card.CounterType;
|
||||
@@ -23,7 +19,6 @@ import forge.game.cost.Cost;
|
||||
import forge.game.cost.CostPart;
|
||||
import forge.game.cost.CostPartMana;
|
||||
import forge.game.mana.Mana;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
@@ -35,25 +30,20 @@ import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.trigger.WrappedAbility;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.Lang;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
*//**
|
||||
/**
|
||||
* A prototype for player controller class
|
||||
*
|
||||
* Handles phase skips for now.
|
||||
*//*
|
||||
*/
|
||||
public class PlayerControllerHuman extends PlayerController {
|
||||
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp) {
|
||||
super(game0, p, lp);
|
||||
@@ -523,4 +513,4 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
346
forge-m-base/src/forge/toolbox/GuiChoose.java
Normal file
346
forge-m-base/src/forge/toolbox/GuiChoose.java
Normal file
@@ -0,0 +1,346 @@
|
||||
package forge.toolbox;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class GuiChoose {
|
||||
|
||||
/**
|
||||
* Convenience for getChoices(message, 0, 1, choices).
|
||||
*
|
||||
* @param <T>
|
||||
* is automatically inferred.
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @param choices
|
||||
* a T object.
|
||||
* @return null if choices is missing, empty, or if the users' choices are
|
||||
* empty; otherwise, returns the first item in the List returned by
|
||||
* getChoices.
|
||||
* @see #getChoices(String, int, int, Object...)
|
||||
*/
|
||||
public static <T> T oneOrNone(final String message, final T[] choices) {
|
||||
if ((choices == null) || (choices.length == 0)) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = GuiChoose.getChoices(message, 0, 1, choices);
|
||||
return choice.isEmpty() ? null : choice.get(0);
|
||||
} // getChoiceOptional(String,T...)
|
||||
|
||||
public static <T> T oneOrNone(final String message, final Collection<T> choices) {
|
||||
if ((choices == null) || choices.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = GuiChoose.getChoices(message, 0, 1, choices);
|
||||
return choice.isEmpty() ? null : choice.get(0);
|
||||
} // getChoiceOptional(String,T...)
|
||||
|
||||
// returned Object will never be null
|
||||
/**
|
||||
* <p>
|
||||
* getChoice.
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* a T object.
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @param choices
|
||||
* a T object.
|
||||
* @return a T object.
|
||||
*/
|
||||
public static <T> T one(final String message, final T[] choices) {
|
||||
final List<T> choice = GuiChoose.getChoices(message, 1, 1, choices);
|
||||
assert choice.size() == 1;
|
||||
return choice.get(0);
|
||||
}
|
||||
|
||||
public static <T> T one(final String message, final Collection<T> choices) {
|
||||
if (choices == null || choices.isEmpty())
|
||||
return null;
|
||||
if( choices.size() == 1)
|
||||
return Iterables.getFirst(choices, null);
|
||||
|
||||
final List<T> choice = GuiChoose.getChoices(message, 1, 1, choices);
|
||||
assert choice.size() == 1;
|
||||
return choice.get(0);
|
||||
}
|
||||
|
||||
public static <T> List<T> noneOrMany(final String message, final Collection<T> choices) {
|
||||
return GuiChoose.getChoices(message, 0, choices.size(), choices, null, null);
|
||||
}
|
||||
|
||||
// Nothing to choose here. Code uses this to just reveal one or more items
|
||||
public static <T> void reveal(final String message, final T item) {
|
||||
List<T> items = new ArrayList<T>();
|
||||
items.add(item);
|
||||
reveal(message, items);
|
||||
}
|
||||
public static <T> void reveal(final String message, final T[] items) {
|
||||
GuiChoose.getChoices(message, -1, -1, items);
|
||||
}
|
||||
public static <T> void reveal(final String message, final Collection<T> items) {
|
||||
GuiChoose.getChoices(message, -1, -1, items);
|
||||
}
|
||||
|
||||
// Get Integer in range
|
||||
public static Integer getInteger(final String message) {
|
||||
return getInteger(message, 0, Integer.MAX_VALUE);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min) {
|
||||
return getInteger(message, min, Integer.MAX_VALUE);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max) {
|
||||
if (max <= min) { return min; } //just return min if max <= min
|
||||
|
||||
//force cutting off after 100 numbers at most
|
||||
if (max == Integer.MAX_VALUE) {
|
||||
return getInteger(message, min, max, min + 99);
|
||||
}
|
||||
int count = max - min + 1;
|
||||
if (count > 100) {
|
||||
return getInteger(message, min, max, min + 99);
|
||||
}
|
||||
|
||||
final Integer[] choices = new Integer[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
choices[i] = Integer.valueOf(i + min);
|
||||
}
|
||||
return GuiChoose.oneOrNone(message, choices);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max, int cutoff) {
|
||||
if (max <= min || cutoff < min) { return min; } //just return min if max <= min or cutoff < min
|
||||
|
||||
if (cutoff >= max) { //fallback to regular integer prompt if cutoff at or after max
|
||||
return getInteger(message, min, max);
|
||||
}
|
||||
|
||||
List<Object> choices = new ArrayList<Object>();
|
||||
for (int i = min; i <= cutoff; i++) {
|
||||
choices.add(Integer.valueOf(i));
|
||||
}
|
||||
choices.add("Other...");
|
||||
|
||||
Object choice = GuiChoose.oneOrNone(message, choices);
|
||||
if (choice instanceof Integer || choice == null) {
|
||||
return (Integer)choice;
|
||||
}
|
||||
|
||||
//if Other option picked, prompt for number input
|
||||
String prompt = "Enter a number";
|
||||
if (min != Integer.MIN_VALUE) {
|
||||
if (max != Integer.MAX_VALUE) {
|
||||
prompt += " between " + min + " and " + max;
|
||||
}
|
||||
else {
|
||||
prompt += " greater than or equal to " + min;
|
||||
}
|
||||
}
|
||||
else if (max != Integer.MAX_VALUE) {
|
||||
prompt += " less than or equal to " + max;
|
||||
}
|
||||
prompt += ":";
|
||||
|
||||
while (true) {
|
||||
String str = FOptionPane.showInputDialog(prompt, message);
|
||||
if (str == null) { return null; } // that is 'cancel'
|
||||
|
||||
if (StringUtils.isNumeric(str)) {
|
||||
Integer val = Integer.valueOf(str);
|
||||
if (val >= min && val <= max) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returned Object will never be null
|
||||
public static <T> List<T> getChoices(final String message, final int min, final int max, final T[] choices) {
|
||||
return getChoices(message, min, max, Arrays.asList(choices), null, null);
|
||||
}
|
||||
|
||||
public static <T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices) {
|
||||
return getChoices(message, min, max, choices, null, null);
|
||||
}
|
||||
|
||||
public static <T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display) {
|
||||
/*if (choices == null || choices.isEmpty()) {
|
||||
if (min == 0) {
|
||||
return new ArrayList<T>();
|
||||
}
|
||||
throw new RuntimeException("choice required from empty list");
|
||||
}
|
||||
|
||||
Callable<List<T>> showChoice = new Callable<List<T>>() {
|
||||
@Override
|
||||
public List<T> call() {
|
||||
ListChooser<T> c = new ListChooser<T>(message, min, max, choices, display);
|
||||
final JList<T> list = c.getLstChoices();
|
||||
list.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(final ListSelectionEvent ev) {
|
||||
if (list.getSelectedValue() instanceof Card) {
|
||||
Card card = (Card) list.getSelectedValue();
|
||||
if (card.isFaceDown() && FControl.mayShowCard(card)) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(card, true);
|
||||
}
|
||||
else {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(card);
|
||||
}
|
||||
|
||||
GuiUtils.clearPanelSelections();
|
||||
GuiUtils.setPanelSelection(card);
|
||||
}
|
||||
if (list.getSelectedValue() instanceof InventoryItem) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard((InventoryItem) list.getSelectedValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (selected != null) {
|
||||
c.show(selected);
|
||||
}
|
||||
else {
|
||||
c.show();
|
||||
}
|
||||
|
||||
GuiUtils.clearPanelSelections();
|
||||
return c.getSelectedValues();
|
||||
}
|
||||
};
|
||||
|
||||
FutureTask<List<T>> future = new FutureTask<List<T>>(showChoice);
|
||||
FThreads.invokeInEdtAndWait(future);
|
||||
try {
|
||||
return future.get();
|
||||
} catch (Exception e) { // should be no exception here
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices, Card referenceCard) {
|
||||
return order(title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, Card referenceCard) {
|
||||
int m2 = min >= 0 ? sourceChoices.size() - min : -1;
|
||||
int m1 = max >= 0 ? sourceChoices.size() - max : -1;
|
||||
return order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> order(final String title, final String top, final List<T> sourceChoices, Card referenceCard) {
|
||||
return order(title, top, 0, 0, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T extends Comparable<? super T>> List<T> sideboard(List<T> sideboard, List<T> deck) {
|
||||
Collections.sort(deck);
|
||||
Collections.sort(sideboard);
|
||||
return order("Sideboard", "Main Deck", -1, -1, sideboard, deck, null, true);
|
||||
}
|
||||
|
||||
private static <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode) {
|
||||
// An input box for handling the order of choices.
|
||||
|
||||
/*Callable<List<T>> callable = new Callable<List<T>>() {
|
||||
@Override
|
||||
public List<T> call() throws Exception {
|
||||
DualListBox<T> dual = new DualListBox<T>(remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices);
|
||||
dual.setSecondColumnLabelText(top);
|
||||
|
||||
dual.setSideboardMode(sideboardingMode);
|
||||
|
||||
dual.setTitle(title);
|
||||
dual.pack();
|
||||
dual.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
if (referenceCard != null) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(referenceCard);
|
||||
// MARKED FOR UPDATE
|
||||
}
|
||||
dual.setVisible(true);
|
||||
|
||||
List<T> objects = dual.getOrderedList();
|
||||
|
||||
dual.dispose();
|
||||
GuiUtils.clearPanelSelections();
|
||||
return objects;
|
||||
}
|
||||
};
|
||||
|
||||
FutureTask<List<T>> ft = new FutureTask<List<T>>(callable);
|
||||
FThreads.invokeInEdtAndWait(ft);
|
||||
try {
|
||||
return ft.get();
|
||||
} catch (Exception e) { // we have waited enough
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> T sortedOneOrNone(final String message, final T[] choices, Comparator<T> comparer) {
|
||||
if ((choices == null) || (choices.length == 0)) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = GuiChoose.sortedGetChoices(message, 0, 1, choices, comparer);
|
||||
return choice.isEmpty() ? null : choice.get(0);
|
||||
} // getChoiceOptional(String,T...)
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> T sortedOneOrNone(final String message, final List<T> choices, Comparator<T> comparer) {
|
||||
if ((choices == null) || choices.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = GuiChoose.sortedGetChoices(message, 0, 1, choices, comparer);
|
||||
return choice.isEmpty() ? null : choice.get(0);
|
||||
} // getChoiceOptional(String,T...)
|
||||
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> T sortedOne(final String message, final T[] choices, Comparator<T> comparer) {
|
||||
final List<T> choice = GuiChoose.sortedGetChoices(message, 1, 1, choices, comparer);
|
||||
assert choice.size() == 1;
|
||||
return choice.get(0);
|
||||
} // getChoice()
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> T sortedOne(final String message, final List<T> choices, Comparator<T> comparer) {
|
||||
if ((choices == null) || (choices.size() == 0)) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = GuiChoose.sortedGetChoices(message, 1, 1, choices, comparer);
|
||||
assert choice.size() == 1;
|
||||
return choice.get(0);
|
||||
}
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> List<T> sortedNoneOrMany(final String message, final List<T> choices, Comparator<T> comparer) {
|
||||
return GuiChoose.sortedGetChoices(message, 0, choices.size(), choices, comparer);
|
||||
}
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> List<T> sortedGetChoices(final String message, final int min, final int max, final T[] choices, Comparator<T> comparer) {
|
||||
// You may create a copy of source array if callers expect the collection to be unchanged
|
||||
Arrays.sort(choices, comparer);
|
||||
return getChoices(message, min, max, choices);
|
||||
}
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> List<T> sortedGetChoices(final String message, final int min, final int max, final List<T> choices, Comparator<T> comparer) {
|
||||
// You may create a copy of source list if callers expect the collection to be unchanged
|
||||
Collections.sort(choices, comparer);
|
||||
return getChoices(message, min, max, choices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user