mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48: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/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/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/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/DeckSerializer.java -text
|
||||||
forge-core/src/main/java/forge/deck/io/DeckStorage.java -text
|
forge-core/src/main/java/forge/deck/io/DeckStorage.java -text
|
||||||
forge-core/src/main/java/forge/deck/io/OldDeckFileFormatException.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/KeyboardShortcuts.java -text
|
||||||
forge-gui/src/main/java/forge/control/RestartUtil.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/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/DeckHtmlSerializer.java -text
|
||||||
forge-gui/src/main/java/forge/deck/io/DeckPreferences.java -text
|
forge-gui/src/main/java/forge/deck/io/DeckPreferences.java -text
|
||||||
forge-gui/src/main/java/forge/deck/io/OldDeckParser.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/FTextureImage.java -text
|
||||||
forge-m-base/src/forge/assets/ImageCache.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/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/BugReporter.java -text
|
||||||
forge-m-base/src/forge/error/ExceptionHandler.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/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/LobbyPlayerHuman.java -text
|
||||||
forge-m-base/src/forge/player/PlayerControllerHuman.java -text
|
forge-m-base/src/forge/player/PlayerControllerHuman.java -text
|
||||||
forge-m-base/src/forge/screens/FScreen.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/FOverlay.java -text
|
||||||
forge-m-base/src/forge/toolbox/FProgressBar.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/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/Constants.java -text
|
||||||
forge-m-base/src/forge/utils/ForgePreferences.java -text
|
forge-m-base/src/forge/utils/ForgePreferences.java -text
|
||||||
forge-m-base/src/forge/utils/ForgeProfileProperties.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.game.card.CardUtil;
|
||||||
import forge.toolbox.FProgressBar;
|
import forge.toolbox.FProgressBar;
|
||||||
import forge.util.FileUtil;
|
import forge.util.FileUtil;
|
||||||
|
import forge.util.storage.IStorage;
|
||||||
|
import forge.util.storage.StorageBase;
|
||||||
import forge.utils.Constants;
|
import forge.utils.Constants;
|
||||||
import forge.utils.ForgePreferences;
|
import forge.utils.ForgePreferences;
|
||||||
|
|
||||||
@@ -53,15 +55,15 @@ public class FModel {
|
|||||||
private static ForgePreferences preferences;
|
private static ForgePreferences preferences;
|
||||||
|
|
||||||
// Someone should take care of 2 gauntlets here
|
// Someone should take care of 2 gauntlets here
|
||||||
/*private static GauntletData gauntletData;
|
//private static GauntletData gauntletData;
|
||||||
private static GauntletMini gauntlet;
|
//private static GauntletMini gauntlet;
|
||||||
|
|
||||||
private static QuestController quest;
|
//private static QuestController quest;
|
||||||
private static CardCollections decks;
|
private static CardCollections decks;
|
||||||
|
|
||||||
private static IStorage<CardBlock> blocks;
|
private static IStorage<CardBlock> blocks;
|
||||||
private static IStorage<CardBlock> fantasyBlocks;
|
private static IStorage<CardBlock> fantasyBlocks;
|
||||||
private static IStorage<QuestWorld> worlds;*/
|
//private static IStorage<QuestWorld> worlds;
|
||||||
private static GameFormat.Collection formats;
|
private static GameFormat.Collection formats;
|
||||||
|
|
||||||
public static void initialize(final FProgressBar progressBar) {
|
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")));
|
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()));
|
blocks = new StorageBase<CardBlock>("Block definitions", new CardBlock.Reader(Constants.BLOCK_DATA_DIR + "blocks.txt", magicDb.getEditions()));
|
||||||
questPreferences = new QuestPreferences();
|
//questPreferences = new QuestPreferences();
|
||||||
gauntletData = new GauntletData();
|
//gauntletData = new GauntletData();
|
||||||
fantasyBlocks = new StorageBase<CardBlock>("Custom blocks", new CardBlock.Reader(Constants.BLOCK_DATA_DIR + "fantasyblocks.txt", magicDb.getEditions()));
|
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();
|
loadDynamicGamedata();
|
||||||
|
|
||||||
progressBar.setDescription("Loading decks");
|
progressBar.setDescription("Loading decks");
|
||||||
|
|
||||||
/*decks = new CardCollections();
|
decks = new CardCollections();
|
||||||
quest = new QuestController();*/
|
//quest = new QuestController();
|
||||||
|
|
||||||
//preload AI profiles
|
//preload AI profiles
|
||||||
AiProfileUtil.loadAllProfiles(Constants.AI_PROFILE_DIR);
|
AiProfileUtil.loadAllProfiles(Constants.AI_PROFILE_DIR);
|
||||||
@@ -272,23 +274,23 @@ public class FModel {
|
|||||||
return preferences;
|
return preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public static IStorage<CardBlock> getBlocks() {
|
public static IStorage<CardBlock> getBlocks() {
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static QuestPreferences getQuestPreferences() {
|
/*public static QuestPreferences getQuestPreferences() {
|
||||||
return questPreferences;
|
return questPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GauntletData getGauntletData() {
|
public static GauntletData getGauntletData() {
|
||||||
return gauntletData;
|
return gauntletData;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public static CardCollections getDecks() {
|
public static CardCollections getDecks() {
|
||||||
return decks;
|
return decks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IStorage<QuestWorld> getWorlds() {
|
/*public static IStorage<QuestWorld> getWorlds() {
|
||||||
return worlds;
|
return worlds;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
@@ -296,6 +298,10 @@ public class FModel {
|
|||||||
return formats;
|
return formats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IStorage<CardBlock> getFantasyBlocks() {
|
||||||
|
return fantasyBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalizer, generally should be avoided, but here closes the log file
|
* Finalizer, generally should be avoided, but here closes the log file
|
||||||
* stream and resets the system output streams.
|
* stream and resets the system output streams.
|
||||||
@@ -308,13 +314,9 @@ public class FModel {
|
|||||||
|
|
||||||
/*public static void setGauntletData(GauntletData data0) {
|
/*public static void setGauntletData(GauntletData data0) {
|
||||||
gauntletData = data0;
|
gauntletData = data0;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public static IStorage<CardBlock> getFantasyBlocks() {
|
/*public static GauntletMini getGauntletMini() {
|
||||||
return fantasyBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GauntletMini getGauntletMini() {
|
|
||||||
if (gauntlet == null) {
|
if (gauntlet == null) {
|
||||||
gauntlet = new GauntletMini();
|
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;
|
package forge.player;
|
||||||
|
|
||||||
import forge.ai.PlayerControllerAi;
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerController;
|
import forge.game.player.PlayerController;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.utils.ForgePreferences.FPref;
|
||||||
|
|
||||||
public class LobbyPlayerHuman extends LobbyPlayer {
|
public class LobbyPlayerHuman extends LobbyPlayer {
|
||||||
public LobbyPlayerHuman(String name) {
|
public LobbyPlayerHuman(String name) {
|
||||||
@@ -18,17 +19,18 @@ public class LobbyPlayerHuman extends LobbyPlayer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlayerController createControllerFor(Player human) {
|
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
|
@Override
|
||||||
public Player createIngamePlayer(Game game) { //TODO
|
public Player createIngamePlayer(Game game) { //TODO
|
||||||
Player player = new Player(/*GuiDisplayUtil.personalizeHuman(*/getName()/*)*/, game);
|
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;
|
player.canCheatPlayUnlimitedLands = true;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
package forge.player;
|
package forge.player;
|
||||||
|
|
||||||
/*import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.deck.CardPool;
|
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckSection;
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
import forge.game.GameObject;
|
import forge.game.GameObject;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.game.ability.effects.CharmEffect;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardShields;
|
import forge.game.card.CardShields;
|
||||||
import forge.game.card.CounterType;
|
import forge.game.card.CounterType;
|
||||||
@@ -23,7 +19,6 @@ import forge.game.cost.Cost;
|
|||||||
import forge.game.cost.CostPart;
|
import forge.game.cost.CostPart;
|
||||||
import forge.game.cost.CostPartMana;
|
import forge.game.cost.CostPartMana;
|
||||||
import forge.game.mana.Mana;
|
import forge.game.mana.Mana;
|
||||||
import forge.game.phase.PhaseType;
|
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerActionConfirmMode;
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
@@ -35,25 +30,20 @@ import forge.game.spellability.SpellAbilityStackInstance;
|
|||||||
import forge.game.spellability.TargetChoices;
|
import forge.game.spellability.TargetChoices;
|
||||||
import forge.game.trigger.Trigger;
|
import forge.game.trigger.Trigger;
|
||||||
import forge.game.trigger.WrappedAbility;
|
import forge.game.trigger.WrappedAbility;
|
||||||
import forge.game.zone.Zone;
|
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.item.PaperCard;
|
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.ImmutablePair;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
*//**
|
/**
|
||||||
* A prototype for player controller class
|
* A prototype for player controller class
|
||||||
*
|
*
|
||||||
* Handles phase skips for now.
|
* Handles phase skips for now.
|
||||||
*//*
|
*/
|
||||||
public class PlayerControllerHuman extends PlayerController {
|
public class PlayerControllerHuman extends PlayerController {
|
||||||
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp) {
|
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp) {
|
||||||
super(game0, p, lp);
|
super(game0, p, lp);
|
||||||
@@ -523,4 +513,4 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
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