mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Huge cleanup of gui and desktop code
- Remove lots of unused classes and methods - Remove code related to transitioning deck format - Refactor some interface structures - General cleanup (imports, indentation etc.) thanks to Eclipse - Some very minor bugfixes
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
package forge;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import forge.util.ThreadUtil;
|
||||
|
||||
public class FThreads {
|
||||
@@ -10,15 +8,15 @@ public class FThreads {
|
||||
/** Checks if calling method uses event dispatch thread.
|
||||
* Exception thrown if method is on "wrong" thread.
|
||||
* A boolean is passed to indicate if the method must be EDT or not.
|
||||
*
|
||||
*
|
||||
* @param methodName   String, part of the custom exception message.
|
||||
* @param mustBeEDT   boolean: true = exception if not EDT, false = exception if EDT
|
||||
*/
|
||||
public static void assertExecutedByEdt(final boolean mustBeEDT) {
|
||||
if (isGuiThread() != mustBeEDT) {
|
||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
final StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
final String methodName = trace[2].getClassName() + "." + trace[2].getMethodName();
|
||||
String modalOperator = mustBeEDT ? " must be" : " may not be";
|
||||
final String modalOperator = mustBeEDT ? " must be" : " may not be";
|
||||
throw new IllegalStateException(methodName + modalOperator + " accessed from the event dispatch thread.");
|
||||
}
|
||||
}
|
||||
@@ -40,10 +38,10 @@ public class FThreads {
|
||||
* Invoke the given Runnable in an Event Dispatch Thread and wait for it to
|
||||
* finish; but <B>try to use SwingUtilities.invokeLater instead whenever
|
||||
* feasible.</B>
|
||||
*
|
||||
*
|
||||
* Exceptions generated by SwingUtilities.invokeAndWait (if used), are
|
||||
* rethrown as RuntimeExceptions.
|
||||
*
|
||||
*
|
||||
* @param proc
|
||||
* the Runnable to run
|
||||
* @see fgd.SwingUtilities#invokeLater(Runnable)
|
||||
@@ -64,7 +62,7 @@ public class FThreads {
|
||||
}
|
||||
|
||||
public static void delayInEDT(final int milliseconds, final Runnable inputUpdater) {
|
||||
Runnable runInEdt = new Runnable() {
|
||||
final Runnable runInEdt = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FThreads.invokeInEdtNowOrLater(inputUpdater);
|
||||
@@ -77,23 +75,8 @@ public class FThreads {
|
||||
return isGuiThread() ? "EDT" : Thread.currentThread().getName();
|
||||
}
|
||||
|
||||
public static String prependThreadId(String message) {
|
||||
return debugGetCurrThreadId() + " > " + message;
|
||||
}
|
||||
|
||||
public static void dumpStackTrace(final PrintStream stream) {
|
||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
stream.printf("%s > %s called from %s%n", debugGetCurrThreadId(),
|
||||
trace[2].getClassName() + "." + trace[2].getMethodName(), trace[3].toString());
|
||||
int i = 0;
|
||||
for (StackTraceElement se : trace) {
|
||||
if (i<2) { i++; }
|
||||
else { stream.println(se.toString()); }
|
||||
}
|
||||
}
|
||||
|
||||
public static String debugGetStackTraceItem(final int depth, final boolean shorter) {
|
||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
final StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
String lastItem = trace[depth].toString();
|
||||
if (shorter) {
|
||||
int lastPeriod = lastItem.lastIndexOf('.');
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -21,19 +21,9 @@ package forge;
|
||||
* <p>
|
||||
* Command interface.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface UiCommand extends java.io.Serializable, Runnable {
|
||||
/** Constant <code>Blank</code>. */
|
||||
public final UiCommand BLANK = new UiCommand() {
|
||||
|
||||
private static final long serialVersionUID = 2689172297036001710L;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,15 +25,15 @@ public abstract class Achievement {
|
||||
private int best;
|
||||
|
||||
//use this constructor for special achievements without tiers
|
||||
protected Achievement(String key0, String displayName0, String description0, String flavorText0, int defaultValue0) {
|
||||
protected Achievement(final String key0, final String displayName0, final String description0, final String flavorText0, final int defaultValue0) {
|
||||
this(key0, displayName0, description0, defaultValue0, null, 1, null, 1, null, 1, "(" + flavorText0 + ")", 1); //pass flavor text as mythic description so it appears below description faded out
|
||||
}
|
||||
//use this constructor for regular tiered achievements
|
||||
protected Achievement(String key0, String displayName0, String sharedDesc0, int defaultValue0,
|
||||
String commonDesc0, int commonThreshold0,
|
||||
String uncommonDesc0, int uncommonThreshold0,
|
||||
String rareDesc0, int rareThreshold0,
|
||||
String mythicDesc0, int mythicThreshold0) {
|
||||
protected Achievement(final String key0, final String displayName0, final String sharedDesc0, final int defaultValue0,
|
||||
final String commonDesc0, final int commonThreshold0,
|
||||
final String uncommonDesc0, final int uncommonThreshold0,
|
||||
final String rareDesc0, final int rareThreshold0,
|
||||
final String mythicDesc0, final int mythicThreshold0) {
|
||||
key = key0;
|
||||
displayName = displayName0;
|
||||
sharedDesc = sharedDesc0;
|
||||
@@ -152,18 +152,18 @@ public abstract class Achievement {
|
||||
image = GuiBase.getInterface().createLayeredImage(background, ForgeConstants.CACHE_ACHIEVEMENTS_DIR + "/" + key + ".png", opacity);
|
||||
}
|
||||
|
||||
public int update(Player player) {
|
||||
int value = evaluate(player, player.getGame());
|
||||
public int update(final Player player) {
|
||||
final int value = evaluate(player, player.getGame());
|
||||
if (checkGreaterThan) {
|
||||
if (value <= best) { return value; }
|
||||
}
|
||||
else if (value >= best) { return value; }
|
||||
|
||||
boolean hadEarnedSpecial = earnedSpecial();
|
||||
boolean hadEarnedMythic = earnedMythic();
|
||||
boolean hadEarnedRare = earnedRare();
|
||||
boolean hadEarnedUncommon = earnedUncommon();
|
||||
boolean hadEarnedCommon = earnedCommon();
|
||||
final boolean hadEarnedSpecial = earnedSpecial();
|
||||
final boolean hadEarnedMythic = earnedMythic();
|
||||
final boolean hadEarnedRare = earnedRare();
|
||||
final boolean hadEarnedUncommon = earnedUncommon();
|
||||
final boolean hadEarnedCommon = earnedCommon();
|
||||
|
||||
best = value;
|
||||
timestamp = new Date().getTime();
|
||||
@@ -216,39 +216,39 @@ public abstract class Achievement {
|
||||
return best != defaultValue;
|
||||
}
|
||||
|
||||
public void saveToXml(Element el) {
|
||||
public void saveToXml(final Element el) {
|
||||
el.setAttribute("best", String.valueOf(best));
|
||||
el.setAttribute("time", String.valueOf(timestamp));
|
||||
}
|
||||
|
||||
public void loadFromXml(Element el) {
|
||||
public void loadFromXml(final Element el) {
|
||||
best = getIntAttribute(el, "best");
|
||||
timestamp = getLongAttribute(el, "time");
|
||||
best = performConversion(best, timestamp);
|
||||
}
|
||||
|
||||
//give derived classes a chance to perform a conversion if needed
|
||||
protected int performConversion(int value, long timestamp) {
|
||||
protected int performConversion(final int value, final long timestamp) {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected int getIntAttribute(Element el, String name) {
|
||||
String value = el.getAttribute(name);
|
||||
protected int getIntAttribute(final Element el, final String name) {
|
||||
final String value = el.getAttribute(name);
|
||||
if (value.length() > 0) {
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
catch (final Exception ex) {}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
protected long getLongAttribute(Element el, String name) {
|
||||
String value = el.getAttribute(name);
|
||||
protected long getLongAttribute(final Element el, final String name) {
|
||||
final String value = el.getAttribute(name);
|
||||
if (value.length() > 0) {
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
catch (final Exception ex) {}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -265,11 +265,11 @@ public abstract class Achievement {
|
||||
protected final String getFormattedTimestamp() {
|
||||
if (timestamp == 0) { return null; }
|
||||
|
||||
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
|
||||
final DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
|
||||
return formatter.format(new Date(timestamp));
|
||||
}
|
||||
|
||||
public String getSubTitle(boolean includeTimestamp) {
|
||||
public String getSubTitle(final boolean includeTimestamp) {
|
||||
if (best == defaultValue) { return null; }
|
||||
|
||||
String subTitle;
|
||||
@@ -280,7 +280,7 @@ public abstract class Achievement {
|
||||
subTitle = "Best: " + best + " " + (pluralizeNoun() ? Lang.getPlural(getNoun()) : getNoun());
|
||||
}
|
||||
if (includeTimestamp) {
|
||||
String formattedTimestamp = getFormattedTimestamp();
|
||||
final String formattedTimestamp = getFormattedTimestamp();
|
||||
if (formattedTimestamp != null) {
|
||||
subTitle += " (" + formattedTimestamp + ")";
|
||||
}
|
||||
|
||||
@@ -8,15 +8,12 @@ import forge.game.player.Player;
|
||||
public abstract class StreakAchievement extends Achievement {
|
||||
private int current;
|
||||
|
||||
protected StreakAchievement(String key0, String displayName0, String description0, String flavorText0) {
|
||||
super(key0, displayName0, description0, flavorText0, 0);
|
||||
}
|
||||
//use this constructor for regular tiered achievements
|
||||
protected StreakAchievement(String key0, String displayName0, String sharedDesc0,
|
||||
String commonDesc0, int commonThreshold0,
|
||||
String uncommonDesc0, int uncommonThreshold0,
|
||||
String rareDesc0, int rareThreshold0,
|
||||
String mythicDesc0, int mythicThreshold0) {
|
||||
protected StreakAchievement(final String key0, final String displayName0, final String sharedDesc0,
|
||||
final String commonDesc0, final int commonThreshold0,
|
||||
final String uncommonDesc0, final int uncommonThreshold0,
|
||||
final String rareDesc0, final int rareThreshold0,
|
||||
final String mythicDesc0, final int mythicThreshold0) {
|
||||
super(key0, displayName0, sharedDesc0, 0, commonDesc0, commonThreshold0,
|
||||
uncommonDesc0, uncommonThreshold0, rareDesc0, rareThreshold0,
|
||||
mythicDesc0, mythicThreshold0);
|
||||
@@ -25,8 +22,8 @@ public abstract class StreakAchievement extends Achievement {
|
||||
protected abstract Boolean eval(Player player, Game game);
|
||||
|
||||
@Override
|
||||
protected final int evaluate(Player player, Game game) {
|
||||
Boolean val = eval(player, game);
|
||||
protected final int evaluate(final Player player, final Game game) {
|
||||
final Boolean val = eval(player, game);
|
||||
if (val != null) { //null means don't increment or reset
|
||||
if (val) {
|
||||
current++;
|
||||
@@ -48,13 +45,13 @@ public abstract class StreakAchievement extends Achievement {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToXml(Element el) {
|
||||
public void saveToXml(final Element el) {
|
||||
super.saveToXml(el);
|
||||
el.setAttribute("current", String.valueOf(current));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromXml(Element el) {
|
||||
public void loadFromXml(final Element el) {
|
||||
super.loadFromXml(el);
|
||||
current = getIntAttribute(el, "current");
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import forge.item.SealedProduct;
|
||||
import forge.util.Lang;
|
||||
|
||||
public class CardDetailUtil {
|
||||
|
||||
private CardDetailUtil() {
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ public class CardDetailUtil {
|
||||
|
||||
public final int r, g, b;
|
||||
|
||||
private DetailColors(int r0, int g0, int b0) {
|
||||
private DetailColors(final int r0, final int g0, final int b0) {
|
||||
r = r0;
|
||||
g = g0;
|
||||
b = b0;
|
||||
@@ -56,9 +57,6 @@ public class CardDetailUtil {
|
||||
}
|
||||
return getBorderColors(card.getColors(), card.isLand(), canShow, false).iterator().next();
|
||||
}
|
||||
public static DetailColors getBorderColor(final ColorSet cardColors, final boolean isLand, boolean canShow) {
|
||||
return getBorderColors(cardColors, isLand, canShow, false).get(0);
|
||||
}
|
||||
public static List<DetailColors> getBorderColors(final CardStateView card, final boolean canShow) {
|
||||
if (card == null) {
|
||||
return getBorderColors(null, false, false, true);
|
||||
@@ -68,8 +66,8 @@ public class CardDetailUtil {
|
||||
public static List<DetailColors> getBorderColors(final ColorSet colorSet) {
|
||||
return getBorderColors(colorSet, false, true, true);
|
||||
}
|
||||
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
||||
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
||||
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, final boolean canShow, final boolean supportMultiple) {
|
||||
final List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
||||
|
||||
if (cardColors == null || !canShow) {
|
||||
borderColors.add(DetailColors.FACE_DOWN);
|
||||
@@ -83,7 +81,7 @@ public class CardDetailUtil {
|
||||
}
|
||||
}
|
||||
else {
|
||||
int colorCount = cardColors.countColors();
|
||||
final int colorCount = cardColors.countColors();
|
||||
if (colorCount > 2 || (colorCount > 1 && !supportMultiple)) {
|
||||
borderColors.add(DetailColors.MULTICOLOR);
|
||||
}
|
||||
@@ -162,7 +160,7 @@ public class CardDetailUtil {
|
||||
if (item instanceof PreconDeck) {
|
||||
return ((PreconDeck) item).getDescription();
|
||||
}
|
||||
return item.getName();
|
||||
return item.getName();
|
||||
}
|
||||
|
||||
public static String formatCardName(final CardView card, final boolean canShow, final boolean forAltState) {
|
||||
@@ -178,7 +176,7 @@ public class CardDetailUtil {
|
||||
if (!canShow && card.getState() != CardStateName.FaceDown) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder ptText = new StringBuilder();
|
||||
final StringBuilder ptText = new StringBuilder();
|
||||
if (card.isCreature()) {
|
||||
ptText.append(card.getPower()).append(" / ").append(card.getToughness());
|
||||
}
|
||||
@@ -250,7 +248,7 @@ public class CardDetailUtil {
|
||||
}
|
||||
for (final Entry<String, String> e : Sets.union(changedColorWords.entrySet(), changedTypes.entrySet())) {
|
||||
// ignore lower case and plural form keys, to avoid duplicity
|
||||
if (Character.isUpperCase(e.getKey().charAt(0)) &&
|
||||
if (Character.isUpperCase(e.getKey().charAt(0)) &&
|
||||
!CardUtil.singularTypes.containsKey(e.getKey())) {
|
||||
area.append("Text changed: all instances of ");
|
||||
if (e.getKey().equals("Any")) {
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -19,21 +19,17 @@ package forge.card;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.CardStorageReader;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileUtil;
|
||||
|
||||
public final class CardScriptInfo {
|
||||
private String text;
|
||||
private File file;
|
||||
private final File file;
|
||||
|
||||
public CardScriptInfo(String text0, File file0) {
|
||||
public CardScriptInfo(final String text0, final File file0) {
|
||||
text = text0;
|
||||
file = file0;
|
||||
}
|
||||
@@ -43,18 +39,18 @@ public final class CardScriptInfo {
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
return file;
|
||||
}
|
||||
|
||||
public boolean canEdit() {
|
||||
return file != null;
|
||||
return file != null;
|
||||
}
|
||||
|
||||
public boolean trySetText(String text0) {
|
||||
public boolean trySetText(final String text0) {
|
||||
if (file == null) { return false; }
|
||||
|
||||
try {
|
||||
PrintWriter p = new PrintWriter(file);
|
||||
final PrintWriter p = new PrintWriter(file);
|
||||
p.print(text0);
|
||||
p.close();
|
||||
|
||||
@@ -69,15 +65,11 @@ public final class CardScriptInfo {
|
||||
}
|
||||
|
||||
private static Map<String, CardScriptInfo> allScripts = new ConcurrentHashMap<>();
|
||||
public static void addCard(String name, String script, File file) {
|
||||
allScripts.put(name, new CardScriptInfo(script, file));
|
||||
}
|
||||
|
||||
public static CardScriptInfo getScriptFor(String name) {
|
||||
public static CardScriptInfo getScriptFor(final String name) {
|
||||
CardScriptInfo script = allScripts.get(name);
|
||||
if (script == null) { //attempt to load script if not previously loaded
|
||||
String filename = name.toLowerCase().replace(' ', '_').replace('-', '_').replace("'", "").replace(",", "") + ".txt";
|
||||
File file = new File(ForgeConstants.CARD_DATA_DIR + filename.charAt(0) + File.separator + filename);
|
||||
final String filename = name.toLowerCase().replace(' ', '_').replace('-', '_').replace("'", "").replace(",", "") + ".txt";
|
||||
final File file = new File(ForgeConstants.CARD_DATA_DIR + filename.charAt(0) + File.separator + filename);
|
||||
if (file.exists()) {
|
||||
script = new CardScriptInfo(FileUtil.readFileToString(file), file);
|
||||
allScripts.put(name, script);
|
||||
@@ -86,10 +78,4 @@ public final class CardScriptInfo {
|
||||
return script;
|
||||
}
|
||||
|
||||
public static CardStorageReader.Observer readerObserver = new CardStorageReader.Observer() {
|
||||
@Override
|
||||
public void cardLoaded(CardRules rules, List<String> lines, File fileOnDisk) {
|
||||
allScripts.put(rules.getName(), new CardScriptInfo(StringUtils.join(lines, '\n'), fileOnDisk));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,17 +38,13 @@ public final class CardScriptParser {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasErrors() {
|
||||
return !getErrorRegions(true).isEmpty();
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getErrorRegions() {
|
||||
return getErrorRegions(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all erroneous regions of this script.
|
||||
*
|
||||
*
|
||||
* @param quick
|
||||
* if {@code true}, stop when the first region is found.
|
||||
* @return a {@link Map} mapping the starting index of each error region to
|
||||
@@ -299,9 +295,9 @@ public final class CardScriptParser {
|
||||
|
||||
private static final Predicate<String> startsWith(final String s) {
|
||||
return new Predicate<String>() {
|
||||
public boolean apply(final String input) {
|
||||
return s.startsWith(input);
|
||||
}};
|
||||
@Override public boolean apply(final String input) {
|
||||
return s.startsWith(input);
|
||||
}};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -159,23 +159,23 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Void processCard(Card card, Set<CardView> list) {
|
||||
private Void processCard(final Card card, final Set<CardView> list) {
|
||||
synchronized (list) {
|
||||
list.add(card.getView());
|
||||
}
|
||||
return processEvent();
|
||||
}
|
||||
private Void processCards(Collection<Card> cards, Set<CardView> list) {
|
||||
private Void processCards(final Collection<Card> cards, final Set<CardView> list) {
|
||||
if (cards.isEmpty()) { return null; }
|
||||
|
||||
synchronized (list) {
|
||||
for (Card c : cards) {
|
||||
for (final Card c : cards) {
|
||||
list.add(c.getView());
|
||||
}
|
||||
}
|
||||
return processEvent();
|
||||
}
|
||||
private Void processPlayer(Player player, Set<PlayerView> list) {
|
||||
private Void processPlayer(final Player player, final Set<PlayerView> list) {
|
||||
synchronized (list) {
|
||||
list.add(player.getView());
|
||||
}
|
||||
@@ -186,7 +186,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
|
||||
return updateZone(z.getPlayer(), z.getZoneType());
|
||||
}
|
||||
private Void updateZone(Player p, ZoneType z) {
|
||||
private Void updateZone(final Player p, final ZoneType z) {
|
||||
if (p == null || z == null) { return null; }
|
||||
|
||||
synchronized (zonesUpdate) {
|
||||
@@ -202,7 +202,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventPlayerPriority event) {
|
||||
public Void visit(final GameEventPlayerPriority event) {
|
||||
needCombatUpdate = true;
|
||||
return processEvent();
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventAnteCardsSelected ev) {
|
||||
public Void visit(final GameEventAnteCardsSelected ev) {
|
||||
final List<CardView> options = Lists.newArrayList();
|
||||
for (final Entry<Player, Card> kv : ev.cards.entries()) {
|
||||
//use fake card so real cards appear with proper formatting
|
||||
@@ -231,7 +231,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventPlayerControl ev) {
|
||||
public Void visit(final GameEventPlayerControl ev) {
|
||||
if (ev.player.getGame().isGameOver()) {
|
||||
return null;
|
||||
}
|
||||
@@ -243,37 +243,37 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventGameOutcome ev) {
|
||||
public Void visit(final GameEventGameOutcome ev) {
|
||||
gameOver = true;
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventGameFinished ev) {
|
||||
public Void visit(final GameEventGameFinished ev) {
|
||||
gameFinished = true;
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventSpellAbilityCast event) {
|
||||
public Void visit(final GameEventSpellAbilityCast event) {
|
||||
needStackUpdate = true;
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventSpellResolved event) {
|
||||
public Void visit(final GameEventSpellResolved event) {
|
||||
needStackUpdate = true;
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventSpellRemovedFromStack event) {
|
||||
public Void visit(final GameEventSpellRemovedFromStack event) {
|
||||
needStackUpdate = true;
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventZone event) {
|
||||
public Void visit(final GameEventZone event) {
|
||||
if (event.player != null) {
|
||||
// anything except stack will get here
|
||||
updateZone(event.player, event.zoneType);
|
||||
@@ -283,7 +283,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardAttachment event) {
|
||||
public Void visit(final GameEventCardAttachment event) {
|
||||
final Game game = event.equipment.getGame();
|
||||
final PlayerZone zEq = (PlayerZone)game.getZoneOf(event.equipment);
|
||||
if (event.oldEntiy instanceof Card) {
|
||||
@@ -301,7 +301,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
processCard(event.card, cardsUpdate);
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Void visit(final GameEventCardPhased event) {
|
||||
processCard(event.card, cardsUpdate);
|
||||
@@ -322,9 +322,9 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
|
||||
@Override
|
||||
public Void visit(final GameEventBlockersDeclared event) {
|
||||
HashSet<Card> cards = new HashSet<Card>();
|
||||
for (MapOfLists<Card, Card> kv : event.blockers.values()) {
|
||||
for (Collection<Card> blockers : kv.values()) {
|
||||
final HashSet<Card> cards = new HashSet<Card>();
|
||||
for (final MapOfLists<Card, Card> kv : event.blockers.values()) {
|
||||
for (final Collection<Card> blockers : kv.values()) {
|
||||
cards.addAll(blockers);
|
||||
}
|
||||
}
|
||||
@@ -332,18 +332,18 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventAttackersDeclared event) {
|
||||
public Void visit(final GameEventAttackersDeclared event) {
|
||||
return processCards(event.attackersMap.values(), cardsUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCombatChanged event) {
|
||||
public Void visit(final GameEventCombatChanged event) {
|
||||
needCombatUpdate = true;
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCombatEnded event) {
|
||||
public Void visit(final GameEventCombatEnded event) {
|
||||
needCombatUpdate = true;
|
||||
|
||||
// This should remove sword/shield icons from combatants by the time game moves to M2
|
||||
@@ -352,20 +352,20 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardChangeZone event) {
|
||||
public Void visit(final GameEventCardChangeZone event) {
|
||||
updateZone(event.from);
|
||||
return updateZone(event.to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardStatsChanged event) {
|
||||
public Void visit(final GameEventCardStatsChanged event) {
|
||||
processCards(event.cards, cardsRefreshDetails);
|
||||
return processCards(event.cards, cardsUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventPlayerStatsChanged event) {
|
||||
CardCollection cards = new CardCollection();
|
||||
public Void visit(final GameEventPlayerStatsChanged event) {
|
||||
final CardCollection cards = new CardCollection();
|
||||
for (final Player p : event.players) {
|
||||
cards.addAll(p.getAllCards());
|
||||
}
|
||||
@@ -373,22 +373,22 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventShuffle event) {
|
||||
public Void visit(final GameEventShuffle event) {
|
||||
return updateZone(event.player.getZone(ZoneType.Library));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventManaPool event) {
|
||||
public Void visit(final GameEventManaPool event) {
|
||||
return processPlayer(event.player, manaPoolUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventPlayerLivesChanged event) {
|
||||
public Void visit(final GameEventPlayerLivesChanged event) {
|
||||
return processPlayer(event.player, livesUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventPlayerPoisoned event) {
|
||||
public Void visit(final GameEventPlayerPoisoned event) {
|
||||
return processPlayer(event.receiver, livesUpdate);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,9 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void receiveGameEvent(final GameEvent ev) { ev.visit(this); }
|
||||
public void receiveGameEvent(final GameEvent ev) {
|
||||
ev.visit(this);
|
||||
}
|
||||
|
||||
public static final int phasesDelay = 200;
|
||||
public static final int combatDelay = 400;
|
||||
@@ -83,9 +85,9 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
@Override
|
||||
public Void visit(final GameEventTurnPhase ev) {
|
||||
try {
|
||||
final boolean isUiToStop = !humanController.getGui().isUiSetToSkipPhase(ev.playerTurn.getView(), ev.phase);
|
||||
final boolean isUiToStop = !humanController.getGui().isUiSetToSkipPhase(ev.playerTurn.getView(), ev.phase);
|
||||
|
||||
switch(ev.phase) {
|
||||
switch(ev.phase) {
|
||||
case COMBAT_END:
|
||||
case COMBAT_DECLARE_ATTACKERS:
|
||||
case COMBAT_DECLARE_BLOCKERS:
|
||||
@@ -98,8 +100,8 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
pauseForEvent(phasesDelay);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
package forge.control;
|
||||
|
||||
@@ -27,6 +27,7 @@ public class WatchLocalGame extends PlayerControllerHuman {
|
||||
public void updateAchievements() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUndoLastAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,24 +5,23 @@ import java.util.List;
|
||||
|
||||
import forge.itemmanager.IItemManager;
|
||||
|
||||
|
||||
public class ColorDeckGenerator extends DeckProxy implements Comparable<ColorDeckGenerator> {
|
||||
public static List<DeckProxy> getColorDecks(IItemManager<DeckProxy> lstDecks0, boolean isAi0) {
|
||||
String[] colors = new String[] { "Random 1", "Random 2", "Random 3",
|
||||
public static List<DeckProxy> getColorDecks(final IItemManager<DeckProxy> lstDecks0, final boolean isAi0) {
|
||||
final String[] colors = new String[] { "Random 1", "Random 2", "Random 3",
|
||||
"White", "Blue", "Black", "Red", "Green" };
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
final ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
decks.add(new ColorDeckGenerator(colors[i], i, lstDecks0, isAi0));
|
||||
}
|
||||
return decks;
|
||||
}
|
||||
|
||||
private String name;
|
||||
private int index;
|
||||
private final String name;
|
||||
private final int index;
|
||||
private final IItemManager<DeckProxy> lstDecks;
|
||||
private final boolean isAi;
|
||||
|
||||
private ColorDeckGenerator(String name0, int index0, IItemManager<DeckProxy> lstDecks0, boolean isAi0) {
|
||||
private ColorDeckGenerator(final String name0, final int index0, final IItemManager<DeckProxy> lstDecks0, final boolean isAi0) {
|
||||
super();
|
||||
name = name0;
|
||||
index = index0;
|
||||
@@ -40,16 +39,15 @@ public class ColorDeckGenerator extends DeckProxy implements Comparable<ColorDec
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(final ColorDeckGenerator d) {
|
||||
return d instanceof ColorDeckGenerator ? Integer.compare(index, ((ColorDeckGenerator)d).index) : 1;
|
||||
return Integer.compare(index, d.index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deck getDeck() {
|
||||
List<String> selection = new ArrayList<String>();
|
||||
for (DeckProxy deck : lstDecks.getSelectedItems()) {
|
||||
final List<String> selection = new ArrayList<String>();
|
||||
for (final DeckProxy deck : lstDecks.getSelectedItems()) {
|
||||
selection.add(deck.getName());
|
||||
}
|
||||
if (DeckgenUtil.colorCheck(selection)) {
|
||||
@@ -57,7 +55,7 @@ public class ColorDeckGenerator extends DeckProxy implements Comparable<ColorDec
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isGeneratedDeck() {
|
||||
return true;
|
||||
|
||||
@@ -31,7 +31,6 @@ import forge.quest.QuestEvent;
|
||||
import forge.util.BinaryUtil;
|
||||
import forge.util.IHasName;
|
||||
import forge.util.storage.IStorage;
|
||||
import forge.util.storage.StorageImmediatelySerialized;
|
||||
|
||||
// Adding a generic to this class creates compile problems in ItemManager (that I can not fix)
|
||||
public class DeckProxy implements InventoryItem {
|
||||
@@ -41,7 +40,7 @@ public class DeckProxy implements InventoryItem {
|
||||
|
||||
public static final Function<DeckProxy, String> FN_GET_NAME = new Function<DeckProxy, String>() {
|
||||
@Override
|
||||
public String apply(DeckProxy arg0) {
|
||||
public String apply(final DeckProxy arg0) {
|
||||
return arg0.getName();
|
||||
}
|
||||
};
|
||||
@@ -61,15 +60,15 @@ public class DeckProxy implements InventoryItem {
|
||||
this(null, "", null, "", null, null);
|
||||
}
|
||||
|
||||
public DeckProxy(Deck deck, String deckType, GameType type, IStorage<? extends IHasName> storage) {
|
||||
public DeckProxy(final Deck deck, final String deckType, final GameType type, final IStorage<? extends IHasName> storage) {
|
||||
this(deck, deckType, type, "", storage, null);
|
||||
}
|
||||
|
||||
public DeckProxy(IHasName deck, String deckType, Function<IHasName, Deck> fnGetDeck, GameType type, IStorage<? extends IHasName> storage) {
|
||||
public DeckProxy(final IHasName deck, final String deckType, final Function<IHasName, Deck> fnGetDeck, final GameType type, final IStorage<? extends IHasName> storage) {
|
||||
this(deck, deckType, type, "", storage, fnGetDeck);
|
||||
}
|
||||
|
||||
private DeckProxy(IHasName deck, String deckType, GameType type, String path, IStorage<? extends IHasName> storage, Function<IHasName, Deck> fnGetDeck) {
|
||||
private DeckProxy(final IHasName deck, final String deckType, final GameType type, final String path, final IStorage<? extends IHasName> storage, final Function<IHasName, Deck> fnGetDeck) {
|
||||
this.deck = deck;
|
||||
this.deckType = deckType;
|
||||
this.storage = storage;
|
||||
@@ -120,7 +119,7 @@ public class DeckProxy implements InventoryItem {
|
||||
return getDeckString(path, deck.getName());
|
||||
}
|
||||
|
||||
public static String getDeckString(String path, String name) {
|
||||
public static String getDeckString(final String path, final String name) {
|
||||
if (StringUtils.isEmpty(path)) {
|
||||
return name;
|
||||
}
|
||||
@@ -143,17 +142,17 @@ public class DeckProxy implements InventoryItem {
|
||||
byte landProfile = MagicColor.COLORLESS;
|
||||
HashSet<Byte> nonReqColors = null;
|
||||
|
||||
for (Entry<DeckSection, CardPool> deckEntry : getDeck()) {
|
||||
for (final Entry<DeckSection, CardPool> deckEntry : getDeck()) {
|
||||
switch (deckEntry.getKey()) {
|
||||
case Main:
|
||||
case Commander:
|
||||
for (Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
CardRules rules = poolEntry.getKey().getRules();
|
||||
for (final Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
final CardRules rules = poolEntry.getKey().getRules();
|
||||
if (rules.getType().isLand()) { //track color identity of lands separately
|
||||
landProfile |= rules.getColorIdentity().getColor();
|
||||
}
|
||||
else {
|
||||
for (ManaCostShard shard : rules.getManaCost()) {
|
||||
for (final ManaCostShard shard : rules.getManaCost()) {
|
||||
//track phyrexian and hybrid costs separately as they won't always affect color
|
||||
if (shard.isPhyrexian() || shard.isOr2Colorless() || !shard.isMonoColor()) {
|
||||
if (nonReqColors == null) {
|
||||
@@ -175,7 +174,7 @@ public class DeckProxy implements InventoryItem {
|
||||
if (nonReqColors != null) {
|
||||
//if any non-required mana colors present, determine which colors, if any,
|
||||
//need to be accounted for in color profile of deck
|
||||
for (Byte colorMask : nonReqColors) {
|
||||
for (final Byte colorMask : nonReqColors) {
|
||||
colorProfile |= (colorMask & landProfile);
|
||||
}
|
||||
}
|
||||
@@ -188,12 +187,12 @@ public class DeckProxy implements InventoryItem {
|
||||
if (colorIdentity == null) {
|
||||
byte colorProfile = MagicColor.COLORLESS;
|
||||
|
||||
for (Entry<DeckSection, CardPool> deckEntry : getDeck()) {
|
||||
for (final Entry<DeckSection, CardPool> deckEntry : getDeck()) {
|
||||
switch (deckEntry.getKey()) {
|
||||
case Main:
|
||||
case Sideboard:
|
||||
case Commander:
|
||||
for (Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
for (final Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
colorProfile |= poolEntry.getKey().getRules().getColorIdentity().getColor();
|
||||
}
|
||||
break;
|
||||
@@ -209,12 +208,12 @@ public class DeckProxy implements InventoryItem {
|
||||
public CardRarity getHighestRarity() {
|
||||
if (highestRarity == null) {
|
||||
highestRarity = CardRarity.Common;
|
||||
for (Entry<DeckSection, CardPool> deckEntry : getDeck()) {
|
||||
for (final Entry<DeckSection, CardPool> deckEntry : getDeck()) {
|
||||
switch (deckEntry.getKey()) {
|
||||
case Main:
|
||||
case Sideboard:
|
||||
case Commander:
|
||||
for (Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
for (final Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
switch (poolEntry.getKey().getRarity()) {
|
||||
case MythicRare:
|
||||
highestRarity = CardRarity.MythicRare;
|
||||
@@ -262,11 +261,11 @@ public class DeckProxy implements InventoryItem {
|
||||
mainSize = -1;
|
||||
}
|
||||
else {
|
||||
Deck d = getDeck();
|
||||
final Deck d = getDeck();
|
||||
mainSize = d.getMain().countAll();
|
||||
|
||||
//account for commander as part of main deck size
|
||||
CardPool commander = d.get(DeckSection.Commander);
|
||||
final CardPool commander = d.get(DeckSection.Commander);
|
||||
if (commander != null) {
|
||||
mainSize += commander.countAll();
|
||||
}
|
||||
@@ -277,7 +276,7 @@ public class DeckProxy implements InventoryItem {
|
||||
|
||||
public int getSideSize() {
|
||||
if (sbSize == null) {
|
||||
CardPool sb = getDeck().get(DeckSection.Sideboard);
|
||||
final CardPool sb = getDeck().get(DeckSection.Sideboard);
|
||||
sbSize = sb == null ? -1 : sb.countAll();
|
||||
if (sbSize == 0) {
|
||||
sbSize = -1;
|
||||
@@ -296,36 +295,36 @@ public class DeckProxy implements InventoryItem {
|
||||
|
||||
// TODO: The methods below should not take the decks collections from singletons, instead they are supposed to use data passed in parameters
|
||||
public static Iterable<DeckProxy> getAllConstructedDecks() {
|
||||
List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
final List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
addDecksRecursivelly("Constructed", GameType.Constructed, result, "", FModel.getDecks().getConstructed());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Iterable<DeckProxy> getAllCommanderDecks() {
|
||||
List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
final List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
addDecksRecursivelly("Commander", GameType.Commander, result, "", FModel.getDecks().getCommander());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Iterable<DeckProxy> getAllSchemeDecks() {
|
||||
List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
final List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
addDecksRecursivelly("Scheme", GameType.Archenemy, result, "", FModel.getDecks().getScheme());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Iterable<DeckProxy> getAllPlanarDecks() {
|
||||
List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
final List<DeckProxy> result = new ArrayList<DeckProxy>();
|
||||
addDecksRecursivelly("Plane", GameType.Planechase, result, "", FModel.getDecks().getPlane());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void addDecksRecursivelly(String deckType, GameType gameType, List<DeckProxy> list, String path, IStorage<Deck> folder) {
|
||||
for (IStorage<Deck> f : folder.getFolders()) {
|
||||
String subPath = (StringUtils.isBlank(path) ? "" : path) + "/" + f.getName();
|
||||
private static void addDecksRecursivelly(final String deckType, final GameType gameType, final List<DeckProxy> list, final String path, final IStorage<Deck> folder) {
|
||||
for (final IStorage<Deck> f : folder.getFolders()) {
|
||||
final String subPath = (StringUtils.isBlank(path) ? "" : path) + "/" + f.getName();
|
||||
addDecksRecursivelly(deckType, gameType, list, subPath, f);
|
||||
}
|
||||
|
||||
for (Deck d : folder) {
|
||||
for (final Deck d : folder) {
|
||||
list.add(new DeckProxy(d, deckType, gameType, path, folder, null));
|
||||
}
|
||||
}
|
||||
@@ -334,13 +333,13 @@ public class DeckProxy implements InventoryItem {
|
||||
public static final Predicate<DeckProxy> createPredicate(final Predicate<PaperCard> cardPredicate) {
|
||||
return new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(DeckProxy input) {
|
||||
for (Entry<DeckSection, CardPool> deckEntry : input.getDeck()) {
|
||||
public boolean apply(final DeckProxy input) {
|
||||
for (final Entry<DeckSection, CardPool> deckEntry : input.getDeck()) {
|
||||
switch (deckEntry.getKey()) {
|
||||
case Main:
|
||||
case Sideboard:
|
||||
case Commander:
|
||||
for (Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
for (final Entry<PaperCard, Integer> poolEntry : deckEntry.getValue()) {
|
||||
if (!cardPredicate.apply(poolEntry.getKey())) {
|
||||
return false; //all cards in deck must pass card predicate to pass deck predicate
|
||||
}
|
||||
@@ -362,13 +361,6 @@ public class DeckProxy implements InventoryItem {
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void updateInStorage() {
|
||||
if (storage instanceof StorageImmediatelySerialized<?>) {
|
||||
((StorageImmediatelySerialized<IHasName>)storage).add(deck);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteFromStorage() {
|
||||
if (storage != null) {
|
||||
storage.delete(getName());
|
||||
@@ -377,7 +369,7 @@ public class DeckProxy implements InventoryItem {
|
||||
|
||||
private static class ThemeDeckGenerator extends DeckProxy {
|
||||
private final String name;
|
||||
public ThemeDeckGenerator(String name0) {
|
||||
public ThemeDeckGenerator(final String name0) {
|
||||
super();
|
||||
name = name0;
|
||||
}
|
||||
@@ -388,7 +380,7 @@ public class DeckProxy implements InventoryItem {
|
||||
final Deck deck = new Deck();
|
||||
gen.setSingleton(FModel.getPreferences().getPrefBoolean(FPref.DECKGEN_SINGLETONS));
|
||||
gen.setUseArtifacts(!FModel.getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS));
|
||||
StringBuilder errorBuilder = new StringBuilder();
|
||||
final StringBuilder errorBuilder = new StringBuilder();
|
||||
deck.getMain().addAll(gen.getThemeDeck(this.getName(), 60, errorBuilder));
|
||||
if (errorBuilder.length() > 0) {
|
||||
throw new RuntimeException(errorBuilder.toString());
|
||||
@@ -406,13 +398,14 @@ public class DeckProxy implements InventoryItem {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneratedDeck() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<DeckProxy> getAllThemeDecks() {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
for (final String s : DeckGeneratorTheme.getThemeNames()) {
|
||||
decks.add(new ThemeDeckGenerator(s));
|
||||
}
|
||||
@@ -420,8 +413,8 @@ public class DeckProxy implements InventoryItem {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<DeckProxy> getAllPreconstructedDecks(IStorage<PreconDeck> iStorage) {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
public static List<DeckProxy> getAllPreconstructedDecks(final IStorage<PreconDeck> iStorage) {
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
for (final PreconDeck preconDeck : iStorage) {
|
||||
decks.add(new DeckProxy(preconDeck, "Precon", (Function<IHasName, Deck>)(Object)PreconDeck.FN_GET_DECK, null, iStorage));
|
||||
}
|
||||
@@ -429,12 +422,12 @@ public class DeckProxy implements InventoryItem {
|
||||
}
|
||||
|
||||
public static List<DeckProxy> getAllQuestEventAndChallenges() {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
QuestController quest = FModel.getQuest();
|
||||
for (QuestEvent e : quest.getDuelsManager().getAllDuels()) {
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
final QuestController quest = FModel.getQuest();
|
||||
for (final QuestEvent e : quest.getDuelsManager().getAllDuels()) {
|
||||
decks.add(new DeckProxy(e.getEventDeck(), "Quest Event", null, null));
|
||||
}
|
||||
for (QuestEvent e : quest.getChallenges()) {
|
||||
for (final QuestEvent e : quest.getChallenges()) {
|
||||
decks.add(new DeckProxy(e.getEventDeck(), "Quest Event", null, null));
|
||||
}
|
||||
return decks;
|
||||
@@ -453,8 +446,8 @@ public class DeckProxy implements InventoryItem {
|
||||
return humanDecks;
|
||||
}
|
||||
|
||||
public static List<DeckProxy> getAllQuestDecks(IStorage<Deck> storage) {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
public static List<DeckProxy> getAllQuestDecks(final IStorage<Deck> storage) {
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
if (storage != null) {
|
||||
for (final Deck deck : storage) {
|
||||
decks.add(new DeckProxy(deck, "Quest", GameType.Quest, storage));
|
||||
@@ -465,25 +458,25 @@ public class DeckProxy implements InventoryItem {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<DeckProxy> getAllDraftDecks() {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
IStorage<DeckGroup> draft = FModel.getDecks().getDraft();
|
||||
for (DeckGroup d : draft) {
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
final IStorage<DeckGroup> draft = FModel.getDecks().getDraft();
|
||||
for (final DeckGroup d : draft) {
|
||||
decks.add(new DeckProxy(d, "Draft", ((Function<IHasName, Deck>)(Object)DeckGroup.FN_HUMAN_DECK), GameType.Draft, draft));
|
||||
}
|
||||
return decks;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<DeckProxy> getWinstonDecks(IStorage<DeckGroup> draft) {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
for (DeckGroup d : draft) {
|
||||
public static List<DeckProxy> getWinstonDecks(final IStorage<DeckGroup> draft) {
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
for (final DeckGroup d : draft) {
|
||||
decks.add(new DeckProxy(d, "Winston", ((Function<IHasName, Deck>)(Object)DeckGroup.FN_HUMAN_DECK), GameType.Winston, draft));
|
||||
}
|
||||
return decks;
|
||||
}
|
||||
|
||||
public static List<DeckProxy> getNetDecks(NetDeckCategory category) {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
public static List<DeckProxy> getNetDecks(final NetDeckCategory category) {
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
if (category != null) {
|
||||
addDecksRecursivelly("Constructed", GameType.Constructed, decks, "", category);
|
||||
}
|
||||
@@ -493,49 +486,49 @@ public class DeckProxy implements InventoryItem {
|
||||
public static final Predicate<DeckProxy> IS_WHITE = new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(final DeckProxy deck) {
|
||||
ColorSet cs = deck.getColor();
|
||||
final ColorSet cs = deck.getColor();
|
||||
return cs != null && cs.hasAnyColor(MagicColor.WHITE);
|
||||
}
|
||||
};
|
||||
public static final Predicate<DeckProxy> IS_BLUE = new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(final DeckProxy deck) {
|
||||
ColorSet cs = deck.getColor();
|
||||
final ColorSet cs = deck.getColor();
|
||||
return cs != null && cs.hasAnyColor(MagicColor.BLUE);
|
||||
}
|
||||
};
|
||||
public static final Predicate<DeckProxy> IS_BLACK = new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(final DeckProxy deck) {
|
||||
ColorSet cs = deck.getColor();
|
||||
final ColorSet cs = deck.getColor();
|
||||
return cs != null && cs.hasAnyColor(MagicColor.BLACK);
|
||||
}
|
||||
};
|
||||
public static final Predicate<DeckProxy> IS_RED = new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(final DeckProxy deck) {
|
||||
ColorSet cs = deck.getColor();
|
||||
final ColorSet cs = deck.getColor();
|
||||
return cs != null && cs.hasAnyColor(MagicColor.RED);
|
||||
}
|
||||
};
|
||||
public static final Predicate<DeckProxy> IS_GREEN = new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(final DeckProxy deck) {
|
||||
ColorSet cs = deck.getColor();
|
||||
final ColorSet cs = deck.getColor();
|
||||
return cs != null && cs.hasAnyColor(MagicColor.GREEN);
|
||||
}
|
||||
};
|
||||
public static final Predicate<DeckProxy> IS_COLORLESS = new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(final DeckProxy deck) {
|
||||
ColorSet cs = deck.getColor();
|
||||
final ColorSet cs = deck.getColor();
|
||||
return cs != null && cs.getColor() == 0;
|
||||
}
|
||||
};
|
||||
public static final Predicate<DeckProxy> IS_MULTICOLOR = new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(final DeckProxy deck) {
|
||||
ColorSet cs = deck.getColor();
|
||||
final ColorSet cs = deck.getColor();
|
||||
return cs != null && BinaryUtil.bitCount(cs.getColor()) > 1;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,19 +17,12 @@ public enum DeckType {
|
||||
NET_COMMANDER_DECK ("Net Commander Decks");
|
||||
|
||||
private String value;
|
||||
private DeckType(String value) {
|
||||
private DeckType(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
public static DeckType fromString(String value){
|
||||
for (final DeckType d : DeckType.values()) {
|
||||
if (d.toString().equalsIgnoreCase(value)) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No Enum specified for this string");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
||||
User,
|
||||
Favorite
|
||||
}
|
||||
|
||||
public static List<DeckProxy> getRandomDecks(IHasGameType lstDecks0, boolean isAi0) {
|
||||
ArrayList<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
|
||||
public static List<DeckProxy> getRandomDecks(final IHasGameType lstDecks0, final boolean isAi0) {
|
||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||
|
||||
decks.add(new RandomDeckGenerator("Random Generated Deck", RandomDeckType.Generated, lstDecks0, isAi0));
|
||||
decks.add(new RandomDeckGenerator("Random User Deck", RandomDeckType.User, lstDecks0, isAi0));
|
||||
@@ -34,7 +34,7 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
||||
private final IHasGameType lstDecks;
|
||||
private final boolean isAi;
|
||||
|
||||
private RandomDeckGenerator(String name0, RandomDeckType type0, IHasGameType lstDecks0, boolean isAi0) {
|
||||
private RandomDeckGenerator(final String name0, final RandomDeckType type0, final IHasGameType lstDecks0, final boolean isAi0) {
|
||||
super();
|
||||
name = name0;
|
||||
type = type0;
|
||||
@@ -54,7 +54,7 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
||||
|
||||
@Override
|
||||
public int compareTo(final RandomDeckGenerator d) {
|
||||
return d instanceof RandomDeckGenerator ? Integer.compare(type.ordinal(), ((RandomDeckGenerator)d).type.ordinal()) : 1;
|
||||
return Integer.compare(type.ordinal(), d.type.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,8 +87,8 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
||||
case QUEST_OPPONENT_DECK:
|
||||
return Aggregates.random(DeckProxy.getAllQuestEventAndChallenges()).getDeck();
|
||||
case COLOR_DECK:
|
||||
List<String> colors = new ArrayList<String>();
|
||||
int count = Aggregates.randomInt(1, 3);
|
||||
final List<String> colors = new ArrayList<String>();
|
||||
final int count = Aggregates.randomInt(1, 3);
|
||||
for (int i = 1; i <= count; i++) {
|
||||
colors.add("Random " + i);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Deck getUserDeck() {
|
||||
Iterable<Deck> decks;
|
||||
switch (lstDecks.getGameType()) {
|
||||
@@ -135,8 +135,7 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
||||
break;
|
||||
case TinyLeaders:
|
||||
decks = Iterables.filter(DeckProxy.getAllCommanderDecks(), new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(DeckProxy deck) {
|
||||
@Override public boolean apply(final DeckProxy deck) {
|
||||
return DeckFormat.TinyLeaders.getDeckConformanceProblem(deck.getDeck()) == null;
|
||||
}
|
||||
});
|
||||
@@ -152,8 +151,7 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
|
||||
break;
|
||||
}
|
||||
decks = Iterables.filter(decks, new Predicate<DeckProxy>() {
|
||||
@Override
|
||||
public boolean apply(DeckProxy deck) {
|
||||
@Override public boolean apply(final DeckProxy deck) {
|
||||
return deck.isFavoriteDeck();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.deck.io;
|
||||
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
};
|
||||
|
||||
public OldDeckParser(final IStorage<Deck> constructed2, final IStorage<DeckGroup> draft2,
|
||||
final IStorage<DeckGroup> sealed2, final IStorage<Deck> cube2) {
|
||||
this.deckDir = new File(ForgeConstants.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 = SOptionPane.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 = SOptionPane.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 = SOptionPane.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 (SOptionPane.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
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -6,29 +6,29 @@
|
||||
* 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.download;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.card.CardRules;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.ImageUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class GuiDownloadPicturesLQ extends GuiDownloadService {
|
||||
@Override
|
||||
public String getTitle() {
|
||||
@@ -37,39 +37,40 @@ public class GuiDownloadPicturesLQ extends GuiDownloadService {
|
||||
|
||||
@Override
|
||||
protected final Map<String, String> getNeededFiles() {
|
||||
Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||
final Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
for (PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
|
||||
for (final PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
|
||||
addDLObject(c, downloads, false);
|
||||
if (ImageUtil.hasBackFacePicture(c)) {
|
||||
addDLObject(c, downloads, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
|
||||
for (final PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
|
||||
addDLObject(c, downloads, false);
|
||||
}
|
||||
|
||||
|
||||
// Add missing tokens to the list of things to download.
|
||||
addMissingItems(downloads, ForgeConstants.IMAGE_LIST_TOKENS_FILE, ForgeConstants.CACHE_TOKEN_PICS_DIR);
|
||||
|
||||
return downloads;
|
||||
}
|
||||
|
||||
private void addDLObject(PaperCard c, Map<String, String> downloads, boolean backFace) {
|
||||
CardRules cardRules = c.getRules();
|
||||
String urls = cardRules.getPictureUrl(backFace);
|
||||
private static void addDLObject(final PaperCard c, final Map<String, String> downloads, final boolean backFace) {
|
||||
final CardRules cardRules = c.getRules();
|
||||
final String urls = cardRules.getPictureUrl(backFace);
|
||||
if (StringUtils.isEmpty(urls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String filename = ImageUtil.getImageKey(c, backFace, false);
|
||||
File destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
|
||||
if (destFile.exists())
|
||||
final File destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
|
||||
if (destFile.exists()) {
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
filename = destFile.getAbsolutePath();
|
||||
|
||||
|
||||
if (downloads.containsKey(filename)) {
|
||||
return;
|
||||
}
|
||||
@@ -77,10 +78,10 @@ public class GuiDownloadPicturesLQ extends GuiDownloadService {
|
||||
final String urlToDownload;
|
||||
int urlIndex = 0;
|
||||
int allUrlsLen = 1;
|
||||
if (urls.indexOf("\\") < 0)
|
||||
if (urls.indexOf("\\") < 0) {
|
||||
urlToDownload = urls;
|
||||
else {
|
||||
String[] allUrls = urls.split("\\\\");
|
||||
} else {
|
||||
final String[] allUrls = urls.split("\\\\");
|
||||
allUrlsLen = allUrls.length;
|
||||
urlIndex = (c.getArtIndex()-1) % allUrlsLen;
|
||||
urlToDownload = allUrls[urlIndex];
|
||||
|
||||
@@ -320,12 +320,10 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
protected Proxy getProxy() {
|
||||
if (type == 0) {
|
||||
return Proxy.NO_PROXY;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
try {
|
||||
return new Proxy(TYPES[type], new InetSocketAddress(txtAddress.getText(), Integer.parseInt(txtPort.getText())));
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
BugReporter.reportException(ex,
|
||||
"Proxy connection could not be established!\nProxy address: %s\nProxy port: %s",
|
||||
txtAddress.getText(), txtPort.getText());
|
||||
|
||||
@@ -6,17 +6,23 @@
|
||||
* 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.download;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.card.CardEdition;
|
||||
@@ -25,12 +31,6 @@ import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.ImageUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class GuiDownloadSetPicturesLQ extends GuiDownloadService {
|
||||
@Override
|
||||
public String getTitle() {
|
||||
@@ -39,12 +39,12 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloadService {
|
||||
|
||||
@Override
|
||||
protected final Map<String, String> getNeededFiles() {
|
||||
Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||
final Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
for (final PaperCard c : Iterables.concat(FModel.getMagicDb().getCommonCards().getAllCards(), FModel.getMagicDb().getVariantCards().getAllCards())) {
|
||||
final String setCode3 = c.getEdition();
|
||||
if (StringUtils.isBlank(setCode3) || CardEdition.UNKNOWN.getCode().equals(setCode3)) {
|
||||
// we don't want cards from unknown sets
|
||||
// we don't want cards from unknown sets
|
||||
continue;
|
||||
}
|
||||
addDLObject(ImageUtil.getDownloadUrl(c, false), ImageUtil.getImageKey(c, false, true), downloads);
|
||||
@@ -60,8 +60,8 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloadService {
|
||||
return downloads;
|
||||
}
|
||||
|
||||
private void addDLObject(String urlPath, String filename, Map<String, String> downloads) {
|
||||
File destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
|
||||
private static void addDLObject(final String urlPath, final String filename, final Map<String, String> downloads) {
|
||||
final File destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
|
||||
// System.out.println(filename);
|
||||
if (!destFile.exists()) {
|
||||
downloads.put(destFile.getAbsolutePath(), ForgeConstants.URL_PIC_DOWNLOAD + urlPath);
|
||||
|
||||
@@ -26,7 +26,7 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
private final String name, desc, sourceUrl, destFolder, deleteFolder;
|
||||
private int filesExtracted;
|
||||
|
||||
public GuiDownloadZipService(String name0, String desc0, String sourceUrl0, String destFolder0, String deleteFolder0, IProgressBar progressBar0) {
|
||||
public GuiDownloadZipService(final String name0, final String desc0, final String sourceUrl0, final String destFolder0, final String deleteFolder0, final IProgressBar progressBar0) {
|
||||
name = name0;
|
||||
desc = desc0;
|
||||
sourceUrl = sourceUrl0;
|
||||
@@ -47,7 +47,7 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
|
||||
@Override
|
||||
protected final Map<String, String> getNeededFiles() {
|
||||
HashMap<String, String> files = new HashMap<String, String>();
|
||||
final Map<String, String> files = new HashMap<String, String>();
|
||||
files.put("_", "_");
|
||||
return files; //not needed by zip service, so just return map of size 1
|
||||
}
|
||||
@@ -74,13 +74,13 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
//if assets.zip downloaded successfully, unzip into destination folder
|
||||
try {
|
||||
if (deleteFolder != null) {
|
||||
File deleteDir = new File(deleteFolder);
|
||||
final File deleteDir = new File(deleteFolder);
|
||||
if (deleteDir.exists()) {
|
||||
//attempt to delete previous res directory if to be rebuilt
|
||||
progressBar.reset();
|
||||
progressBar.setDescription("Deleting old " + desc + "...");
|
||||
if (deleteFolder.equals(destFolder)) { //move zip file to prevent deleting it
|
||||
String oldZipFilename = zipFilename;
|
||||
final String oldZipFilename = zipFilename;
|
||||
zipFilename = deleteDir.getParentFile().getAbsolutePath() + File.separator + "temp.zip";
|
||||
Files.move(new File(oldZipFilename), new File(zipFilename));
|
||||
}
|
||||
@@ -88,8 +88,8 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
}
|
||||
}
|
||||
|
||||
ZipFile zipFile = new ZipFile(zipFilename);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
final ZipFile zipFile = new ZipFile(zipFilename);
|
||||
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
|
||||
progressBar.reset();
|
||||
progressBar.setPercentMode(true);
|
||||
@@ -104,9 +104,9 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
if (cancel) { break; }
|
||||
|
||||
try {
|
||||
ZipEntry entry = (ZipEntry)entries.nextElement();
|
||||
final ZipEntry entry = entries.nextElement();
|
||||
|
||||
String path = destFolder + entry.getName();
|
||||
final String path = destFolder + entry.getName();
|
||||
if (entry.isDirectory()) {
|
||||
new File(path).mkdir();
|
||||
progressBar.setValue(++count);
|
||||
@@ -116,7 +116,7 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
progressBar.setValue(++count);
|
||||
filesExtracted++;
|
||||
}
|
||||
catch (Exception e) { //don't quit out completely if an entry is not UTF-8
|
||||
catch (final Exception e) { //don't quit out completely if an entry is not UTF-8
|
||||
progressBar.setValue(++count);
|
||||
failedCount++;
|
||||
}
|
||||
@@ -129,19 +129,19 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
zipFile.close();
|
||||
new File(zipFilename).delete();
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String download(String filename) {
|
||||
public String download(final String filename) {
|
||||
progressBar.reset();
|
||||
progressBar.setPercentMode(true);
|
||||
progressBar.setDescription("Downloading " + desc);
|
||||
|
||||
try {
|
||||
URL url = new URL(sourceUrl);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection(getProxy());
|
||||
final URL url = new URL(sourceUrl);
|
||||
final HttpURLConnection conn = (HttpURLConnection) url.openConnection(getProxy());
|
||||
|
||||
if (url.getPath().endsWith(".php")) {
|
||||
//ensure file can be downloaded if returned from PHP script
|
||||
@@ -154,7 +154,7 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
return null;
|
||||
}
|
||||
|
||||
long contentLength = conn.getContentLength();
|
||||
final long contentLength = conn.getContentLength();
|
||||
if (contentLength == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -162,18 +162,18 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
progressBar.setMaximum(100);
|
||||
|
||||
// input stream to read file - with 8k buffer
|
||||
InputStream input = new BufferedInputStream(conn.getInputStream(), 8192);
|
||||
final InputStream input = new BufferedInputStream(conn.getInputStream(), 8192);
|
||||
|
||||
FileUtil.ensureDirectoryExists(destFolder);
|
||||
|
||||
|
||||
// output stream to write file
|
||||
String destFile = destFolder + filename;
|
||||
OutputStream output = new FileOutputStream(destFile);
|
||||
|
||||
final String destFile = destFolder + filename;
|
||||
final OutputStream output = new FileOutputStream(destFile);
|
||||
|
||||
int count;
|
||||
long total = 0;
|
||||
byte data[] = new byte[1024];
|
||||
|
||||
final byte data[] = new byte[1024];
|
||||
|
||||
while ((count = input.read(data)) != -1) {
|
||||
if (cancel) { break; }
|
||||
|
||||
@@ -181,7 +181,7 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
progressBar.setValue((int)(100 * total / contentLength));
|
||||
output.write(data, 0, count);
|
||||
}
|
||||
|
||||
|
||||
output.flush();
|
||||
output.close();
|
||||
input.close();
|
||||
@@ -198,10 +198,10 @@ public class GuiDownloadZipService extends GuiDownloadService {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void copyInputStream(InputStream in, String outPath) throws IOException{
|
||||
byte[] buffer = new byte[1024];
|
||||
protected void copyInputStream(final InputStream in, final String outPath) throws IOException{
|
||||
final byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outPath));
|
||||
final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outPath));
|
||||
|
||||
while((len = in.read(buffer)) >= 0) {
|
||||
out.write(buffer, 0, len);
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -23,8 +23,6 @@ import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -36,7 +34,7 @@ import forge.util.gui.SOptionPane;
|
||||
/**
|
||||
* The class ErrorViewer. Enables showing and saving error messages that
|
||||
* occurred in forge.
|
||||
*
|
||||
*
|
||||
* @author Clemens Koza
|
||||
* @version V1.0 02.08.2009
|
||||
*/
|
||||
@@ -48,30 +46,30 @@ public class BugReporter {
|
||||
public static final String CONTINUE = "Continue";
|
||||
public static final String EXIT = "Exit";
|
||||
|
||||
public static final String HELP_TEXT =
|
||||
"A template for a post in the bug reports forum topic is shown below. Just select '" + REPORT + "' "
|
||||
+ "and the template will be copied to your system clipboard and the forum page will open in your browser. "
|
||||
+ "Then all you have to do is paste the text into a forum post and edit the description line.";
|
||||
public static final String HELP_TEXT = String.format(
|
||||
"A template for a post in the bug reports forum topic is shown below. Just select '%s' "
|
||||
+ "and the template will be copied to your system clipboard and the forum page will open in your browser. "
|
||||
+ "Then all you have to do is paste the text into a forum post and edit the description line.", REPORT);
|
||||
public static final String HELP_URL_LABEL =
|
||||
"Reporting bugs in Forge is very important. We sincerely thank you for your time."
|
||||
+ " For help writing a solid bug report, please see:";
|
||||
+ " For help writing a solid bug report, please see:";
|
||||
public static final String HELP_URL =
|
||||
"http://www.slightlymagic.net/forum/viewtopic.php?f=26&p=109925#p109925";
|
||||
public static final String FORUM_URL;
|
||||
private static final String FORUM_URL;
|
||||
|
||||
static {
|
||||
String forgeVersion = BuildInfo.getVersionString();
|
||||
final String forgeVersion = BuildInfo.getVersionString();
|
||||
if (StringUtils.containsIgnoreCase(forgeVersion, "svn") || StringUtils.containsIgnoreCase(forgeVersion, "snapshot")) {
|
||||
FORUM_URL = "http://www.slightlymagic.net/forum/viewtopic.php?f=52&t=6333&start=54564487645#bottom";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
FORUM_URL = "http://www.slightlymagic.net/forum/viewforum.php?f=26";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows exception information in a format ready to post to the forum as a crash report. Uses the exception's message
|
||||
* as the reason if message is null.
|
||||
* Shows exception information in a format ready to post to the forum as a
|
||||
* crash report. Uses the exception's message as the reason if message is
|
||||
* null.
|
||||
*/
|
||||
public static void reportException(final Throwable ex, final String message) {
|
||||
if (ex == null) {
|
||||
@@ -82,20 +80,20 @@ public class BugReporter {
|
||||
}
|
||||
System.err.print(FThreads.debugGetCurrThreadId() + " > ");
|
||||
ex.printStackTrace();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Description: [describe what you were doing when the crash occurred]\n\n");
|
||||
buildSpoilerHeader(sb, ex.getClass().getSimpleName());
|
||||
sb.append("\n\n");
|
||||
if (null != message && !message.isEmpty()) {
|
||||
sb.append(FThreads.debugGetCurrThreadId()).append(" > ").append(message).append("\n");
|
||||
}
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
ex.printStackTrace(pw);
|
||||
|
||||
String swStr = sw.toString();
|
||||
final String swStr = sw.toString();
|
||||
if (ex instanceof StackOverflowError && swStr.length() >= STACK_OVERFLOW_MAX_MESSAGE_LEN) {
|
||||
// most likely a cycle. only take first portion so the message
|
||||
// doesn't grow too large to post
|
||||
@@ -129,7 +127,7 @@ public class BugReporter {
|
||||
* Shows a forum post template for reporting a bug.
|
||||
*/
|
||||
public static void reportBug(final String details) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Description: [describe the problem]\n\n");
|
||||
buildSpoilerHeader(sb, "General bug report");
|
||||
if (null != details && !details.isEmpty()) {
|
||||
@@ -141,42 +139,6 @@ public class BugReporter {
|
||||
GuiBase.getInterface().showBugReportDialog("Report a bug", sb.toString(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows thread stack information in a format ready to post to the forum.
|
||||
*/
|
||||
public static void reportThreadStacks(final String message) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Description: [describe what you were doing at the time]\n\n");
|
||||
buildSpoilerHeader(sb, "Thread stack dump");
|
||||
sb.append("\n\n");
|
||||
if (null != message && !message.isEmpty()) {
|
||||
sb.append(message);
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
final Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
|
||||
for (final Entry<Thread, StackTraceElement[]> e : traces.entrySet()) {
|
||||
pw.println();
|
||||
pw.printf("%s (%s):%n", e.getKey().getName(), e.getKey().getId());
|
||||
for (final StackTraceElement el : e.getValue()) {
|
||||
pw.println(el);
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(sw.toString());
|
||||
buildSpoilerFooter(sb);
|
||||
GuiBase.getInterface().showBugReportDialog("Thread stack dump", sb.toString(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for reportThreadStacks(String.format(format, args))
|
||||
*/
|
||||
public static void reportThreadStacks(final String format, final Object... args) {
|
||||
reportThreadStacks(String.format(format, args));
|
||||
}
|
||||
|
||||
private static StringBuilder buildSpoilerHeader(final StringBuilder sb, final String reportTitle) {
|
||||
sb.append("[spoiler=").append(reportTitle).append("][code]");
|
||||
sb.append("\nForge Version: ").append(GuiBase.getInterface().getCurrentVersion());
|
||||
@@ -188,7 +150,7 @@ public class BugReporter {
|
||||
return sb;
|
||||
}
|
||||
|
||||
private static StringBuilder buildSpoilerFooter(StringBuilder sb) {
|
||||
private static StringBuilder buildSpoilerFooter(final StringBuilder sb) {
|
||||
sb.append("[/code][/spoiler]");
|
||||
return sb;
|
||||
}
|
||||
@@ -198,8 +160,7 @@ public class BugReporter {
|
||||
// copy text to clipboard
|
||||
GuiBase.getInterface().copyToClipboard(text);
|
||||
GuiBase.getInterface().browseToUrl(FORUM_URL);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
SOptionPane.showMessageDialog("Sorry, a problem occurred while opening the forum in your default browser.",
|
||||
"A problem occurred", SOptionPane.ERROR_ICON);
|
||||
}
|
||||
@@ -207,7 +168,7 @@ public class BugReporter {
|
||||
|
||||
public static void saveToFile(final String text) {
|
||||
File f;
|
||||
long curTime = System.currentTimeMillis();
|
||||
final long curTime = System.currentTimeMillis();
|
||||
for (int i = 0;; i++) {
|
||||
final String name = String.format("%TF-%02d.txt", curTime, i);
|
||||
f = new File(name);
|
||||
@@ -228,7 +189,10 @@ public class BugReporter {
|
||||
"Error saving file", SOptionPane.ERROR_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
// disable instantiation
|
||||
private BugReporter() { }
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private BugReporter() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,35 +45,35 @@ public class GauntletIO {
|
||||
return xStream;
|
||||
}
|
||||
|
||||
public static File getGauntletFile(String name) {
|
||||
public static File getGauntletFile(final String name) {
|
||||
return new File(ForgeConstants.GAUNTLET_DIR.userPrefLoc, name + SUFFIX_DATA);
|
||||
}
|
||||
|
||||
public static File getGauntletFile(GauntletData gd) {
|
||||
public static File getGauntletFile(final GauntletData gd) {
|
||||
return getGauntletFile(gd.getName());
|
||||
}
|
||||
|
||||
public static File[] getGauntletFilesUnlocked(final String prefix) {
|
||||
final FilenameFilter filter = new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
public boolean accept(final File dir, final String name) {
|
||||
return ((prefix == null || name.startsWith(prefix)) && name.endsWith(SUFFIX_DATA));
|
||||
}
|
||||
};
|
||||
|
||||
File folder = new File(ForgeConstants.GAUNTLET_DIR.userPrefLoc);
|
||||
final File folder = new File(ForgeConstants.GAUNTLET_DIR.userPrefLoc);
|
||||
return folder.listFiles(filter);
|
||||
}
|
||||
|
||||
public static File[] getGauntletFilesLocked() {
|
||||
final FilenameFilter filter = new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
public boolean accept(final File dir, final String name) {
|
||||
return (name.startsWith(PREFIX_LOCKED) && name.endsWith(SUFFIX_DATA));
|
||||
}
|
||||
};
|
||||
|
||||
File folder = new File(ForgeConstants.GAUNTLET_DIR.defaultLoc);
|
||||
final File folder = new File(ForgeConstants.GAUNTLET_DIR.defaultLoc);
|
||||
return folder.listFiles(filter);
|
||||
}
|
||||
|
||||
@@ -101,8 +101,7 @@ public class GauntletIO {
|
||||
if (zin != null) {
|
||||
try {
|
||||
zin.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (final IOException e) {
|
||||
System.out.println("error closing gauntlet data reader: " + e);
|
||||
}
|
||||
}
|
||||
@@ -110,8 +109,7 @@ public class GauntletIO {
|
||||
if (isCorrupt) {
|
||||
try {
|
||||
xmlSaveFile.delete();
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
System.out.println("error delete corrupt gauntlet file: " + e);
|
||||
}
|
||||
}
|
||||
@@ -145,7 +143,7 @@ public class GauntletIO {
|
||||
@Override
|
||||
public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) {
|
||||
for (final Entry<PaperCard, Integer> e : (CardPool) source) {
|
||||
this.writeCardPrinted(e.getKey(), e.getValue(), writer);
|
||||
writeCardPrinted(e.getKey(), e.getValue(), writer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,15 +159,15 @@ public class GauntletIO {
|
||||
if ("string".equals(nodename)) {
|
||||
result.add(FModel.getMagicDb().getCommonCards().getCard(reader.getValue()));
|
||||
} else if ("card".equals(nodename)) { // new format
|
||||
result.add(this.readCardPrinted(reader), cnt);
|
||||
result.add(readCardPrinted(reader), cnt);
|
||||
}
|
||||
reader.moveUp();
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeCardPrinted(final PaperCard cref, final Integer count, final HierarchicalStreamWriter writer) {
|
||||
private static void writeCardPrinted(final PaperCard cref, final Integer count, final HierarchicalStreamWriter writer) {
|
||||
writer.startNode("card");
|
||||
writer.addAttribute("c", cref.getName());
|
||||
writer.addAttribute("s", cref.getEdition());
|
||||
@@ -181,17 +179,19 @@ public class GauntletIO {
|
||||
writer.endNode();
|
||||
}
|
||||
|
||||
private PaperCard readCardPrinted(final HierarchicalStreamReader reader) {
|
||||
private static PaperCard readCardPrinted(final HierarchicalStreamReader reader) {
|
||||
final String name = reader.getAttribute("c");
|
||||
final String set = reader.getAttribute("s");
|
||||
final String sIndex = reader.getAttribute("i");
|
||||
final short index = StringUtils.isNumeric(sIndex) ? Short.parseShort(sIndex) : 0;
|
||||
final boolean foil = "1".equals(reader.getAttribute("foil"));
|
||||
PaperCard card = FModel.getMagicDb().getCommonCards().getCard(name, set, index);
|
||||
if ( null == card )
|
||||
if (null == card) {
|
||||
card = FModel.getMagicDb().getCommonCards().getCard(name, set, -1);
|
||||
if ( null == card )
|
||||
}
|
||||
if (null == card) {
|
||||
throw new RuntimeException("Unsupported card found in quest save: " + name + " from edition " + set);
|
||||
}
|
||||
return foil ? FModel.getMagicDb().getCommonCards().getFoiled(card) : card;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,7 @@ package forge.interfaces;
|
||||
import forge.UiCommand;
|
||||
import forge.assets.FSkinProp;
|
||||
|
||||
public interface IButton {
|
||||
void setEnabled(boolean b0);
|
||||
void setVisible(boolean b0);
|
||||
void setText(String text0);
|
||||
public interface IButton extends ITextComponent {
|
||||
boolean isSelected();
|
||||
void setSelected(boolean b0);
|
||||
boolean requestFocusInWindow();
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package forge.interfaces;
|
||||
|
||||
public interface ICheckBox {
|
||||
boolean isEnabled();
|
||||
void setEnabled(boolean b0);
|
||||
boolean isVisible();
|
||||
void setVisible(boolean b0);
|
||||
public interface ICheckBox extends IComponent {
|
||||
boolean isSelected();
|
||||
void setSelected(boolean b0);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package forge.interfaces;
|
||||
|
||||
public interface IComboBox<E> {
|
||||
boolean isEnabled();
|
||||
void setEnabled(boolean b0);
|
||||
boolean isVisible();
|
||||
void setVisible(boolean b0);
|
||||
public interface IComboBox<E> extends IComponent {
|
||||
void setSelectedItem(E item);
|
||||
void setSelectedIndex(int index);
|
||||
void addItem(E item);
|
||||
|
||||
8
forge-gui/src/main/java/forge/interfaces/IComponent.java
Normal file
8
forge-gui/src/main/java/forge/interfaces/IComponent.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package forge.interfaces;
|
||||
|
||||
public interface IComponent {
|
||||
boolean isEnabled();
|
||||
void setEnabled(boolean b0);
|
||||
boolean isVisible();
|
||||
void setVisible(boolean b0);
|
||||
}
|
||||
@@ -24,7 +24,6 @@ public interface IGuiBase {
|
||||
void invokeInEdtLater(Runnable runnable);
|
||||
void invokeInEdtAndWait(Runnable proc);
|
||||
boolean isGuiThread();
|
||||
IGuiTimer createGuiTimer(Runnable proc, int interval);
|
||||
ISkinImage getSkinIcon(FSkinProp skinProp);
|
||||
ISkinImage getUnskinnedIcon(String path);
|
||||
ISkinImage getCardArt(PaperCard card);
|
||||
|
||||
@@ -68,24 +68,18 @@ public interface IGuiGame {
|
||||
|
||||
String showInputDialog(String message, String title);
|
||||
String showInputDialog(String message, String title, FSkinProp icon);
|
||||
String showInputDialog(String message, String title, FSkinProp icon,
|
||||
String initialInput);
|
||||
String showInputDialog(String message, String title, FSkinProp icon,
|
||||
String initialInput, String[] inputOptions);
|
||||
String showInputDialog(String message, String title, FSkinProp icon, String initialInput);
|
||||
String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions);
|
||||
|
||||
boolean confirm(CardView c, String question);
|
||||
boolean confirm(CardView c, String question, boolean defaultChoice);
|
||||
boolean confirm(CardView c, String question, String[] options);
|
||||
boolean confirm(CardView c, String question, boolean defaultIsYes, String[] options);
|
||||
|
||||
<T> List<T> getChoices(String message, int min, int max, T[] choices);
|
||||
<T> List<T> getChoices(String message, int min, int max,
|
||||
Collection<T> choices);
|
||||
<T> List<T> getChoices(String message, int min, int max,
|
||||
Collection<T> choices, T selected, Function<T, String> display);
|
||||
<T> List<T> getChoices(String message, int min, int max, Collection<T> choices);
|
||||
<T> List<T> getChoices(String message, int min, int max, Collection<T> choices, T selected, Function<T, String> display);
|
||||
|
||||
// Get Integer in range
|
||||
Integer getInteger(String message);
|
||||
Integer getInteger(String message, int min);
|
||||
Integer getInteger(String message, int min, int max);
|
||||
Integer getInteger(String message, int min, int max, boolean sortDesc);
|
||||
@@ -93,7 +87,7 @@ public interface IGuiGame {
|
||||
|
||||
/**
|
||||
* Convenience for getChoices(message, 0, 1, choices).
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* is automatically inferred.
|
||||
* @param message
|
||||
@@ -108,50 +102,47 @@ public interface IGuiGame {
|
||||
<T> T oneOrNone(String message, T[] choices);
|
||||
<T> T oneOrNone(String message, Collection<T> choices);
|
||||
|
||||
// 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.
|
||||
* @return One of {@code choices}. Can only be {@code null} if {@code choices} is empty.
|
||||
*/
|
||||
<T> T one(String message, T[] choices);
|
||||
<T> T one(String message, Collection<T> choices);
|
||||
<T> List<T> noneOrMany(String message, Collection<T> choices);
|
||||
|
||||
<T> void reveal(String message, T item);
|
||||
<T> void reveal(String message, T[] items);
|
||||
<T> void reveal(String message, Collection<T> items);
|
||||
|
||||
<T> List<T> many(String title, String topCaption, int min, int max,
|
||||
List<T> sourceChoices);
|
||||
<T> List<T> many(String title, String topCaption, int cnt,
|
||||
List<T> sourceChoices);
|
||||
<T> List<T> many(String title, String topCaption, int cnt,
|
||||
List<T> sourceChoices, CardView c);
|
||||
<T> List<T> many(String title, String topCaption, int min, int max,
|
||||
List<T> sourceChoices, CardView c);
|
||||
<T> List<T> many(String title, String topCaption, int cnt, List<T> sourceChoices, CardView c);
|
||||
<T> List<T> many(String title, String topCaption, int min, int max, List<T> sourceChoices, CardView c);
|
||||
|
||||
<T> List<T> order(String title, String top, List<T> sourceChoices);
|
||||
<T> List<T> order(String title, String top, List<T> sourceChoices, CardView c);
|
||||
<T> List<T> order(String title, String top, int remainingObjectsMin,
|
||||
int remainingObjectsMax, List<T> sourceChoices,
|
||||
List<T> destChoices, CardView referenceCard,
|
||||
boolean sideboardingMode);
|
||||
<T> List<T> order(String title, String top, int remainingObjectsMin, int remainingObjectsMax, List<T> sourceChoices, List<T> destChoices, CardView referenceCard, boolean sideboardingMode);
|
||||
|
||||
/**
|
||||
* Ask the user to insert an object into a list of other objects. The
|
||||
* current implementation requires the user to cancel in order to get the
|
||||
* new item to be the first item in the resulting list.
|
||||
*
|
||||
* @param title
|
||||
* the dialog title.
|
||||
* @param newItem
|
||||
* the object to insert.
|
||||
* @param oldItems
|
||||
* the list of objects.
|
||||
* @return A shallow copy of the list of objects, with newItem inserted.
|
||||
*/
|
||||
<T> List<T> insertInList(String title, T newItem, List<T> oldItems);
|
||||
|
||||
List<PaperCard> sideboard(CardPool sideboard, CardPool main);
|
||||
GameEntityView chooseSingleEntityForEffect(String title,
|
||||
Collection<? extends GameEntityView> optionList,
|
||||
DelayedReveal delayedReveal, boolean isOptional);
|
||||
void setCard(CardView card);
|
||||
GameEntityView chooseSingleEntityForEffect(String title, Collection<? extends GameEntityView> optionList, DelayedReveal delayedReveal, boolean isOptional); void setCard(CardView card);
|
||||
void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi);
|
||||
boolean openZones(Collection<ZoneType> zones, Map<PlayerView, Object> players);
|
||||
void restoreOldZones(Map<PlayerView, Object> playersToRestoreZonesFor);
|
||||
@@ -170,7 +161,6 @@ public interface IGuiGame {
|
||||
void setShouldAutoYield(String key, boolean autoYield);
|
||||
boolean shouldAlwaysAcceptTrigger(int trigger);
|
||||
boolean shouldAlwaysDeclineTrigger(int trigger);
|
||||
boolean shouldAlwaysAskTrigger(int trigger);
|
||||
void setShouldAlwaysAcceptTrigger(int trigger);
|
||||
void setShouldAlwaysDeclineTrigger(int trigger);
|
||||
void setShouldAlwaysAskTrigger(int trigger);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package forge.interfaces;
|
||||
|
||||
public interface IGuiTimer {
|
||||
void setInterval(int interval0);
|
||||
void start();
|
||||
void stop();
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package forge.interfaces;
|
||||
|
||||
import forge.match.GameLobby;
|
||||
import forge.net.server.RemoteClient;
|
||||
|
||||
public interface ILobby {
|
||||
GameLobby getState();
|
||||
int login(RemoteClient client);
|
||||
void logout(RemoteClient client);
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package forge.interfaces;
|
||||
|
||||
public interface IProgressBar {
|
||||
void setDescription(final String s0);
|
||||
void setDescription(String s0);
|
||||
void setValue(int value0);
|
||||
void reset();
|
||||
void setShowETA(boolean b0);
|
||||
void setShowCount(boolean b0);
|
||||
boolean isPercentMode();
|
||||
void setPercentMode(boolean percentMode0);
|
||||
int getMaximum();
|
||||
void setMaximum(int maximum0);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package forge.interfaces;
|
||||
|
||||
public interface ITextComponent extends IComponent {
|
||||
String getText();
|
||||
void setText(String text0);
|
||||
}
|
||||
@@ -1,11 +1,5 @@
|
||||
package forge.interfaces;
|
||||
|
||||
public interface ITextField {
|
||||
boolean isEnabled();
|
||||
void setEnabled(boolean b0);
|
||||
boolean isVisible();
|
||||
void setVisible(boolean b0);
|
||||
String getText();
|
||||
void setText(String text0);
|
||||
public interface ITextField extends ITextComponent {
|
||||
boolean requestFocusInWindow();
|
||||
}
|
||||
|
||||
@@ -6,30 +6,34 @@
|
||||
* 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.itemmanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import forge.item.InventoryItem;
|
||||
import forge.itemmanager.ItemColumnConfig.SortState;
|
||||
import forge.util.ItemPool;
|
||||
import forge.util.ItemPoolSorter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* ItemManagerModel class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* the generic type
|
||||
* @author Forge
|
||||
@@ -44,7 +48,7 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
|
||||
/**
|
||||
* Instantiates a new list view model
|
||||
*
|
||||
*
|
||||
* @param ItemManager0
|
||||
* @param genericType0
|
||||
*/
|
||||
@@ -67,13 +71,7 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
/** Whether list is in sync. */
|
||||
protected transient boolean isListInSync = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* getOrderedList.
|
||||
*
|
||||
* @return List<Entry<T, Integer>>
|
||||
*/
|
||||
public final List<Entry<T, Integer>> getOrderedList() {
|
||||
public List<Entry<T, Integer>> getOrderedList() {
|
||||
if (!this.isListInSync) {
|
||||
this.rebuildOrderedList();
|
||||
}
|
||||
@@ -90,19 +88,13 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
this.isListInSync = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* countDistinct.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int countDistinct() {
|
||||
public int countDistinct() {
|
||||
return this.data.countDistinct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all items in the model.
|
||||
*
|
||||
*
|
||||
* @return ItemPoolView<T>
|
||||
*/
|
||||
public ItemPool<T> getItems() {
|
||||
@@ -111,10 +103,10 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
|
||||
/**
|
||||
* Removes a item from the model.
|
||||
*
|
||||
*
|
||||
* @param item0   {@link forge.Item} object
|
||||
*/
|
||||
public void removeItem(final T item0, int qty) {
|
||||
public void removeItem(final T item0, final int qty) {
|
||||
if (isInfinite()) { return; }
|
||||
|
||||
final boolean wasThere = this.data.count(item0) > 0;
|
||||
@@ -125,7 +117,7 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
}
|
||||
|
||||
public void replaceAll(final T item0, final T replacement0) {
|
||||
int count = this.data.count(item0);
|
||||
final int count = this.data.count(item0);
|
||||
if (count > 0) {
|
||||
this.data.removeAll(item0);
|
||||
this.data.add(replacement0, count);
|
||||
@@ -135,17 +127,17 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
|
||||
/**
|
||||
* Adds a item to the model.
|
||||
*
|
||||
*
|
||||
* @param item0   {@link forge.Item} object.
|
||||
*/
|
||||
public void addItem(final T item0, int qty) {
|
||||
public void addItem(final T item0, final int qty) {
|
||||
this.data.add(item0, qty);
|
||||
isListInSync = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple copies of multiple items to the model.
|
||||
*
|
||||
*
|
||||
* @param items0   {@link java.lang.Iterable}<Entry<T, Integer>>
|
||||
*/
|
||||
public void addItems(final Iterable<Entry<T, Integer>> items0) {
|
||||
@@ -154,17 +146,17 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this table's pool of items is in infinite supply. If false, items in the
|
||||
* table have a limited number of copies.
|
||||
* Sets whether this table's pool of items is in infinite supply. If false,
|
||||
* items in the table have a limited number of copies.
|
||||
*/
|
||||
public void setInfinite(boolean infinite) {
|
||||
public void setInfinite(final boolean infinite) {
|
||||
this.infiniteSupply = infinite;
|
||||
}
|
||||
|
||||
public boolean isInfinite() {
|
||||
return infiniteSupply;
|
||||
}
|
||||
|
||||
|
||||
public CascadeManager getCascadeManager() {
|
||||
return cascadeManager;
|
||||
}
|
||||
@@ -188,13 +180,12 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
// Adds a column to sort cascade list.
|
||||
// If column is first in the cascade, inverts direction of sort.
|
||||
// Otherwise, sorts in ascending direction.
|
||||
public void add(final ItemColumn col0, boolean forSetup) {
|
||||
public void add(final ItemColumn col0, final boolean forSetup) {
|
||||
this.sorter = null;
|
||||
|
||||
if (forSetup) { //just add column unmodified if setting up sort columns
|
||||
this.colsToSort.add(0, (ItemColumn) col0);
|
||||
}
|
||||
else {
|
||||
this.colsToSort.add(0, col0);
|
||||
} else {
|
||||
if (colsToSort.size() > 0 && colsToSort.get(0).equals(col0)) { //if column already at top level, just invert
|
||||
col0.getConfig().setSortPriority(1);
|
||||
col0.getConfig().setSortState(col0.getConfig().getSortState() == SortState.ASC ? SortState.DESC : SortState.ASC);
|
||||
@@ -203,7 +194,7 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
this.colsToSort.remove(col0);
|
||||
col0.getConfig().setSortPriority(1);
|
||||
col0.getConfig().setSortState(col0.getConfig().getDefaultSortState());
|
||||
this.colsToSort.add(0, (ItemColumn) col0);
|
||||
this.colsToSort.add(0, col0);
|
||||
}
|
||||
|
||||
//decrement sort priority on remaining columns
|
||||
@@ -236,8 +227,7 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
}
|
||||
|
||||
private Sorter createSorter() {
|
||||
final List<ItemPoolSorter<InventoryItem>> oneColSorters
|
||||
= new ArrayList<ItemPoolSorter<InventoryItem>>(maxSortDepth);
|
||||
final List<ItemPoolSorter<InventoryItem>> oneColSorters = new ArrayList<ItemPoolSorter<InventoryItem>>(maxSortDepth);
|
||||
|
||||
for (final ItemColumn col : this.colsToSort) {
|
||||
oneColSorters.add(new ItemPoolSorter<InventoryItem>(
|
||||
@@ -253,9 +243,9 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
private final int cntFields;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Sorter Constructor.
|
||||
*
|
||||
*
|
||||
* @param sorters0
|
||||
* a List<TableSorter<InventoryItem>>
|
||||
*/
|
||||
@@ -266,7 +256,7 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -286,13 +276,13 @@ public final class ItemManagerModel<T extends InventoryItem> {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyComparator implements Comparator<Entry<T, Integer>> {
|
||||
private final class MyComparator implements Comparator<Entry<T, Integer>> {
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int compare(Entry<T, Integer> o1, Entry<T, Integer> o2) {
|
||||
public int compare(final Entry<T, Integer> o1, final Entry<T, Integer> o2) {
|
||||
return cascadeManager.getSorter().compare((Entry<InventoryItem, Integer>)o1, (Entry<InventoryItem, Integer>)o2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package forge.itemmanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.CardRulesPredicates;
|
||||
@@ -8,15 +16,7 @@ import forge.interfaces.IComboBox;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.util.ComparableOp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Static methods for working with top-level editor methods,
|
||||
* included but not limited to preferences IO, icon generation,
|
||||
* and stats analysis.
|
||||
@@ -65,25 +65,25 @@ public final class SItemManagerUtil {
|
||||
public final Predicate<CardRules> predicate;
|
||||
public final String label;
|
||||
|
||||
private StatTypes(FSkinProp skinProp0, Predicate<CardRules> predicate0, String label0) {
|
||||
private StatTypes(final FSkinProp skinProp0, final Predicate<CardRules> predicate0, final String label0) {
|
||||
skinProp = skinProp0;
|
||||
predicate = predicate0;
|
||||
label = label0;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getItemDisplayString(InventoryItem item, int qty, boolean forTitle) {
|
||||
ArrayList<InventoryItem> items = new ArrayList<InventoryItem>();
|
||||
public static String getItemDisplayString(final InventoryItem item, final int qty, final boolean forTitle) {
|
||||
final List<InventoryItem> items = new ArrayList<InventoryItem>();
|
||||
items.add(item);
|
||||
return getItemDisplayString(items, qty, forTitle);
|
||||
}
|
||||
public static String getItemDisplayString(Iterable<? extends InventoryItem> items, int qty, boolean forTitle) {
|
||||
public static String getItemDisplayString(final Iterable<? extends InventoryItem> items, final int qty, final boolean forTitle) {
|
||||
//determine shared type among items
|
||||
int itemCount = 0;
|
||||
String sharedType = null;
|
||||
boolean checkForSharedType = true;
|
||||
|
||||
for (InventoryItem item : items) {
|
||||
for (final InventoryItem item : items) {
|
||||
if (checkForSharedType) {
|
||||
if (sharedType == null) {
|
||||
sharedType = item.getItemType();
|
||||
@@ -122,9 +122,9 @@ public final class SItemManagerUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String buildDisplayList(Iterable<Entry<InventoryItem, Integer>> items) {
|
||||
ArrayList<Entry<InventoryItem, Integer>> sorted = new ArrayList<Entry<InventoryItem, Integer>>();
|
||||
for (Entry<InventoryItem, Integer> itemEntry : items) {
|
||||
public static String buildDisplayList(final Iterable<Entry<InventoryItem, Integer>> items) {
|
||||
final List<Entry<InventoryItem, Integer>> sorted = new ArrayList<Entry<InventoryItem, Integer>>();
|
||||
for (final Entry<InventoryItem, Integer> itemEntry : items) {
|
||||
sorted.add(itemEntry);
|
||||
}
|
||||
Collections.sort(sorted, new Comparator<Entry<InventoryItem, Integer>>() {
|
||||
@@ -133,8 +133,8 @@ public final class SItemManagerUtil {
|
||||
return x.getKey().toString().compareTo(y.getKey().toString());
|
||||
}
|
||||
});
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Entry<InventoryItem, Integer> itemEntry : sorted) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (final Entry<InventoryItem, Integer> itemEntry : sorted) {
|
||||
builder.append("\n" + itemEntry.getValue() + " * " + itemEntry.getKey().toString());
|
||||
}
|
||||
return builder.toString();
|
||||
@@ -145,16 +145,16 @@ public final class SItemManagerUtil {
|
||||
private static final ColumnDef[] CARD_PILEBY_OPTIONS = { ColumnDef.CMC, ColumnDef.COLOR, ColumnDef.NAME, ColumnDef.COST, ColumnDef.TYPE, ColumnDef.RARITY, ColumnDef.SET };
|
||||
private static final ColumnDef[] DECK_PILEBY_OPTIONS = { ColumnDef.DECK_COLOR, ColumnDef.DECK_FOLDER, ColumnDef.NAME, ColumnDef.DECK_FORMAT, ColumnDef.DECK_EDITION };
|
||||
|
||||
public static void populateImageViewOptions(IItemManager<?> itemManager, IComboBox<Object> cbGroupByOptions, IComboBox<Object> cbPileByOptions) {
|
||||
boolean isDeckManager = itemManager.getGenericType().equals(DeckProxy.class);
|
||||
GroupDef[] groupByOptions = isDeckManager ? DECK_GROUPBY_OPTIONS : CARD_GROUPBY_OPTIONS;
|
||||
ColumnDef[] pileByOptions = isDeckManager ? DECK_PILEBY_OPTIONS : CARD_PILEBY_OPTIONS;
|
||||
public static void populateImageViewOptions(final IItemManager<?> itemManager, final IComboBox<Object> cbGroupByOptions, final IComboBox<Object> cbPileByOptions) {
|
||||
final boolean isDeckManager = itemManager.getGenericType().equals(DeckProxy.class);
|
||||
final GroupDef[] groupByOptions = isDeckManager ? DECK_GROUPBY_OPTIONS : CARD_GROUPBY_OPTIONS;
|
||||
final ColumnDef[] pileByOptions = isDeckManager ? DECK_PILEBY_OPTIONS : CARD_PILEBY_OPTIONS;
|
||||
cbGroupByOptions.addItem("(none)");
|
||||
cbPileByOptions.addItem("(none)");
|
||||
for (GroupDef option : groupByOptions) {
|
||||
for (final GroupDef option : groupByOptions) {
|
||||
cbGroupByOptions.addItem(option);
|
||||
}
|
||||
for (ColumnDef option : pileByOptions) {
|
||||
for (final ColumnDef option : pileByOptions) {
|
||||
cbPileByOptions.addItem(option);
|
||||
}
|
||||
cbGroupByOptions.setSelectedIndex(0);
|
||||
|
||||
@@ -6,17 +6,29 @@
|
||||
* 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 java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Stack;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
import forge.card.CardEdition;
|
||||
@@ -30,8 +42,8 @@ import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.model.CardBlock;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.HttpUtil;
|
||||
import forge.util.ItemPool;
|
||||
@@ -39,16 +51,8 @@ import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
*
|
||||
* Booster Draft Format.
|
||||
*
|
||||
*/
|
||||
public class BoosterDraft implements IBoosterDraft {
|
||||
private final BoosterDraftAI draftAI = new BoosterDraftAI();
|
||||
@@ -67,7 +71,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
protected final List<Supplier<List<PaperCard>>> product = new ArrayList<Supplier<List<PaperCard>>>();
|
||||
|
||||
public static BoosterDraft createDraft(final LimitedPoolType draftType) {
|
||||
BoosterDraft draft = new BoosterDraft(draftType);
|
||||
final BoosterDraft draft = new BoosterDraft(draftType);
|
||||
if (!draft.generateProduct()) { return null; }
|
||||
return draft;
|
||||
}
|
||||
@@ -75,7 +79,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
protected boolean generateProduct() {
|
||||
switch (this.draftFormat) {
|
||||
case Full: // Draft from all cards in Forge
|
||||
Supplier<List<PaperCard>> s = new UnOpenedProduct(SealedProduct.Template.genericBooster);
|
||||
final Supplier<List<PaperCard>> s = new UnOpenedProduct(SealedProduct.Template.genericBooster);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
this.product.add(s);
|
||||
@@ -85,11 +89,12 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
|
||||
case Block: // Draft from cards by block or set
|
||||
case FantasyBlock:
|
||||
List<CardBlock> blocks = new ArrayList<CardBlock>();
|
||||
IStorage<CardBlock> storage = this.draftFormat == LimitedPoolType.Block
|
||||
? FModel.getBlocks() : FModel.getFantasyBlocks();
|
||||
final List<CardBlock> blocks = new ArrayList<CardBlock>();
|
||||
final IStorage<CardBlock> storage = this.draftFormat == LimitedPoolType.Block
|
||||
? FModel.getBlocks()
|
||||
: FModel.getFantasyBlocks();
|
||||
|
||||
for (CardBlock b : storage) {
|
||||
for (final CardBlock b : storage) {
|
||||
if (b.getCntBoostersDraft() > 0) {
|
||||
blocks.add(b);
|
||||
}
|
||||
@@ -109,7 +114,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
sets.add(cardSets.get(k).getCode());
|
||||
}
|
||||
|
||||
for (String setCode : block.getMetaSetNames()) {
|
||||
for (final String setCode : block.getMetaSetNames()) {
|
||||
if (block.getMetaSet(setCode).isDraftable()) {
|
||||
sets.push(setCode); // to the beginning
|
||||
}
|
||||
@@ -127,7 +132,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
}
|
||||
}
|
||||
else {
|
||||
IUnOpenedProduct product1 = block.getBooster(sets.get(0));
|
||||
final IUnOpenedProduct product1 = block.getBooster(sets.get(0));
|
||||
|
||||
for (int i = 0; i < nPacks; i++) {
|
||||
this.product.add(product1);
|
||||
@@ -138,7 +143,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
break;
|
||||
|
||||
case Custom:
|
||||
final List<CustomLimited> myDrafts = this.loadCustomDrafts();
|
||||
final List<CustomLimited> myDrafts = loadCustomDrafts();
|
||||
|
||||
if (myDrafts.isEmpty()) {
|
||||
SOptionPane.showMessageDialog("No custom draft files found.");
|
||||
@@ -159,9 +164,9 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BoosterDraft createDraft(final LimitedPoolType draftType, final CardBlock block, final String[] boosters) {
|
||||
BoosterDraft draft = new BoosterDraft(draftType);
|
||||
|
||||
public static BoosterDraft createDraft(final LimitedPoolType draftType, final CardBlock block, final String[] boosters) {
|
||||
final BoosterDraft draft = new BoosterDraft(draftType);
|
||||
|
||||
final int nPacks = boosters.length;
|
||||
|
||||
for (int i = 0; i < nPacks; i++) {
|
||||
@@ -198,7 +203,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
|
||||
final SealedProduct.Template tpl = draft.getSealedProductTemplate();
|
||||
|
||||
UnOpenedProduct toAdd = new UnOpenedProduct(tpl, dPool);
|
||||
final UnOpenedProduct toAdd = new UnOpenedProduct(tpl, dPool);
|
||||
toAdd.setLimitedPool(draft.isSingleton());
|
||||
for (int i = 0; i < draft.getNumPacks(); i++) {
|
||||
this.product.add(toAdd);
|
||||
@@ -208,7 +213,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
}
|
||||
|
||||
/** Looks for draft files, reads them, returns a list. */
|
||||
private List<CustomLimited> loadCustomDrafts() {
|
||||
private static List<CustomLimited> loadCustomDrafts() {
|
||||
String[] dList;
|
||||
final ArrayList<CustomLimited> customs = new ArrayList<CustomLimited>();
|
||||
|
||||
@@ -237,7 +242,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
* <p>
|
||||
* nextChoice.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a {@link forge.deck.CardPool} object.
|
||||
*/
|
||||
@Override
|
||||
@@ -247,7 +252,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
}
|
||||
|
||||
this.computerChoose();
|
||||
CardPool result = new CardPool();
|
||||
final CardPool result = new CardPool();
|
||||
result.addAllFlat(this.pack.get(this.getCurrentBoosterIndex()));
|
||||
return result;
|
||||
}
|
||||
@@ -256,7 +261,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
* <p>
|
||||
* get8BoosterPack.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return an array of {@link forge.deck.CardPool} objects.
|
||||
*/
|
||||
public List<List<PaperCard>> get8BoosterPack() {
|
||||
@@ -281,7 +286,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
* <p>
|
||||
* getDecks.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return an array of {@link forge.deck.Deck} objects.
|
||||
*/
|
||||
@Override
|
||||
@@ -305,7 +310,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
} // computerChoose()
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Get the current booster index.
|
||||
* @return int
|
||||
*/
|
||||
@@ -317,7 +322,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
* <p>
|
||||
* hasNextChoice.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
@Override
|
||||
@@ -374,8 +379,8 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> outDraftData = new ArrayList<String>();
|
||||
for (Entry<String, Float> key : draftPicks.entrySet()) {
|
||||
final List<String> outDraftData = new ArrayList<String>();
|
||||
for (final Entry<String, Float> key : draftPicks.entrySet()) {
|
||||
outDraftData.add(key.getValue() + "|" + key.getKey());
|
||||
}
|
||||
Collections.sort(outDraftData);
|
||||
@@ -388,8 +393,8 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
}
|
||||
|
||||
private static List<String> getSetCombos(final List<String> setz) {
|
||||
String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
|
||||
List<String> setCombos = new ArrayList<String>();
|
||||
final String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
|
||||
final List<String> setCombos = new ArrayList<String>();
|
||||
if (sets.length >= 2) {
|
||||
setCombos.add(String.format("%s/%s/%s", sets[0], sets[0], sets[0]));
|
||||
setCombos.add(String.format("%s/%s/%s", sets[0], sets[0], sets[1]));
|
||||
|
||||
@@ -6,17 +6,23 @@
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.deck.Deck;
|
||||
@@ -24,17 +30,11 @@ import forge.item.PaperCard;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* BoosterDraftAI class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
@@ -62,7 +62,7 @@ public class BoosterDraftAI {
|
||||
* <p>
|
||||
* Choose a CardPrinted from the list given.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param chooseFrom
|
||||
* List of CardPrinted
|
||||
* @param player
|
||||
@@ -74,22 +74,24 @@ public class BoosterDraftAI {
|
||||
System.out.println("Player[" + player + "] pack: " + chooseFrom.toString());
|
||||
}
|
||||
|
||||
DeckColors deckCols = this.playerColors.get(player);
|
||||
ColorSet currentChoice = deckCols.getChosenColors();
|
||||
boolean canAddMoreColors = deckCols.canChoseMoreColors();
|
||||
|
||||
List<Pair<PaperCard, Double>> rankedCards = rankCards(chooseFrom);
|
||||
|
||||
for(Pair<PaperCard, Double> p : rankedCards) {
|
||||
final DeckColors deckCols = this.playerColors.get(player);
|
||||
final ColorSet currentChoice = deckCols.getChosenColors();
|
||||
final boolean canAddMoreColors = deckCols.canChoseMoreColors();
|
||||
|
||||
final List<Pair<PaperCard, Double>> rankedCards = rankCards(chooseFrom);
|
||||
|
||||
for (final Pair<PaperCard, Double> p : rankedCards) {
|
||||
double valueBoost = 0;
|
||||
|
||||
// If a card is not ai playable, somewhat decrease its rating
|
||||
if( p.getKey().getRules().getAiHints().getRemAIDecks() )
|
||||
if( p.getKey().getRules().getAiHints().getRemAIDecks() ) {
|
||||
valueBoost = TAKE_BEST_THRESHOLD;
|
||||
}
|
||||
|
||||
// if I cannot choose more colors, and the card cannot be played with chosen colors, decrease its rating.
|
||||
if( !canAddMoreColors && !p.getKey().getRules().getManaCost().canBePaidWithAvaliable(currentChoice.getColor()))
|
||||
if( !canAddMoreColors && !p.getKey().getRules().getManaCost().canBePaidWithAvaliable(currentChoice.getColor())) {
|
||||
valueBoost = TAKE_BEST_THRESHOLD * 3;
|
||||
}
|
||||
|
||||
if (valueBoost > 0) {
|
||||
p.setValue(p.getValue() + valueBoost);
|
||||
@@ -100,11 +102,11 @@ public class BoosterDraftAI {
|
||||
double bestRanking = Double.MAX_VALUE;
|
||||
PaperCard bestPick = null;
|
||||
final List<PaperCard> possiblePick = new ArrayList<PaperCard>();
|
||||
for(Pair<PaperCard, Double> p : rankedCards) {
|
||||
double rating = p.getValue();
|
||||
for (final Pair<PaperCard, Double> p : rankedCards) {
|
||||
final double rating = p.getValue();
|
||||
if(rating <= bestRanking + .01) {
|
||||
if (rating < bestRanking) {
|
||||
// found a better card start a new list
|
||||
// found a better card start a new list
|
||||
possiblePick.clear();
|
||||
bestRanking = rating;
|
||||
}
|
||||
@@ -114,12 +116,13 @@ public class BoosterDraftAI {
|
||||
|
||||
bestPick = Aggregates.random(possiblePick);
|
||||
|
||||
if (canAddMoreColors)
|
||||
if (canAddMoreColors) {
|
||||
deckCols.addColorsOf(bestPick);
|
||||
|
||||
}
|
||||
|
||||
System.out.println("Player[" + player + "] picked: " + bestPick + " ranking of " + bestRanking);
|
||||
this.deck.get(player).add(bestPick);
|
||||
|
||||
|
||||
return bestPick;
|
||||
}
|
||||
|
||||
@@ -127,14 +130,14 @@ public class BoosterDraftAI {
|
||||
* Sort cards by rank. Note that if pack has cards from different editions,
|
||||
* they could have the same rank. Basic lands and unrecognised cards are
|
||||
* rated worse than all other possible picks.
|
||||
*
|
||||
*
|
||||
* @param chooseFrom
|
||||
* List of cards
|
||||
* @return map of rankings
|
||||
*/
|
||||
private List<Pair<PaperCard, Double>> rankCards(final Iterable<PaperCard> chooseFrom) {
|
||||
List<Pair<PaperCard, Double>> rankedCards = new ArrayList<Pair<PaperCard,Double>>();
|
||||
for (PaperCard card : chooseFrom) {
|
||||
private static List<Pair<PaperCard, Double>> rankCards(final Iterable<PaperCard> chooseFrom) {
|
||||
final List<Pair<PaperCard, Double>> rankedCards = new ArrayList<Pair<PaperCard,Double>>();
|
||||
for (final PaperCard card : chooseFrom) {
|
||||
Double rank;
|
||||
if (MagicColor.Constant.BASIC_LANDS.contains(card.getName())) {
|
||||
rank = RANK_UNPICKABLE;
|
||||
@@ -155,7 +158,7 @@ public class BoosterDraftAI {
|
||||
* <p>
|
||||
* getDecks.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return an array of {@link forge.deck.Deck} objects.
|
||||
*/
|
||||
public Deck[] getDecks() {
|
||||
@@ -186,7 +189,7 @@ public class BoosterDraftAI {
|
||||
|
||||
/**
|
||||
* Gets the bd.
|
||||
*
|
||||
*
|
||||
* @return the bd
|
||||
*/
|
||||
public IBoosterDraft getBd() {
|
||||
@@ -195,7 +198,7 @@ public class BoosterDraftAI {
|
||||
|
||||
/**
|
||||
* Sets the bd.
|
||||
*
|
||||
*
|
||||
* @param bd0
|
||||
* the bd to set
|
||||
*/
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ import forge.util.Aggregates;
|
||||
* <p>
|
||||
* GauntletMini class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: GauntletMini.java $
|
||||
* @since 1.2.xx
|
||||
@@ -47,7 +47,7 @@ public class GauntletMini {
|
||||
private int losses;
|
||||
private boolean gauntletDraft; // Means: Draft game is in Gauntlet-mode, not a single match
|
||||
private GameType gauntletType;
|
||||
private List<RegisteredPlayer> aiOpponents = new ArrayList<RegisteredPlayer>();
|
||||
private final List<RegisteredPlayer> aiOpponents = new ArrayList<RegisteredPlayer>();
|
||||
|
||||
public GauntletMini() {
|
||||
currentRound = 1;
|
||||
@@ -87,10 +87,10 @@ public class GauntletMini {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Setup and launch the gauntlet.
|
||||
* Note: The AI decks are connected to the human deck.
|
||||
*
|
||||
*
|
||||
* @param rounds0
|
||||
* the number of rounds (opponent decks) in this tournament
|
||||
* @param humanDeck0
|
||||
@@ -98,7 +98,7 @@ public class GauntletMini {
|
||||
* @param gauntletType0
|
||||
* game type (Sealed, Draft, Constructed...)
|
||||
*/
|
||||
public void launch(int rounds0, Deck humanDeck0, final GameType gauntletType0) {
|
||||
public void launch(final int rounds0, final Deck humanDeck0, final GameType gauntletType0) {
|
||||
rounds = rounds0;
|
||||
humanDeck = humanDeck0;
|
||||
gauntletType = gauntletType0;
|
||||
|
||||
@@ -1,11 +1,28 @@
|
||||
package forge.limited;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.card.*;
|
||||
import forge.card.CardAiHints;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.CardRulesPredicates;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.DeckHints;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostShard;
|
||||
import forge.deck.CardPool;
|
||||
@@ -18,25 +35,20 @@ import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Limited format deck.
|
||||
*
|
||||
*/
|
||||
public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
private int numSpellsNeeded = 22;
|
||||
private final int numSpellsNeeded = 22;
|
||||
private int landsNeeded = 18;
|
||||
|
||||
private final DeckColors deckColors;
|
||||
private Predicate<CardRules> hasColor;
|
||||
private final List<PaperCard> availableList;
|
||||
private final List<PaperCard> aiPlayables;
|
||||
private List<PaperCard> deckList = new ArrayList<PaperCard>();
|
||||
private List<String> setsWithBasicLands = new ArrayList<String>();
|
||||
private final List<PaperCard> deckList = new ArrayList<PaperCard>();
|
||||
private final List<String> setsWithBasicLands = new ArrayList<String>();
|
||||
// Views for aiPlayable
|
||||
|
||||
private Iterable<PaperCard> colorList;
|
||||
@@ -44,24 +56,24 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
private Iterable<PaperCard> onColorNonCreatures;
|
||||
|
||||
private static final boolean logToConsole = false;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Constructor.
|
||||
*
|
||||
*
|
||||
* @param dList
|
||||
* Cards to build the deck from.
|
||||
* @param pClrs
|
||||
* Chosen colors.
|
||||
*/
|
||||
public LimitedDeckBuilder(List<PaperCard> dList, DeckColors pClrs) {
|
||||
public LimitedDeckBuilder(final List<PaperCard> dList, final DeckColors pClrs) {
|
||||
super(FModel.getMagicDb().getCommonCards(), DeckFormat.Limited);
|
||||
this.availableList = dList;
|
||||
this.deckColors = pClrs;
|
||||
this.colors = pClrs.getChosenColors();
|
||||
|
||||
// removeUnplayables();
|
||||
Iterable<PaperCard> playables = Iterables.filter(availableList,
|
||||
final Iterable<PaperCard> playables = Iterables.filter(availableList,
|
||||
Predicates.compose(CardRulesPredicates.IS_KEPT_IN_AI_DECKS, PaperCard.FN_GET_RULES));
|
||||
this.aiPlayables = Lists.newArrayList(playables);
|
||||
this.availableList.removeAll(getAiPlayables());
|
||||
@@ -72,19 +84,19 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*
|
||||
* @param list
|
||||
* Cards to build the deck from.
|
||||
*/
|
||||
public LimitedDeckBuilder(List<PaperCard> list) {
|
||||
public LimitedDeckBuilder(final List<PaperCard> list) {
|
||||
this(list, new DeckColors());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CardPool getDeck(int size, boolean forAi) {
|
||||
public CardPool getDeck(final int size, final boolean forAi) {
|
||||
return buildDeck().getMain();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* buildDeck.
|
||||
@@ -105,7 +117,7 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
* the set to take basic lands from (pass 'null' for random).
|
||||
* @return the new Deck.
|
||||
*/
|
||||
public Deck buildDeck(String landSetCode) {
|
||||
public Deck buildDeck(final String landSetCode) {
|
||||
// 1. Prepare
|
||||
hasColor = Predicates.or(new MatchColorIdentity(colors), COLORLESS_CARDS);
|
||||
colorList = Iterables.filter(aiPlayables, Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
@@ -118,9 +130,9 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
// aiPlayable has changed, there is no need to create a new iterable.
|
||||
|
||||
// 2. Add any planeswalkers
|
||||
Iterable<PaperCard> onColorWalkers = Iterables.filter(colorList,
|
||||
final Iterable<PaperCard> onColorWalkers = Iterables.filter(colorList,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_PLANESWALKER, PaperCard.FN_GET_RULES));
|
||||
List<PaperCard> walkers = Lists.newArrayList(onColorWalkers);
|
||||
final List<PaperCard> walkers = Lists.newArrayList(onColorWalkers);
|
||||
deckList.addAll(walkers);
|
||||
aiPlayables.removeAll(walkers);
|
||||
|
||||
@@ -140,12 +152,12 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
// 6. If there are still on-color cards, and the average cmc is low, add
|
||||
// a 23rd card.
|
||||
Iterable<PaperCard> nonLands = Iterables.filter(colorList,
|
||||
final Iterable<PaperCard> nonLands = Iterables.filter(colorList,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
|
||||
if (deckList.size() == numSpellsNeeded && getAverageCMC(deckList) < 3) {
|
||||
List<Pair<Double, PaperCard>> list = rankCards(nonLands);
|
||||
final List<Pair<Double, PaperCard>> list = rankCards(nonLands);
|
||||
if (!list.isEmpty()) {
|
||||
PaperCard c = list.get(0).getValue();
|
||||
final PaperCard c = list.get(0).getValue();
|
||||
deckList.add(c);
|
||||
getAiPlayables().remove(c);
|
||||
landsNeeded--;
|
||||
@@ -178,9 +190,9 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
fixDeckSize(clrCnts, landSetCode);
|
||||
|
||||
if (deckList.size() == 40) {
|
||||
Deck result = new Deck(generateName());
|
||||
final Deck result = new Deck(generateName());
|
||||
result.getMain().add(deckList);
|
||||
CardPool cp = result.getOrCreate(DeckSection.Sideboard);
|
||||
final CardPool cp = result.getOrCreate(DeckSection.Sideboard);
|
||||
cp.add(aiPlayables);
|
||||
cp.add(availableList);
|
||||
if (logToConsole) {
|
||||
@@ -194,7 +206,7 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Generate a descriptive name.
|
||||
*
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
private String generateName() {
|
||||
@@ -207,19 +219,19 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
private void debugFinalDeck() {
|
||||
int i = 0;
|
||||
System.out.println("DECK");
|
||||
for (PaperCard c : deckList) {
|
||||
for (final PaperCard c : deckList) {
|
||||
i++;
|
||||
System.out.println(i + ". " + c.toString() + ": " + c.getRules().getManaCost().toString());
|
||||
}
|
||||
i = 0;
|
||||
System.out.println("NOT PLAYABLE");
|
||||
for (PaperCard c : availableList) {
|
||||
for (final PaperCard c : availableList) {
|
||||
i++;
|
||||
System.out.println(i + ". " + c.toString() + ": " + c.getRules().getManaCost().toString());
|
||||
}
|
||||
i = 0;
|
||||
System.out.println("NOT PICKED");
|
||||
for (PaperCard c : getAiPlayables()) {
|
||||
for (final PaperCard c : getAiPlayables()) {
|
||||
i++;
|
||||
System.out.println(i + ". " + c.toString() + ": " + c.getRules().getManaCost().toString());
|
||||
}
|
||||
@@ -228,13 +240,13 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
/**
|
||||
* If the deck does not have 40 cards, fix it. This method should not be
|
||||
* called if the stuff above it is working correctly.
|
||||
*
|
||||
*
|
||||
* @param clrCnts
|
||||
* color counts needed
|
||||
* @param landSetCode
|
||||
* the set to take basic lands from (pass 'null' for random).
|
||||
*/
|
||||
private void fixDeckSize(final int[] clrCnts, String landSetCode) {
|
||||
private void fixDeckSize(final int[] clrCnts, final String landSetCode) {
|
||||
while (deckList.size() > 40) {
|
||||
System.out.println("WARNING: Fixing deck size, currently " + deckList.size() + " cards.");
|
||||
final PaperCard c = deckList.get(MyRandom.getRandom().nextInt(deckList.size() - 1));
|
||||
@@ -273,11 +285,12 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
* Find the sets that have basic lands for the available cards.
|
||||
*/
|
||||
private void findBasicLandSets() {
|
||||
Set<String> sets = new HashSet<String>();
|
||||
for (PaperCard cp : aiPlayables) {
|
||||
CardEdition ee = FModel.getMagicDb().getEditions().get(cp.getEdition());
|
||||
if( !sets.contains(cp.getEdition()) && CardEdition.Predicates.hasBasicLands.apply(ee))
|
||||
final Set<String> sets = new HashSet<String>();
|
||||
for (final PaperCard cp : aiPlayables) {
|
||||
final CardEdition ee = FModel.getMagicDb().getEditions().get(cp.getEdition());
|
||||
if( !sets.contains(cp.getEdition()) && CardEdition.Predicates.hasBasicLands.apply(ee)) {
|
||||
sets.add(cp.getEdition());
|
||||
}
|
||||
}
|
||||
setsWithBasicLands.addAll(sets);
|
||||
if (setsWithBasicLands.isEmpty()) {
|
||||
@@ -287,15 +300,15 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Add lands to fulfill the given color counts.
|
||||
*
|
||||
*
|
||||
* @param clrCnts
|
||||
* @param landSetCode
|
||||
* the set to take basic lands from (pass 'null' for random).
|
||||
*/
|
||||
private void addLands(final int[] clrCnts, String landSetCode) {
|
||||
private void addLands(final int[] clrCnts, final String landSetCode) {
|
||||
// basic lands that are available in the deck
|
||||
Iterable<PaperCard> basicLands = Iterables.filter(aiPlayables, Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, PaperCard.FN_GET_RULES));
|
||||
Set<PaperCard> snowLands = new HashSet<PaperCard>();
|
||||
final Iterable<PaperCard> basicLands = Iterables.filter(aiPlayables, Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, PaperCard.FN_GET_RULES));
|
||||
final Set<PaperCard> snowLands = new HashSet<PaperCard>();
|
||||
|
||||
// total of all ClrCnts
|
||||
int totalColor = 0;
|
||||
@@ -318,13 +331,13 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
}
|
||||
|
||||
// if appropriate snow-covered lands are available, add them
|
||||
for (PaperCard cp : basicLands) {
|
||||
for (final PaperCard cp : basicLands) {
|
||||
if (cp.getName().equals(MagicColor.Constant.SNOW_LANDS.get(i))) {
|
||||
snowLands.add(cp);
|
||||
nLand--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int j = 0; j < nLand; j++) {
|
||||
deckList.add(getBasicLand(i, landSetCode));
|
||||
}
|
||||
@@ -337,13 +350,13 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Get basic land.
|
||||
*
|
||||
*
|
||||
* @param basicLand
|
||||
* @param landSetCode
|
||||
* the set to take basic lands from (pass 'null' for random).
|
||||
* @return card
|
||||
*/
|
||||
private PaperCard getBasicLand(int basicLand, String landSetCode) {
|
||||
private PaperCard getBasicLand(final int basicLand, final String landSetCode) {
|
||||
String set;
|
||||
if (landSetCode == null) {
|
||||
if (setsWithBasicLands.size() > 1) {
|
||||
@@ -362,22 +375,23 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
* Only consider colors that are supposed to be in the deck. It's not worth
|
||||
* putting one land in for that random off-color card we had to stick in at
|
||||
* the end...
|
||||
*
|
||||
*
|
||||
* @return CCnt
|
||||
*/
|
||||
private int[] calculateLandNeeds() {
|
||||
final int[] clrCnts = { 0,0,0,0,0 };
|
||||
|
||||
// count each card color using mana costs
|
||||
for (PaperCard cp : deckList) {
|
||||
for (final PaperCard cp : deckList) {
|
||||
final ManaCost mc = cp.getRules().getManaCost();
|
||||
|
||||
// count each mana symbol in the mana cost
|
||||
for (ManaCostShard shard : mc) {
|
||||
for (final ManaCostShard shard : mc) {
|
||||
for ( int i = 0 ; i < MagicColor.WUBRG.length; i++ ) {
|
||||
byte c = MagicColor.WUBRG[i];
|
||||
if ( shard.canBePaidWithManaOfColor(c) && colors.hasAnyColor(c))
|
||||
final byte c = MagicColor.WUBRG[i];
|
||||
if ( shard.canBePaidWithManaOfColor(c) && colors.hasAnyColor(c)) {
|
||||
clrCnts[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,11 +402,11 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
* Add non-basic lands to the deck.
|
||||
*/
|
||||
private void addNonBasicLands() {
|
||||
List<String> inverseDuals = getInverseDualLandList();
|
||||
Iterable<PaperCard> lands = Iterables.filter(aiPlayables,
|
||||
final List<String> inverseDuals = getInverseDualLandList();
|
||||
final Iterable<PaperCard> lands = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NONBASIC_LAND, PaperCard.FN_GET_RULES));
|
||||
List<Pair<Double, PaperCard>> ranked = rankCards(lands);
|
||||
for (Pair<Double, PaperCard> bean : ranked) {
|
||||
final List<Pair<Double, PaperCard>> ranked = rankCards(lands);
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
if (landsNeeded > 0) {
|
||||
// Throw out any dual-lands for the wrong colors. Assume
|
||||
// everything else is either
|
||||
@@ -413,17 +427,17 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Add a third color to the deck.
|
||||
*
|
||||
*
|
||||
* @param nCards
|
||||
*/
|
||||
private void addThirdColorCards(int nCards) {
|
||||
if (nCards > 0) {
|
||||
Iterable<PaperCard> others = Iterables.filter(aiPlayables,
|
||||
final Iterable<PaperCard> others = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
|
||||
List<Pair<Double, PaperCard>> ranked = rankCards(others);
|
||||
for (Pair<Double, PaperCard> bean : ranked) {
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
// Want a card that has just one "off" color.
|
||||
ColorSet off = colors.getOffColors(bean.getValue().getRules().getColor());
|
||||
final ColorSet off = colors.getOffColors(bean.getValue().getRules().getColor());
|
||||
if (off.isMonoColor()) {
|
||||
colors = ColorSet.fromMask(colors.getColor() | off.getColor());
|
||||
break;
|
||||
@@ -432,10 +446,10 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
hasColor = Predicates.or(new DeckGeneratorBase.MatchColorIdentity(colors),
|
||||
DeckGeneratorBase.COLORLESS_CARDS);
|
||||
Iterable<PaperCard> threeColorList = Iterables.filter(aiPlayables,
|
||||
final Iterable<PaperCard> threeColorList = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
ranked = rankCards(threeColorList);
|
||||
for (Pair<Double, PaperCard> bean : ranked) {
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
if (nCards > 0) {
|
||||
deckList.add(bean.getValue());
|
||||
aiPlayables.remove(bean.getValue());
|
||||
@@ -453,14 +467,14 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Add random cards to the deck.
|
||||
*
|
||||
*
|
||||
* @param nCards
|
||||
*/
|
||||
private void addRandomCards(int nCards) {
|
||||
Iterable<PaperCard> others = Iterables.filter(aiPlayables,
|
||||
final Iterable<PaperCard> others = Iterables.filter(aiPlayables,
|
||||
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
|
||||
List<Pair<Double, PaperCard>> ranked = rankCards(others);
|
||||
for (Pair<Double, PaperCard> bean : ranked) {
|
||||
final List<Pair<Double, PaperCard>> ranked = rankCards(others);
|
||||
for (final Pair<Double, PaperCard> bean : ranked) {
|
||||
if (nCards > 0) {
|
||||
deckList.add(bean.getValue());
|
||||
aiPlayables.remove(bean.getValue());
|
||||
@@ -477,15 +491,15 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Add highest ranked non-creatures to the deck.
|
||||
*
|
||||
*
|
||||
* @param nonCreatures
|
||||
* cards to choose from
|
||||
* @param num
|
||||
*/
|
||||
private void addNonCreatures(List<Pair<Double, PaperCard>> nonCreatures, int num) {
|
||||
for (Pair<Double, PaperCard> bean : nonCreatures) {
|
||||
private void addNonCreatures(final List<Pair<Double, PaperCard>> nonCreatures, int num) {
|
||||
for (final Pair<Double, PaperCard> bean : nonCreatures) {
|
||||
if (num > 0) {
|
||||
PaperCard cardToAdd = bean.getValue();
|
||||
final PaperCard cardToAdd = bean.getValue();
|
||||
deckList.add(cardToAdd);
|
||||
num--;
|
||||
getAiPlayables().remove(cardToAdd);
|
||||
@@ -502,29 +516,29 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Add cards that work well with the given card.
|
||||
*
|
||||
*
|
||||
* @param cardToAdd
|
||||
* card being checked
|
||||
* @param num
|
||||
* number of cards
|
||||
* @return number left after adding
|
||||
*/
|
||||
private int addDeckHintsCards(PaperCard cardToAdd, int num) {
|
||||
private int addDeckHintsCards(final PaperCard cardToAdd, int num) {
|
||||
// cards with DeckHints will try to grab additional cards from the pool
|
||||
DeckHints hints = cardToAdd.getRules().getAiHints().getDeckHints();
|
||||
final DeckHints hints = cardToAdd.getRules().getAiHints().getDeckHints();
|
||||
if (hints != null && hints.getType() != DeckHints.Type.NONE) {
|
||||
Iterable<PaperCard> onColor = Iterables.filter(aiPlayables, Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
List<PaperCard> comboCards = hints.filter(onColor);
|
||||
final Iterable<PaperCard> onColor = Iterables.filter(aiPlayables, Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||
final List<PaperCard> comboCards = hints.filter(onColor);
|
||||
if (logToConsole) {
|
||||
System.out.println("Found " + comboCards.size() + " cards for " + cardToAdd.getName());
|
||||
}
|
||||
for (Pair<Double, PaperCard> comboBean : rankCards(comboCards)) {
|
||||
for (final Pair<Double, PaperCard> comboBean : rankCards(comboCards)) {
|
||||
if (num > 0) {
|
||||
// This is not exactly right, because the
|
||||
// rankedComboCards could include creatures and
|
||||
// non-creatures.
|
||||
// This code could add too many of one or the other.
|
||||
PaperCard combo = comboBean.getValue();
|
||||
final PaperCard combo = comboBean.getValue();
|
||||
deckList.add(combo);
|
||||
num--;
|
||||
getAiPlayables().remove(combo);
|
||||
@@ -548,19 +562,19 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
private void checkRemRandomDeckCards() {
|
||||
int numCreatures = 0;
|
||||
int numOthers = 0;
|
||||
for (ListIterator<PaperCard> it = deckList.listIterator(); it.hasNext();) {
|
||||
PaperCard card = it.next();
|
||||
CardAiHints ai = card.getRules().getAiHints();
|
||||
for (final ListIterator<PaperCard> it = deckList.listIterator(); it.hasNext();) {
|
||||
final PaperCard card = it.next();
|
||||
final CardAiHints ai = card.getRules().getAiHints();
|
||||
if (ai.getRemRandomDecks()) {
|
||||
List<PaperCard> comboCards = new ArrayList<PaperCard>();
|
||||
final List<PaperCard> comboCards = new ArrayList<PaperCard>();
|
||||
if (ai.getDeckNeeds() != null
|
||||
&& ai.getDeckNeeds().getType() != DeckHints.Type.NONE) {
|
||||
DeckHints needs = ai.getDeckNeeds();
|
||||
final DeckHints needs = ai.getDeckNeeds();
|
||||
comboCards.addAll(needs.filter(deckList));
|
||||
}
|
||||
if (ai.getDeckHints() != null
|
||||
&& ai.getDeckHints().getType() != DeckHints.Type.NONE) {
|
||||
DeckHints hints = ai.getDeckHints();
|
||||
final DeckHints hints = ai.getDeckHints();
|
||||
comboCards.addAll(hints.filter(deckList));
|
||||
}
|
||||
if (comboCards.isEmpty()) {
|
||||
@@ -597,15 +611,15 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Add creatures to the deck.
|
||||
*
|
||||
*
|
||||
* @param creatures
|
||||
* cards to choose from
|
||||
* @param num
|
||||
*/
|
||||
private void addCreatures(List<Pair<Double, PaperCard>> creatures, int num) {
|
||||
for (Pair<Double, PaperCard> bean : creatures) {
|
||||
private void addCreatures(final List<Pair<Double, PaperCard>> creatures, int num) {
|
||||
for (final Pair<Double, PaperCard> bean : creatures) {
|
||||
if (num > 0) {
|
||||
PaperCard c = bean.getValue();
|
||||
final PaperCard c = bean.getValue();
|
||||
deckList.add(c);
|
||||
num--;
|
||||
getAiPlayables().remove(c);
|
||||
@@ -623,19 +637,19 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
* Add creatures to the deck, trying to follow some mana curve. Trying to
|
||||
* have generous limits at each cost, but perhaps still too strict. But
|
||||
* we're trying to prevent the AI from adding everything at a single cost.
|
||||
*
|
||||
*
|
||||
* @param creatures
|
||||
* cards to choose from
|
||||
* @param num
|
||||
*/
|
||||
private void addManaCurveCreatures(List<Pair<Double, PaperCard>> creatures, int num) {
|
||||
Map<Integer, Integer> creatureCosts = new HashMap<Integer, Integer>();
|
||||
private void addManaCurveCreatures(final List<Pair<Double, PaperCard>> creatures, int num) {
|
||||
final Map<Integer, Integer> creatureCosts = new HashMap<Integer, Integer>();
|
||||
for (int i = 1; i < 7; i++) {
|
||||
creatureCosts.put(i, 0);
|
||||
}
|
||||
Predicate<PaperCard> filter = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE,
|
||||
final Predicate<PaperCard> filter = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE,
|
||||
PaperCard.FN_GET_RULES);
|
||||
for (IPaperCard creature : Iterables.filter(deckList, filter)) {
|
||||
for (final IPaperCard creature : Iterables.filter(deckList, filter)) {
|
||||
int cmc = creature.getRules().getManaCost().getCMC();
|
||||
if (cmc < 1) {
|
||||
cmc = 1;
|
||||
@@ -645,15 +659,15 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
||||
}
|
||||
|
||||
for (Pair<Double, PaperCard> bean : creatures) {
|
||||
PaperCard c = bean.getValue();
|
||||
for (final Pair<Double, PaperCard> bean : creatures) {
|
||||
final PaperCard c = bean.getValue();
|
||||
int cmc = c.getRules().getManaCost().getCMC();
|
||||
if (cmc < 1) {
|
||||
cmc = 1;
|
||||
} else if (cmc > 6) {
|
||||
cmc = 6;
|
||||
}
|
||||
Integer currentAtCmc = creatureCosts.get(cmc);
|
||||
final Integer currentAtCmc = creatureCosts.get(cmc);
|
||||
boolean willAddCreature = false;
|
||||
if (cmc <= 1 && currentAtCmc < 2) {
|
||||
willAddCreature = true;
|
||||
@@ -693,15 +707,15 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Rank cards.
|
||||
*
|
||||
*
|
||||
* @param cards
|
||||
* CardPrinteds to rank
|
||||
* @return List of beans with card rankings
|
||||
*/
|
||||
protected List<Pair<Double, PaperCard>> rankCards(Iterable<PaperCard> cards) {
|
||||
List<Pair<Double, PaperCard>> ranked = new ArrayList<Pair<Double, PaperCard>>();
|
||||
for (PaperCard card : cards) {
|
||||
Double rkg = DraftRankCache.getRanking(card.getName(), card.getEdition());
|
||||
protected List<Pair<Double, PaperCard>> rankCards(final Iterable<PaperCard> cards) {
|
||||
final List<Pair<Double, PaperCard>> ranked = new ArrayList<Pair<Double, PaperCard>>();
|
||||
for (final PaperCard card : cards) {
|
||||
final Double rkg = DraftRankCache.getRanking(card.getName(), card.getEdition());
|
||||
if (rkg != null) {
|
||||
ranked.add(Pair.of(rkg, card));
|
||||
} else {
|
||||
@@ -714,13 +728,13 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
|
||||
/**
|
||||
* Calculate average CMC.
|
||||
*
|
||||
*
|
||||
* @param cards
|
||||
* @return the average
|
||||
*/
|
||||
private double getAverageCMC(List<PaperCard> cards) {
|
||||
private static double getAverageCMC(final List<PaperCard> cards) {
|
||||
double sum = 0.0;
|
||||
for (IPaperCard cardPrinted : cards) {
|
||||
for (final IPaperCard cardPrinted : cards) {
|
||||
sum += cardPrinted.getRules().getManaCost().getCMC();
|
||||
}
|
||||
return sum / cards.size();
|
||||
@@ -737,7 +751,7 @@ public class LimitedDeckBuilder extends DeckGeneratorBase{
|
||||
* @param colors
|
||||
* the colors to set
|
||||
*/
|
||||
public void setColors(ColorSet colors) {
|
||||
public void setColors(final ColorSet colors) {
|
||||
this.colors = colors;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package forge.limited;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
@@ -9,8 +14,6 @@ import forge.deck.Deck;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class WinstonDraft extends BoosterDraft {
|
||||
private WinstonDraftAI draftAI = null;
|
||||
private static int NUM_PILES = 3;
|
||||
@@ -20,7 +23,7 @@ public class WinstonDraft extends BoosterDraft {
|
||||
private List<List<PaperCard>> piles; // 3 piles to draft from
|
||||
|
||||
public static WinstonDraft createDraft(final LimitedPoolType draftType) {
|
||||
WinstonDraft draft = new WinstonDraft(draftType);
|
||||
final WinstonDraft draft = new WinstonDraft(draftType);
|
||||
if (!draft.generateProduct()) {
|
||||
return null;
|
||||
}
|
||||
@@ -28,7 +31,7 @@ public class WinstonDraft extends BoosterDraft {
|
||||
return draft;
|
||||
}
|
||||
|
||||
private WinstonDraft(LimitedPoolType draftType) {
|
||||
private WinstonDraft(final LimitedPoolType draftType) {
|
||||
draftFormat = draftType;
|
||||
draftAI = new WinstonDraftAI();
|
||||
|
||||
@@ -37,10 +40,10 @@ public class WinstonDraft extends BoosterDraft {
|
||||
private void initializeWinstonDraft() {
|
||||
this.deck = new Stack<PaperCard>();
|
||||
for (int i = 0; i < this.product.size(); i++) {
|
||||
Supplier<List<PaperCard>> supply = this.product.get(i);
|
||||
final Supplier<List<PaperCard>> supply = this.product.get(i);
|
||||
for(int j = 0; j < NUM_PLAYERS; j++) {
|
||||
// Remove Basic Lands from draft for simplicity
|
||||
for (PaperCard paperCard : Iterables.filter(supply.get(), Predicates.not(PaperCard.Predicates.Presets.IS_BASIC_LAND))) {
|
||||
for (final PaperCard paperCard : Iterables.filter(supply.get(), Predicates.not(PaperCard.Predicates.Presets.IS_BASIC_LAND))) {
|
||||
this.deck.add(paperCard);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +53,7 @@ public class WinstonDraft extends BoosterDraft {
|
||||
// Create three Winston piles, adding the top card from the Winston deck to start each pile
|
||||
this.piles = new ArrayList<>();
|
||||
for(int i = 0; i < NUM_PILES; i++) {
|
||||
List<PaperCard> pile = new ArrayList<PaperCard>();
|
||||
final List<PaperCard> pile = new ArrayList<PaperCard>();
|
||||
pile.add(this.deck.pop());
|
||||
this.piles.add(pile);
|
||||
}
|
||||
@@ -77,8 +80,9 @@ public class WinstonDraft extends BoosterDraft {
|
||||
}
|
||||
}
|
||||
|
||||
if (nextPile < 0 || nextPile > this.piles.size())
|
||||
if (nextPile < 0 || nextPile > this.piles.size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
nextBoosterGroup = nextPile;
|
||||
|
||||
@@ -89,64 +93,72 @@ public class WinstonDraft extends BoosterDraft {
|
||||
return getPoolByPile(this.nextBoosterGroup);
|
||||
}
|
||||
|
||||
private CardPool getPoolByPile(int i) {
|
||||
CardPool result = new CardPool();
|
||||
private CardPool getPoolByPile(final int i) {
|
||||
final CardPool result = new CardPool();
|
||||
result.addAllFlat(this.piles.get(i));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void computerChoose() {
|
||||
nextBoosterGroup = 0;
|
||||
draftAI.choose();
|
||||
}
|
||||
|
||||
public void refillPile(List<PaperCard> pile) {
|
||||
if (this.deck.size() > 0)
|
||||
public void refillPile(final List<PaperCard> pile) {
|
||||
if (this.deck.size() > 0) {
|
||||
pile.add(this.deck.pop());
|
||||
}
|
||||
}
|
||||
|
||||
public int getNextChoice(int startPile) {
|
||||
public int getNextChoice(final int startPile) {
|
||||
for(int i = startPile; i < NUM_PILES; i++) {
|
||||
if (this.piles.get(i).size() > 0)
|
||||
if (this.piles.get(i).size() > 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// All piles are empty, so draft is about to end.
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextChoice() {
|
||||
return getNextChoice(0) >= 0;
|
||||
}
|
||||
|
||||
public boolean isLastPileAndEmptyDeck(int pile) {
|
||||
public boolean isLastPileAndEmptyDeck(final int pile) {
|
||||
return this.deck.size() == 0 && getNextChoice(pile+1) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentBoosterIndex() {
|
||||
return nextBoosterGroup;
|
||||
}
|
||||
|
||||
public CardPool takeActivePile(boolean humanAction) {
|
||||
CardPool pool = getPoolByPile(this.nextBoosterGroup);
|
||||
public CardPool takeActivePile(final boolean humanAction) {
|
||||
final CardPool pool = getPoolByPile(this.nextBoosterGroup);
|
||||
|
||||
this.piles.get(this.nextBoosterGroup).clear();
|
||||
this.refillPile(this.piles.get(this.nextBoosterGroup));
|
||||
this.nextBoosterGroup = 0;
|
||||
if (humanAction)
|
||||
if (humanAction) {
|
||||
computerChoose();
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
|
||||
public CardPool passActivePile(boolean humanAction) {
|
||||
public CardPool passActivePile(final boolean humanAction) {
|
||||
this.refillPile(this.piles.get(this.nextBoosterGroup));
|
||||
this.nextBoosterGroup++;
|
||||
if (this.nextBoosterGroup >= this.piles.size()) {
|
||||
CardPool pool = new CardPool();
|
||||
if (this.deck.size() > 0)
|
||||
final CardPool pool = new CardPool();
|
||||
if (this.deck.size() > 0) {
|
||||
pool.add(this.deck.pop());
|
||||
}
|
||||
this.nextBoosterGroup = 0;
|
||||
if (humanAction)
|
||||
if (humanAction) {
|
||||
computerChoose();
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -65,6 +65,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
public final GameView getGameView() {
|
||||
return gameView;
|
||||
}
|
||||
@Override
|
||||
public void setGameView(final GameView gameView) {
|
||||
this.gameView = gameView;
|
||||
}
|
||||
@@ -73,7 +74,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
public final IGameController getGameController() {
|
||||
return gameControllers.get(getCurrentPlayer());
|
||||
}
|
||||
public final IGameController getGameController(PlayerView p0) {
|
||||
public final IGameController getGameController(final PlayerView p0) {
|
||||
return gameControllers.get(p0);
|
||||
}
|
||||
public final Collection<IGameController> getGameControllers() {
|
||||
@@ -94,10 +95,6 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
//not needed for base game implementation
|
||||
}
|
||||
|
||||
public String getCardImageKey(final CardStateView csv) {
|
||||
return csv.getImageKey(getLocalPlayers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayView(final CardView c) {
|
||||
if (!hasLocalPlayers()) {
|
||||
@@ -113,12 +110,12 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
public boolean mayFlip(final CardView cv) {
|
||||
if (cv == null) { return false; }
|
||||
|
||||
CardStateView altState = cv.getAlternateState();
|
||||
final CardStateView altState = cv.getAlternateState();
|
||||
if (altState == null) { return false; }
|
||||
|
||||
switch (altState.getState()) {
|
||||
case Original:
|
||||
CardStateView currentState = cv.getCurrentState();
|
||||
final CardStateView currentState = cv.getCurrentState();
|
||||
if (currentState.getState() == CardStateName.FaceDown) {
|
||||
return getCurrentPlayer() == null || cv.canFaceDownBeShownToAny(getLocalPlayers());
|
||||
}
|
||||
@@ -131,7 +128,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
}
|
||||
|
||||
private Set<PlayerView> highlightedPlayers = Sets.newHashSet();
|
||||
private final Set<PlayerView> highlightedPlayers = Sets.newHashSet();
|
||||
@Override
|
||||
public void setHighlighted(final PlayerView pv, final boolean b) {
|
||||
if (b) {
|
||||
@@ -141,21 +138,21 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHighlighted(PlayerView player) {
|
||||
public boolean isHighlighted(final PlayerView player) {
|
||||
return highlightedPlayers.contains(player);
|
||||
}
|
||||
|
||||
private Set<CardView> highlightedCards = Sets.newHashSet();
|
||||
private final Set<CardView> highlightedCards = Sets.newHashSet();
|
||||
// used to highlight cards in UI
|
||||
@Override
|
||||
public void setUsedToPay(CardView card, boolean value) {
|
||||
boolean hasChanged = value ? highlightedCards.add(card) : highlightedCards.remove(card);
|
||||
public void setUsedToPay(final CardView card, final boolean value) {
|
||||
final boolean hasChanged = value ? highlightedCards.add(card) : highlightedCards.remove(card);
|
||||
if (hasChanged) { // since we are in UI thread, may redraw the card right now
|
||||
updateSingleCard(card);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUsedToPay(CardView card) {
|
||||
public boolean isUsedToPay(final CardView card) {
|
||||
return highlightedCards.contains(card);
|
||||
}
|
||||
|
||||
@@ -210,6 +207,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
updateAutoPassPrompt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void autoPassCancel(final PlayerView player) {
|
||||
if (!autoPassUntilEndOfTurn.remove(player)) {
|
||||
return;
|
||||
@@ -222,6 +220,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
awaitNextInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean mayAutoPass(final PlayerView player) {
|
||||
return autoPassUntilEndOfTurn.contains(player);
|
||||
}
|
||||
@@ -313,8 +312,6 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
public final boolean shouldAlwaysAcceptTrigger(final int trigger) { return Boolean.TRUE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger))); }
|
||||
@Override
|
||||
public final boolean shouldAlwaysDeclineTrigger(final int trigger) { return Boolean.FALSE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger))); }
|
||||
@Override
|
||||
public final boolean shouldAlwaysAskTrigger(final int trigger) { return !triggersAlwaysAccept.containsKey(Integer.valueOf(trigger)); }
|
||||
|
||||
@Override
|
||||
public final void setShouldAlwaysAcceptTrigger(final int trigger) { triggersAlwaysAccept.put(Integer.valueOf(trigger), Boolean.TRUE); }
|
||||
@@ -329,7 +326,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
/**
|
||||
* Convenience for getChoices(message, 0, 1, choices).
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* is automatically inferred.
|
||||
* @param message
|
||||
@@ -364,7 +361,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
* <p>
|
||||
* getChoice.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* a T object.
|
||||
* @param message
|
||||
@@ -394,22 +391,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
return choice.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> noneOrMany(final String message, final Collection<T> choices) {
|
||||
return getChoices(message, 0, choices.size(), choices, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
// Nothing to choose here. Code uses this to just reveal one or more items
|
||||
public <T> void reveal(final String message, final T item) {
|
||||
List<T> items = new ArrayList<T>();
|
||||
items.add(item);
|
||||
reveal(message, items);
|
||||
}
|
||||
@Override
|
||||
public <T> void reveal(final String message, final T[] items) {
|
||||
getChoices(message, -1, -1, items);
|
||||
}
|
||||
@Override
|
||||
public <T> void reveal(final String message, final Collection<T> items) {
|
||||
getChoices(message, -1, -1, items);
|
||||
@@ -417,15 +399,11 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
// Get Integer in range
|
||||
@Override
|
||||
public Integer getInteger(final String message) {
|
||||
return getInteger(message, 0, Integer.MAX_VALUE, false);
|
||||
}
|
||||
@Override
|
||||
public Integer getInteger(final String message, int min) {
|
||||
public Integer getInteger(final String message, final int min) {
|
||||
return getInteger(message, min, Integer.MAX_VALUE, false);
|
||||
}
|
||||
@Override
|
||||
public Integer getInteger(final String message, int min, int max) {
|
||||
public Integer getInteger(final String message, final int min, final int max) {
|
||||
return getInteger(message, min, max, false);
|
||||
}
|
||||
@Override
|
||||
@@ -436,8 +414,8 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
if (max == Integer.MAX_VALUE) {
|
||||
return getInteger(message, min, max, min + 99);
|
||||
}
|
||||
int count = max - min + 1;
|
||||
if (count > 100) {
|
||||
final int count = max - min + 1;
|
||||
if (count > 100) {
|
||||
return getInteger(message, min, max, min + 99);
|
||||
}
|
||||
|
||||
@@ -512,33 +490,18 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
return getChoices(message, min, max, choices, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices) {
|
||||
return many(title, topCaption, cnt, sourceChoices, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> many(final String title, final String topCaption, final int cnt, final List<T> sourceChoices, final CardView c) {
|
||||
return many(title, topCaption, cnt, cnt, sourceChoices, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> many(final String title, final String topCaption, final int min, final int max, final List<T> sourceChoices) {
|
||||
return many(title, topCaption, min, max, sourceChoices, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, final CardView c) {
|
||||
public <T> List<T> many(final String title, final String topCaption, final int min, final int max, final List<T> sourceChoices, final CardView c) {
|
||||
final int m2 = min >= 0 ? sourceChoices.size() - min : -1;
|
||||
final int m1 = max >= 0 ? sourceChoices.size() - max : -1;
|
||||
return order(title, topCaption, m1, m2, sourceChoices, null, c, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> order(final String title, final String top, final List<T> sourceChoices) {
|
||||
return order(title, top, sourceChoices, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> order(final String title, final String top, final List<T> sourceChoices, final CardView c) {
|
||||
return order(title, top, 0, 0, sourceChoices, null, c, false);
|
||||
@@ -548,7 +511,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
* Ask the user to insert an object into a list of other objects. The
|
||||
* current implementation requires the user to cancel in order to get the
|
||||
* new item to be the first item in the resulting list.
|
||||
*
|
||||
*
|
||||
* @param title the dialog title.
|
||||
* @param newItem the object to insert.
|
||||
* @param oldItems the list of objects.
|
||||
@@ -584,11 +547,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
return confirm(c, question, true, null);
|
||||
}
|
||||
@Override
|
||||
public boolean confirm(final CardView c, final String question, final boolean defaultChoice) {
|
||||
return confirm(c, question, defaultChoice, null);
|
||||
}
|
||||
@Override
|
||||
public boolean confirm(final CardView c, final String question, String[] options) {
|
||||
public boolean confirm(final CardView c, final String question, final String[] options) {
|
||||
return confirm(c, question, true, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,10 +167,10 @@ public abstract class GameLobby {
|
||||
}
|
||||
return NameGenerator.getRandomName("Any", "Any", names);
|
||||
}
|
||||
protected final String localName() {
|
||||
protected final static String localName() {
|
||||
return FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
}
|
||||
protected final int[] localAvatarIndices() {
|
||||
protected final static int[] localAvatarIndices() {
|
||||
final String[] sAvatars = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",");
|
||||
final int[] result = new int[sAvatars.length];
|
||||
for (int i = 0; i < sAvatars.length; i++) {
|
||||
@@ -323,14 +323,14 @@ public abstract class GameLobby {
|
||||
}
|
||||
}
|
||||
|
||||
boolean checkLegality = FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY);
|
||||
final boolean checkLegality = FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY);
|
||||
|
||||
//Auto-generated decks don't need to be checked here
|
||||
//Commander deck replaces regular deck and is checked later
|
||||
if (checkLegality && autoGenerateVariant == null && !isCommanderMatch) {
|
||||
for (final LobbySlot slot : activeSlots) {
|
||||
final String name = slot.getName();
|
||||
String errMsg = GameType.Constructed.getDeckFormat().getDeckConformanceProblem(slot.getDeck());
|
||||
final String errMsg = GameType.Constructed.getDeckFormat().getDeckConformanceProblem(slot.getDeck());
|
||||
if (null != errMsg) {
|
||||
SOptionPane.showErrorDialog(name + "'s deck " + errMsg, "Invalid Deck");
|
||||
return;
|
||||
@@ -374,7 +374,7 @@ public abstract class GameLobby {
|
||||
if (isCommanderMatch) {
|
||||
final GameType commanderGameType = isTinyLeadersMatch ? GameType.TinyLeaders : GameType.Commander;
|
||||
if (checkLegality) {
|
||||
String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck);
|
||||
final String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck);
|
||||
if (null != errMsg) {
|
||||
SOptionPane.showErrorDialog(name + "'s deck " + errMsg, "Invalid " + commanderGameType + " Deck");
|
||||
return;
|
||||
@@ -400,7 +400,7 @@ public abstract class GameLobby {
|
||||
|| (variantTypes.contains(GameType.Archenemy) && isArchenemy)) {
|
||||
final CardPool schemePool = deck.get(DeckSection.Schemes);
|
||||
if (checkLegality) {
|
||||
String errMsg = DeckFormat.getSchemeSectionConformanceProblem(schemePool);
|
||||
final String errMsg = DeckFormat.getSchemeSectionConformanceProblem(schemePool);
|
||||
if (null != errMsg) {
|
||||
SOptionPane.showErrorDialog(name + "'s deck " + errMsg, "Invalid Scheme Deck");
|
||||
return;
|
||||
@@ -413,7 +413,7 @@ public abstract class GameLobby {
|
||||
if (variantTypes.contains(GameType.Planechase)) {
|
||||
final CardPool planePool = deck.get(DeckSection.Planes);
|
||||
if (checkLegality) {
|
||||
String errMsg = DeckFormat.getPlaneSectionConformanceProblem(planePool);
|
||||
final String errMsg = DeckFormat.getPlaneSectionConformanceProblem(planePool);
|
||||
if (null != errMsg) {
|
||||
SOptionPane.showErrorDialog(name + "'s deck " + errMsg, "Invalid Planar Deck");
|
||||
return;
|
||||
|
||||
@@ -17,7 +17,6 @@ import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.control.FControlGameEventHandler;
|
||||
import forge.control.FControlGamePlayback;
|
||||
import forge.control.WatchLocalGame;
|
||||
@@ -110,7 +109,7 @@ public class HostedMatch {
|
||||
if (sortedPlayers.size() == 2) {
|
||||
title = String.format("%s vs %s", sortedPlayers.get(0).getPlayer().getName(), sortedPlayers.get(1).getPlayer().getName());
|
||||
} else {
|
||||
title = String.format("Multiplayer Game (%d players)", sortedPlayers.size());
|
||||
title = String.format("Multiplayer Game (%d players)", sortedPlayers.size());
|
||||
}
|
||||
this.match = new Match(gameRules, sortedPlayers, title);
|
||||
startGame();
|
||||
@@ -134,7 +133,7 @@ public class HostedMatch {
|
||||
game = match.createGame();
|
||||
|
||||
if (game.getRules().getGameType() == GameType.Quest) {
|
||||
QuestController qc = FModel.getQuest();
|
||||
final QuestController qc = FModel.getQuest();
|
||||
// Reset new list when the Match round starts, not when each game starts
|
||||
if (game.getMatch().getPlayedGames().isEmpty()) {
|
||||
qc.getCards().resetNewList();
|
||||
@@ -150,7 +149,7 @@ public class HostedMatch {
|
||||
final GameView gameView = getGameView();
|
||||
|
||||
humanCount = 0;
|
||||
final MapOfLists<IGuiGame, PlayerView> playersPerGui = new HashMapOfLists<IGuiGame, PlayerView>(CollectionSuppliers.<PlayerView>arrayLists());
|
||||
final MapOfLists<IGuiGame, PlayerView> playersPerGui = new HashMapOfLists<IGuiGame, PlayerView>(CollectionSuppliers.<PlayerView>arrayLists());
|
||||
for (int iPlayer = 0; iPlayer < players.size(); iPlayer++) {
|
||||
final RegisteredPlayer rp = match.getPlayers().get(iPlayer);
|
||||
final Player p = players.get(iPlayer);
|
||||
@@ -234,7 +233,7 @@ public class HostedMatch {
|
||||
|
||||
}
|
||||
|
||||
public void registerSpectator(final LobbyPlayer lobbyPlayer, final IGuiGame gui) {
|
||||
public void registerSpectator(final IGuiGame gui) {
|
||||
final PlayerControllerHuman humanController = new WatchLocalGame(game, null, gui);
|
||||
gui.setGameController(null, humanController);
|
||||
gui.openView(null);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
package forge.match;
|
||||
|
||||
public enum MatchButtonType {
|
||||
OK,
|
||||
CANCEL;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package forge.match;
|
||||
|
||||
public enum MatchConstants {
|
||||
ALWAYSACCEPT ("Always accept this trigger"),
|
||||
ALWAYSDECLINE ("Always decline this trigger"),
|
||||
ALWAYSASK ("Always ask"),
|
||||
HUMANCOMMAND ("Player's Command zone", "Command: ", "Player - View Command"),
|
||||
HUMANEXILED ("Player's Exile", "Exile:", "Player - View Exile"),
|
||||
HUMANFLASHBACK("Play card with Flashback", "Flashback:", "Player - View Cards with Flashback"),
|
||||
HUMANGRAVEYARD("Player's Graveyard", "Graveyard:", "Player - View Graveyard"),
|
||||
HUMANHAND ("Player's Hand", "Hand:", "Player - View Hand"),
|
||||
HUMANLIBRARY ("Player's Library", "Library:", "Player - View Library");
|
||||
|
||||
public final String title;
|
||||
public final String button;
|
||||
public final String menu;
|
||||
|
||||
private MatchConstants(String title0) {
|
||||
title = title0;
|
||||
button = title0;
|
||||
menu = title0;
|
||||
}
|
||||
private MatchConstants(String title0, String button0, String menu0) {
|
||||
title = title0;
|
||||
button = button0;
|
||||
menu = menu0;
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ import forge.util.ITriggerEvent;
|
||||
* <p>
|
||||
* Abstract Input class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: InputBase.java 24769 2014-02-09 13:56:04Z Hellfish $
|
||||
*/
|
||||
@@ -47,6 +47,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
public final PlayerControllerHuman getController() {
|
||||
return controller;
|
||||
}
|
||||
@Override
|
||||
public PlayerView getOwner() {
|
||||
final Player owner = getController().getPlayer();
|
||||
return owner == null ? null : owner.getView();
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -30,15 +30,15 @@ import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.Lang;
|
||||
import forge.util.ThreadUtil;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* InputConfirmMulligan class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: InputConfirmMulligan.java 24769 2014-02-09 13:56:04Z Hellfish $
|
||||
*/
|
||||
* <p>
|
||||
* InputConfirmMulligan class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: InputConfirmMulligan.java 24769 2014-02-09 13:56:04Z Hellfish $
|
||||
*/
|
||||
public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
/** Constant <code>serialVersionUID=-8112954303001155622L</code>. */
|
||||
private static final long serialVersionUID = -8112954303001155622L;
|
||||
@@ -60,9 +60,9 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void showMessage() {
|
||||
Game game = player.getGame();
|
||||
final Game game = player.getGame();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
if (startingPlayer == player) {
|
||||
sb.append(player).append(", you are going first!\n\n");
|
||||
}
|
||||
@@ -116,9 +116,9 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
|
||||
@Override
|
||||
protected boolean onCardSelected(final Card c0, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) { // the only place that would cause troubles - input is supposed only to confirm, not to fire abilities
|
||||
boolean fromHand = player.getZone(ZoneType.Hand).contains(c0);
|
||||
boolean isSerumPowder = c0.getName().equals("Serum Powder");
|
||||
boolean isLegalChoice = fromHand && (isCommander || isSerumPowder);
|
||||
final boolean fromHand = player.getZone(ZoneType.Hand).contains(c0);
|
||||
final boolean isSerumPowder = c0.getName().equals("Serum Powder");
|
||||
final boolean isLegalChoice = fromHand && (isCommander || isSerumPowder);
|
||||
if (!isLegalChoice || cardSelectLocked) {
|
||||
return false;
|
||||
}
|
||||
@@ -127,9 +127,9 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
if (isSerumPowder && getController().getGui().confirm(cView, "Use " + cView + "'s ability?")) {
|
||||
cardSelectLocked = true;
|
||||
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||
public void run() {
|
||||
CardCollection hand = new CardCollection(c0.getController().getCardsIn(ZoneType.Hand));
|
||||
for (Card c : hand) {
|
||||
@Override public void run() {
|
||||
final CardCollection hand = new CardCollection(c0.getController().getCardsIn(ZoneType.Hand));
|
||||
for (final Card c : hand) {
|
||||
player.getGame().getAction().exile(c);
|
||||
}
|
||||
c0.getController().drawCards(hand.size());
|
||||
@@ -162,7 +162,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivateAction(Card card) {
|
||||
public String getActivateAction(final Card card) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,31 +30,33 @@ public class InputLockUI implements Input {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessageInitial() {
|
||||
int ixCall = 1 + iCall.getAndIncrement();
|
||||
final int ixCall = 1 + iCall.getAndIncrement();
|
||||
ThreadUtil.delay(500, new InputUpdater(ixCall));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "lockUI";
|
||||
return "lockUI";
|
||||
}
|
||||
|
||||
|
||||
private class InputUpdater implements Runnable {
|
||||
final int ixCall;
|
||||
|
||||
|
||||
public InputUpdater(final int idxCall) {
|
||||
ixCall = idxCall;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( ixCall != iCall.get() || !isActive()) // cancel the message if it's not from latest call or input is gone already
|
||||
if ( ixCall != iCall.get() || !isActive()) {
|
||||
return;
|
||||
}
|
||||
FThreads.invokeInEdtLater(showMessageFromEdt);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final Runnable showMessageFromEdt = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -67,20 +69,20 @@ public class InputLockUI implements Input {
|
||||
return inputQueue.getInput() == this;
|
||||
}
|
||||
|
||||
protected void showMessage(String message) {
|
||||
protected void showMessage(final String message) {
|
||||
controller.getGui().showPromptMessage(getOwner(), message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectCard(Card c, final List<Card> otherCardsToSelect, ITriggerEvent triggerEvent) {
|
||||
public boolean selectCard(final Card c, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean selectAbility(SpellAbility ab) {
|
||||
public boolean selectAbility(final SpellAbility ab) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void selectPlayer(Player player, ITriggerEvent triggerEvent) {
|
||||
public void selectPlayer(final Player player, final ITriggerEvent triggerEvent) {
|
||||
}
|
||||
@Override
|
||||
public void selectButtonOK() {
|
||||
@@ -88,13 +90,13 @@ public class InputLockUI implements Input {
|
||||
@Override
|
||||
public void selectButtonCancel() {
|
||||
//cancel auto pass for all players
|
||||
for (Player player : game.getPlayers()) {
|
||||
for (final Player player : game.getPlayers()) {
|
||||
player.getController().autoPassCancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivateAction(Card card) {
|
||||
public String getActivateAction(final Card card) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -51,6 +51,7 @@ public class InputPayManaSimple extends InputPayMana {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onManaAbilityPaid() {
|
||||
if (this.manaCost.isPaid()) {
|
||||
this.originalCard.setSunburstValue(this.manaCost.getSunburst());
|
||||
@@ -59,7 +60,7 @@ public class InputPayManaSimple extends InputPayMana {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected final void onPlayerSelected(Player selected, final ITriggerEvent triggerEvent) {
|
||||
protected final void onPlayerSelected(final Player selected, final ITriggerEvent triggerEvent) {
|
||||
if (player == selected) {
|
||||
if (player.canPayLife(this.phyLifeToLose + 2) && manaCost.payPhyrexian()) {
|
||||
this.phyLifeToLose += 2;
|
||||
|
||||
@@ -16,20 +16,21 @@ import forge.util.ITriggerEvent;
|
||||
|
||||
public final class InputProliferate extends InputSelectManyBase<GameEntity> {
|
||||
private static final long serialVersionUID = -1779224307654698954L;
|
||||
private Map<GameEntity, CounterType> chosenCounters = new HashMap<GameEntity, CounterType>();
|
||||
private final Map<GameEntity, CounterType> chosenCounters = new HashMap<GameEntity, CounterType>();
|
||||
|
||||
public InputProliferate(final PlayerControllerHuman controller) {
|
||||
super(controller, 1, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMessage() {
|
||||
StringBuilder sb = new StringBuilder("Choose permanents and/or players with counters on them to add one more counter of that type.");
|
||||
final StringBuilder sb = new StringBuilder("Choose permanents and/or players with counters on them to add one more counter of that type.");
|
||||
sb.append("\n\nYou've selected so far:\n");
|
||||
if (chosenCounters.isEmpty()) {
|
||||
sb.append("(none)");
|
||||
}
|
||||
else {
|
||||
for (Entry<GameEntity, CounterType> ge : chosenCounters.entrySet()) {
|
||||
for (final Entry<GameEntity, CounterType> ge : chosenCounters.entrySet()) {
|
||||
if (ge.getKey() instanceof Player) {
|
||||
sb.append("* A poison counter to player ").append(ge.getKey()).append("\n");
|
||||
}
|
||||
@@ -47,8 +48,8 @@ public final class InputProliferate extends InputSelectManyBase<GameEntity> {
|
||||
if (!card.hasCounters()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean entityWasSelected = chosenCounters.containsKey(card);
|
||||
|
||||
final boolean entityWasSelected = chosenCounters.containsKey(card);
|
||||
if (entityWasSelected) {
|
||||
this.chosenCounters.remove(card);
|
||||
}
|
||||
@@ -60,7 +61,7 @@ public final class InputProliferate extends InputSelectManyBase<GameEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
CounterType toAdd = choices.size() == 1 ? choices.get(0) : getController().getGui().one("Select counter type", choices);
|
||||
final CounterType toAdd = choices.size() == 1 ? choices.get(0) : getController().getGui().one("Select counter type", choices);
|
||||
chosenCounters.put(card, toAdd);
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ public final class InputProliferate extends InputSelectManyBase<GameEntity> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivateAction(Card card) {
|
||||
public String getActivateAction(final Card card) {
|
||||
if (card.hasCounters() && !chosenCounters.containsKey(card)) {
|
||||
return "add counter to card";
|
||||
}
|
||||
@@ -77,17 +78,18 @@ public final class InputProliferate extends InputSelectManyBase<GameEntity> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onPlayerSelected(Player player, final ITriggerEvent triggerEvent) {
|
||||
protected final void onPlayerSelected(final Player player, final ITriggerEvent triggerEvent) {
|
||||
if (player.getPoisonCounters() == 0 || player.hasKeyword("You can't get poison counters")) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean entityWasSelected = chosenCounters.containsKey(player);
|
||||
|
||||
final boolean entityWasSelected = chosenCounters.containsKey(player);
|
||||
if (entityWasSelected) {
|
||||
this.chosenCounters.remove(player);
|
||||
} else
|
||||
} else {
|
||||
this.chosenCounters.put(player, null /* POISON counter is meant */);
|
||||
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ import forge.player.PlayerControllerHuman;
|
||||
* <p>
|
||||
* InputControl class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: InputQueue.java 24769 2014-02-09 13:56:04Z Hellfish $
|
||||
*/
|
||||
@@ -50,8 +50,8 @@ public class InputQueue extends Observable {
|
||||
return inputStack.isEmpty() ? null : inputStack.peek();
|
||||
}
|
||||
|
||||
public final void removeInput(Input inp) {
|
||||
Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop();
|
||||
public final void removeInput(final Input inp) {
|
||||
final Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop();
|
||||
|
||||
if (topMostInput != inp) {
|
||||
throw new RuntimeException("Cannot remove input " + inp.getClass().getSimpleName() + " because it's not on top of stack. Stack = " + inputStack );
|
||||
|
||||
@@ -26,14 +26,15 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card>
|
||||
private final ManaCostBeingPaid remainingCost;
|
||||
private final Player player;
|
||||
private final CardCollectionView availableCreatures;
|
||||
|
||||
public InputSelectCardsForConvoke(final PlayerControllerHuman controller, final Player p, final ManaCost cost, final CardCollectionView untapped) {
|
||||
|
||||
public InputSelectCardsForConvoke(final PlayerControllerHuman controller, final Player p, final ManaCost cost, final CardCollectionView untapped) {
|
||||
super(controller, 0, Math.min(cost.getCMC(), untapped.size()));
|
||||
remainingCost = new ManaCostBeingPaid(cost);
|
||||
player = p;
|
||||
availableCreatures = untapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMessage() {
|
||||
return "Choose creatures to tap for convoke.\nRemaining mana cost is " + remainingCost.toString();
|
||||
}
|
||||
@@ -45,15 +46,15 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card>
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean entityWasSelected = chosenCards.containsKey(card);
|
||||
final boolean entityWasSelected = chosenCards.containsKey(card);
|
||||
if (entityWasSelected) {
|
||||
ImmutablePair<Byte, ManaCostShard> color = this.chosenCards.remove(card);
|
||||
final ImmutablePair<Byte, ManaCostShard> color = this.chosenCards.remove(card);
|
||||
remainingCost.increaseShard(color.right, 1);
|
||||
onSelectStateChanged(card, false);
|
||||
}
|
||||
else {
|
||||
byte chosenColor;
|
||||
ColorSet colors = CardUtil.getColors(card);
|
||||
final ColorSet colors = CardUtil.getColors(card);
|
||||
if (colors.isMonoColor()) {
|
||||
// Since the convoke mana logic can use colored mana as colorless if needed,
|
||||
// there is no need to prompt the user when convoking with a mono-color creature.
|
||||
@@ -61,7 +62,7 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card>
|
||||
} else {
|
||||
chosenColor = player.getController().chooseColorAllowColorless("Convoke " + card.toString() + " for which color?", card, colors);
|
||||
}
|
||||
ManaCostShard shard = remainingCost.payManaViaConvoke(chosenColor);
|
||||
final ManaCostShard shard = remainingCost.payManaViaConvoke(chosenColor);
|
||||
if (shard != null) {
|
||||
chosenCards.put(card, ImmutablePair.of(chosenColor, shard));
|
||||
onSelectStateChanged(card, true);
|
||||
@@ -77,7 +78,7 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card>
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivateAction(Card card) {
|
||||
public String getActivateAction(final Card card) {
|
||||
if (availableCreatures.contains(card)) {
|
||||
return "tap creature for Convoke";
|
||||
}
|
||||
@@ -85,14 +86,16 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onPlayerSelected(Player player, final ITriggerEvent triggerEvent) {
|
||||
protected final void onPlayerSelected(final Player player, final ITriggerEvent triggerEvent) {
|
||||
}
|
||||
|
||||
public Map<Card, ManaCostShard> getConvokeMap() {
|
||||
Map<Card, ManaCostShard> result = new HashMap<Card, ManaCostShard>();
|
||||
if( !hasCancelled() )
|
||||
for(Entry<Card, ImmutablePair<Byte, ManaCostShard>> c : chosenCards.entrySet())
|
||||
final Map<Card, ManaCostShard> result = new HashMap<Card, ManaCostShard>();
|
||||
if(!hasCancelled()) {
|
||||
for(final Entry<Card, ImmutablePair<Byte, ManaCostShard>> c : chosenCards.entrySet()) {
|
||||
result.put(c.getKey(), c.getValue().right);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,9 @@ public class InputSelectCardsFromList extends InputSelectEntitiesFromList<Card>
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final int cnt, final FCollectionView<Card> validCards) {
|
||||
super(controller, cnt, cnt, validCards); // to avoid hangs
|
||||
}
|
||||
|
||||
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<Card> validCards) {
|
||||
super(controller, min, max, validCards); // to avoid hangs
|
||||
}
|
||||
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final FCollectionView<Card> validCards) {
|
||||
super(controller, 1, 1, validCards); // to avoid hangs
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivateAction(Card card) {
|
||||
public String getActivateAction(final Card card) {
|
||||
if (validChoices.contains(card)) {
|
||||
if (selected.contains(card)) {
|
||||
return "unselect card";
|
||||
@@ -54,17 +54,18 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Collection<T> getSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected boolean selectEntity(GameEntity c) {
|
||||
protected boolean selectEntity(final GameEntity c) {
|
||||
if (!validChoices.contains(c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean entityWasSelected = selected.contains(c);
|
||||
final boolean entityWasSelected = selected.contains(c);
|
||||
if (entityWasSelected) {
|
||||
selected.remove(c);
|
||||
}
|
||||
@@ -77,9 +78,12 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
}
|
||||
|
||||
// might re-define later
|
||||
@Override
|
||||
protected boolean hasEnoughTargets() { return selected.size() >= min; }
|
||||
@Override
|
||||
protected boolean hasAllTargets() { return selected.size() >= max; }
|
||||
|
||||
@Override
|
||||
protected String getMessage() {
|
||||
return max == Integer.MAX_VALUE
|
||||
? String.format(message, selected.size())
|
||||
|
||||
@@ -15,16 +15,17 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
||||
cdlDone = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void awaitLatchRelease() {
|
||||
FThreads.assertExecutedByEdt(false);
|
||||
try{
|
||||
cdlDone.await();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
} catch (final InterruptedException e) {
|
||||
BugReporter.reportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void relaseLatchWhenGameIsOver() {
|
||||
cdlDone.countDown();
|
||||
}
|
||||
@@ -33,7 +34,7 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
||||
getController().getInputQueue().setInput(this);
|
||||
awaitLatchRelease();
|
||||
}
|
||||
|
||||
|
||||
protected final void stop() {
|
||||
onStop();
|
||||
|
||||
|
||||
@@ -6,30 +6,29 @@
|
||||
* 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 java.io.File;
|
||||
|
||||
import org.apache.commons.lang3.time.StopWatch;
|
||||
|
||||
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.properties.ForgeConstants;
|
||||
import forge.util.storage.IStorage;
|
||||
import forge.util.storage.StorageImmediatelySerialized;
|
||||
|
||||
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
|
||||
@@ -46,24 +45,19 @@ public class CardCollections {
|
||||
private final IStorage<Deck> tinyLeaders;
|
||||
|
||||
public CardCollections() {
|
||||
StopWatch sw = new StopWatch();
|
||||
final StopWatch sw = new StopWatch();
|
||||
sw.start();
|
||||
constructed = new StorageImmediatelySerialized<Deck>("Constructed decks", new DeckStorage(new File(ForgeConstants.DECK_CONSTRUCTED_DIR), true), true);
|
||||
draft = new StorageImmediatelySerialized<DeckGroup>("Draft deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_DRAFT_DIR)));
|
||||
sealed = new StorageImmediatelySerialized<DeckGroup>("Sealed deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_SEALED_DIR)));
|
||||
winston = new StorageImmediatelySerialized<DeckGroup>("Winston draft deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_WINSTON_DIR)));
|
||||
cube = new StorageImmediatelySerialized<Deck>("Cubes", new DeckStorage(new File(ForgeConstants.DECK_CUBE_DIR)));
|
||||
scheme = new StorageImmediatelySerialized<Deck>("Archenemy decks", new DeckStorage(new File(ForgeConstants.DECK_SCHEME_DIR)));
|
||||
plane = new StorageImmediatelySerialized<Deck>("Planechase decks", new DeckStorage(new File(ForgeConstants.DECK_PLANE_DIR)));
|
||||
commander = new StorageImmediatelySerialized<Deck>("Commander decks", new DeckStorage(new File(ForgeConstants.DECK_COMMANDER_DIR)));
|
||||
tinyLeaders = new StorageImmediatelySerialized<Deck>("Commander decks", new DeckStorage(new File(ForgeConstants.DECK_TINY_LEADERS_DIR)));
|
||||
constructed = new StorageImmediatelySerialized<Deck> ("Constructed decks", new DeckStorage(new File(ForgeConstants.DECK_CONSTRUCTED_DIR), true), true);
|
||||
draft = new StorageImmediatelySerialized<DeckGroup>("Draft deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_DRAFT_DIR)));
|
||||
sealed = new StorageImmediatelySerialized<DeckGroup>("Sealed deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_SEALED_DIR)));
|
||||
winston = new StorageImmediatelySerialized<DeckGroup>("Winston draft deck sets", new DeckGroupSerializer(new File(ForgeConstants.DECK_WINSTON_DIR)));
|
||||
cube = new StorageImmediatelySerialized<Deck> ("Cubes", new DeckStorage(new File(ForgeConstants.DECK_CUBE_DIR)));
|
||||
scheme = new StorageImmediatelySerialized<Deck> ("Archenemy decks", new DeckStorage(new File(ForgeConstants.DECK_SCHEME_DIR)));
|
||||
plane = new StorageImmediatelySerialized<Deck> ("Planechase decks", new DeckStorage(new File(ForgeConstants.DECK_PLANE_DIR)));
|
||||
commander = new StorageImmediatelySerialized<Deck> ("Commander decks", new DeckStorage(new File(ForgeConstants.DECK_COMMANDER_DIR)));
|
||||
tinyLeaders = new StorageImmediatelySerialized<Deck> ("Commander decks", new DeckStorage(new File(ForgeConstants.DECK_TINY_LEADERS_DIR)));
|
||||
sw.stop();
|
||||
System.out.printf("Read decks (%d ms): %d constructed, %d sealed, %d draft, %d cubes, %d scheme, %d planar, %d commander, %d tiny leaders.%n", sw.getTime(), constructed.size(), sealed.size(), draft.size(), cube.size(), scheme.size(), plane.size(), commander.size(), tinyLeaders.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(constructed, draft, sealed, cube);
|
||||
oldParser.tryParse();
|
||||
}
|
||||
|
||||
public final IStorage<Deck> getConstructed() {
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -59,10 +59,10 @@ import forge.util.storage.StorageBase;
|
||||
|
||||
/**
|
||||
* The default Model implementation for Forge.
|
||||
*
|
||||
*
|
||||
* This used to be an interface, but it seems unlikely that we will ever use a
|
||||
* different model.
|
||||
*
|
||||
*
|
||||
* In case we need to convert it into an interface in the future, all fields of
|
||||
* this class must be either private or public static final.
|
||||
*/
|
||||
@@ -98,18 +98,18 @@ public class FModel {
|
||||
ForgeConstants.CACHE_BOOSTERBOX_PICS_DIR, ForgeConstants.CACHE_PRECON_PICS_DIR,
|
||||
ForgeConstants.CACHE_TOURNAMENTPACK_PICS_DIR);
|
||||
|
||||
// Instantiate preferences: quest and regular
|
||||
//Preferences are initialized first so that the splash screen can be translated.
|
||||
try {
|
||||
preferences = new ForgePreferences();
|
||||
GamePlayerUtil.getGuiPlayer().setName(preferences.getPref(FPref.PLAYER_NAME));
|
||||
}
|
||||
catch (final Exception exn) {
|
||||
throw new RuntimeException(exn);
|
||||
}
|
||||
// Instantiate preferences: quest and regular
|
||||
// Preferences are initialized first so that the splash screen can be translated.
|
||||
try {
|
||||
preferences = new ForgePreferences();
|
||||
GamePlayerUtil.getGuiPlayer().setName(preferences.getPref(FPref.PLAYER_NAME));
|
||||
}
|
||||
catch (final Exception exn) {
|
||||
throw new RuntimeException(exn);
|
||||
}
|
||||
|
||||
Localizer.getInstance().initialize(FModel.getPreferences().getPref(FPref.UI_LANGUAGE), ForgeConstants.LANG_DIR);
|
||||
|
||||
Localizer.getInstance().initialize(FModel.getPreferences().getPref(FPref.UI_LANGUAGE), ForgeConstants.LANG_DIR);
|
||||
|
||||
//load card database
|
||||
final ProgressObserver progressBarBridge = (progressBar == null) ?
|
||||
ProgressObserver.emptyObserver : new ProgressObserver() {
|
||||
@@ -140,8 +140,8 @@ public class FModel {
|
||||
magicDb = new StaticData(reader, ForgeConstants.EDITIONS_DIR, ForgeConstants.BLOCK_DATA_DIR);
|
||||
|
||||
//create profile dirs if they don't already exist
|
||||
for (String dname : ForgeConstants.PROFILE_DIRS) {
|
||||
File path = new File(dname);
|
||||
for (final String dname : ForgeConstants.PROFILE_DIRS) {
|
||||
final File path = new File(dname);
|
||||
if (path.isDirectory()) {
|
||||
// already exists
|
||||
continue;
|
||||
@@ -199,7 +199,7 @@ public class FModel {
|
||||
}
|
||||
|
||||
private static boolean keywordsLoaded = false;
|
||||
|
||||
|
||||
/**
|
||||
* Load dynamic gamedata.
|
||||
*/
|
||||
@@ -210,37 +210,22 @@ public class FModel {
|
||||
List<String> tList = null;
|
||||
|
||||
if (typeListFile.size() > 0) {
|
||||
for (int i = 0; i < typeListFile.size(); i++) {
|
||||
final String s = typeListFile.get(i);
|
||||
for (final String s : typeListFile) {
|
||||
if (s.equals("[BasicTypes]")) {
|
||||
tList = CardType.Constant.BASIC_TYPES;
|
||||
}
|
||||
|
||||
else if (s.equals("[LandTypes]")) {
|
||||
} else if (s.equals("[LandTypes]")) {
|
||||
tList = CardType.Constant.LAND_TYPES;
|
||||
}
|
||||
|
||||
else if (s.equals("[CreatureTypes]")) {
|
||||
} else if (s.equals("[CreatureTypes]")) {
|
||||
tList = CardType.Constant.CREATURE_TYPES;
|
||||
}
|
||||
|
||||
else if (s.equals("[SpellTypes]")) {
|
||||
} else if (s.equals("[SpellTypes]")) {
|
||||
tList = CardType.Constant.SPELL_TYPES;
|
||||
}
|
||||
|
||||
else if (s.equals("[EnchantmentTypes]")) {
|
||||
} else if (s.equals("[EnchantmentTypes]")) {
|
||||
tList = CardType.Constant.ENCHANTMENT_TYPES;
|
||||
}
|
||||
|
||||
else if (s.equals("[ArtifactTypes]")) {
|
||||
} else if (s.equals("[ArtifactTypes]")) {
|
||||
tList = CardType.Constant.ARTIFACT_TYPES;
|
||||
}
|
||||
|
||||
else if (s.equals("[WalkerTypes]")) {
|
||||
} else if (s.equals("[WalkerTypes]")) {
|
||||
tList = CardType.Constant.WALKER_TYPES;
|
||||
}
|
||||
|
||||
else if (s.length() > 1) {
|
||||
} else if (s.length() > 1) {
|
||||
tList.add(s);
|
||||
}
|
||||
}
|
||||
@@ -252,7 +237,7 @@ public class FModel {
|
||||
final List<String> nskwListFile = FileUtil.readFile(ForgeConstants.KEYWORD_LIST_FILE);
|
||||
|
||||
if (nskwListFile.size() > 1) {
|
||||
for (String s : nskwListFile) {
|
||||
for (final String s : nskwListFile) {
|
||||
if (s.length() > 1) {
|
||||
CardUtil.NON_STACKING_LIST.add(s);
|
||||
}
|
||||
@@ -303,7 +288,7 @@ public class FModel {
|
||||
return gauntletData;
|
||||
}
|
||||
|
||||
public static void setGauntletData(GauntletData data0) {
|
||||
public static void setGauntletData(final GauntletData data0) {
|
||||
gauntletData = data0;
|
||||
}
|
||||
|
||||
@@ -321,7 +306,7 @@ public class FModel {
|
||||
public static IStorage<QuestWorld> getWorlds() {
|
||||
return worlds;
|
||||
}
|
||||
|
||||
|
||||
public static GameFormat.Collection getFormats() {
|
||||
return formats;
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.model;
|
||||
|
||||
//import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Exception thrown by model when it is trying to find a single forge jar, but
|
||||
* it finds more than one.
|
||||
*/
|
||||
public class MultipleForgeJarsFoundError extends RuntimeException {
|
||||
/** Automatically generated. */
|
||||
private static final long serialVersionUID = 8899307272033517172L;
|
||||
|
||||
/**
|
||||
* Create an exception with a message.
|
||||
*
|
||||
* @param message
|
||||
* the message, which could be the System's class path.
|
||||
*/
|
||||
public MultipleForgeJarsFoundError(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
package forge.net;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.deck.CardPool;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.GameView;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.DelayedReveal;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.spellability.SpellAbilityView;
|
||||
import forge.interfaces.IGameController;
|
||||
import forge.interfaces.IGuiGame;
|
||||
import forge.match.NextGameDecision;
|
||||
import forge.trackable.TrackableCollection;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.ReflectionUtil;
|
||||
|
||||
public final class GameProtocol {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private GameProtocol() {
|
||||
}
|
||||
|
||||
public static ProtocolMethod getProtocolMethod(final String name) {
|
||||
return ProtocolMethod.valueOf(name);
|
||||
}
|
||||
|
||||
private enum Mode {
|
||||
SERVER(IGuiGame.class),
|
||||
CLIENT(IGameController.class);
|
||||
|
||||
private final Class<?> toInvoke;
|
||||
private Mode(final Class<?> toInvoke) {
|
||||
this.toInvoke = toInvoke;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The methods that can be sent through this protocol.
|
||||
*/
|
||||
public enum ProtocolMethod {
|
||||
// Server -> Client
|
||||
setGameView (Mode.SERVER, Void.TYPE, GameView.class),
|
||||
openView (Mode.SERVER, Void.TYPE, TrackableCollection/*PlayerView*/.class),
|
||||
afterGameEnd (Mode.SERVER),
|
||||
showCombat (Mode.SERVER),
|
||||
showPromptMessage (Mode.SERVER, Void.TYPE, PlayerView.class, String.class),
|
||||
updateButtons (Mode.SERVER, Void.TYPE, PlayerView.class, String.class, String.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE),
|
||||
flashIncorrectAction(Mode.SERVER),
|
||||
updatePhase (Mode.SERVER),
|
||||
updateTurn (Mode.SERVER, Void.TYPE, PlayerView.class),
|
||||
updatePlayerControl (Mode.SERVER),
|
||||
enableOverlay (Mode.SERVER),
|
||||
disableOverlay (Mode.SERVER),
|
||||
finishGame (Mode.SERVER),
|
||||
showManaPool (Mode.SERVER, Object.class, PlayerView.class),
|
||||
hideManaPool (Mode.SERVER, Void.TYPE, PlayerView.class),
|
||||
updateStack (Mode.SERVER),
|
||||
updateZones (Mode.SERVER, Void.TYPE, Iterable/*PlayerZoneUpdate*/.class),
|
||||
updateCards (Mode.SERVER, Void.TYPE, Iterable/*CardView*/.class),
|
||||
updateManaPool (Mode.SERVER, Void.TYPE, Iterable/*PlayerView*/.class),
|
||||
updateLives (Mode.SERVER, Void.TYPE, Iterable/*PlayerView*/.class),
|
||||
setPanelSelection (Mode.SERVER, Void.TYPE, CardView.class),
|
||||
getAbilityToPlay (Mode.SERVER, SpellAbilityView.class, CardView.class, List/*SpellAbilityView*/.class, ITriggerEvent.class),
|
||||
assignDamage (Mode.SERVER, Map.class, CardView.class, List/*CardView*/.class, Integer.TYPE, GameEntityView.class, Boolean.TYPE),
|
||||
message (Mode.SERVER, Void.TYPE, String.class, String.class),
|
||||
showErrorDialog (Mode.SERVER, Void.TYPE, String.class, String.class),
|
||||
showConfirmDialog (Mode.SERVER, Boolean.TYPE, String.class, String.class, String.class, String.class, Boolean.TYPE),
|
||||
showOptionDialog (Mode.SERVER, Integer.TYPE, String.class, String.class, FSkinProp.class, Array/*String*/.class, Integer.TYPE),
|
||||
showCardOptionDialog(Mode.SERVER, Integer.TYPE, CardView.class, String.class, String.class, FSkinProp.class, String.class, Array/*String*/.class),
|
||||
showInputDialog (Mode.SERVER, String.class, String.class, String.class, FSkinProp.class, String.class, Array/*String*/.class),
|
||||
confirm (Mode.SERVER, Boolean.TYPE, CardView.class, String.class, Boolean.TYPE, Array/*String*/.class),
|
||||
getChoices (Mode.SERVER, List.class, String.class, Integer.TYPE, Integer.TYPE, Collection.class, Object.class, Function.class),
|
||||
order (Mode.SERVER, List.class, String.class, String.class, Integer.TYPE, Integer.TYPE, List.class, List.class, CardView.class, Boolean.TYPE),
|
||||
sideboard (Mode.SERVER, List.class, CardPool.class, CardPool.class),
|
||||
chooseSingleEntityForEffect(Mode.SERVER, GameEntityView.class, String.class, TrackableCollection.class, DelayedReveal.class, Boolean.TYPE),
|
||||
setCard (Mode.SERVER, Void.TYPE, CardView.class),
|
||||
// TODO case "setPlayerAvatar":
|
||||
openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
|
||||
restoreOldZones (Mode.SERVER, Void.TYPE, Map/*PlayerView,Object*/.class),
|
||||
isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class),
|
||||
|
||||
// Client -> Server
|
||||
// Note: these should all return void, to avoid awkward situations in
|
||||
// which client and server wait for one another's response and block
|
||||
// the threads that're supposed to give that response
|
||||
useMana (Mode.CLIENT, Void.TYPE, Byte.TYPE),
|
||||
undoLastAction (Mode.CLIENT, Void.TYPE, Boolean.TYPE),
|
||||
selectPlayer (Mode.CLIENT, Void.TYPE, PlayerView.class, ITriggerEvent.class),
|
||||
selectCard (Mode.CLIENT, Void.TYPE, CardView.class, List.class, ITriggerEvent.class),
|
||||
selectButtonOk (Mode.CLIENT),
|
||||
selectButtonCancel (Mode.CLIENT),
|
||||
selectAbility (Mode.CLIENT, Void.TYPE, SpellAbilityView.class),
|
||||
passPriorityUntilEndOfTurn(Mode.CLIENT),
|
||||
passPriority (Mode.CLIENT),
|
||||
nextGameDecision (Mode.CLIENT, Void.TYPE, NextGameDecision.class),
|
||||
getActivateDescription (Mode.CLIENT, Void.TYPE, String.class, CardView.class),
|
||||
concede (Mode.CLIENT),
|
||||
alphaStrike (Mode.CLIENT),
|
||||
reorderHand (Mode.CLIENT, Void.TYPE, CardView.class, Integer.TYPE);
|
||||
|
||||
private final Mode mode;
|
||||
private final Class<?> returnType;
|
||||
private final Class<?>[] args;
|
||||
|
||||
private ProtocolMethod(final Mode mode) {
|
||||
this(mode, Void.TYPE);
|
||||
}
|
||||
private ProtocolMethod(final Mode mode, final Class<?> returnType) {
|
||||
this(mode, returnType, (Class<?>[]) null);
|
||||
}
|
||||
@SafeVarargs
|
||||
private ProtocolMethod(final Mode mode, final Class<?> returnType, final Class<?> ... args) {
|
||||
this.mode = mode;
|
||||
this.returnType = returnType;
|
||||
this.args = args == null ? new Class<?>[] {} : args;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
try {
|
||||
final Class<?> toCall = mode.toInvoke;
|
||||
final Method candidate = toCall.getMethod(name(), args);
|
||||
// Don't check Client return values for now as some use void
|
||||
// and a default return value, to improve performance
|
||||
if (mode == Mode.SERVER && !candidate.getReturnType().equals(returnType)) {
|
||||
throw new NoSuchMethodException(String.format("Wrong return type for method %s", name()));
|
||||
}
|
||||
return candidate;
|
||||
} catch (final NoSuchMethodException | SecurityException e) {
|
||||
System.err.println(String.format("Warning: class contains no accessible method named %s", name()));
|
||||
return getMethodNoArgs();
|
||||
}
|
||||
}
|
||||
|
||||
private Method getMethodNoArgs() {
|
||||
try {
|
||||
return mode.toInvoke.getMethod(name(), (Class<?>[]) null);
|
||||
} catch (final NoSuchMethodException | SecurityException e) {
|
||||
System.err.println(String.format("Warning: class contains no accessible arg-less method named %s", name()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public Class<?> getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
public Class<?>[] getArgTypes() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public void checkArgs(final Object[] args) {
|
||||
for (int iArg = 0; iArg < args.length; iArg++) {
|
||||
final Object arg = args[iArg];
|
||||
final Class<?> type = this.args[iArg];
|
||||
if (!ReflectionUtil.isInstance(arg, type)) {
|
||||
throw new InternalError(String.format("Protocol method %s: illegal argument (%d) of type %s, %s expected", name(), iArg, arg.getClass().getName(), type.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkReturnValue(final Object value) {
|
||||
if (returnType.equals(Void.TYPE)) {
|
||||
// If void is expected, any return value is fine
|
||||
return;
|
||||
}
|
||||
if (!ReflectionUtil.isInstance(value, returnType)) {
|
||||
throw new IllegalStateException(String.format("Protocol method %s: illegal return object type %s returned by client, expected %s", name(), value.getClass().getName(), getReturnType().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.ai.AiProfileUtil;
|
||||
import forge.ai.LobbyPlayerAi;
|
||||
import forge.game.player.Player;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.GuiDisplayUtil;
|
||||
@@ -43,15 +42,15 @@ public final class GamePlayerUtil {
|
||||
public final static LobbyPlayer createAiPlayer() {
|
||||
return createAiPlayer(GuiDisplayUtil.getRandomAiName());
|
||||
}
|
||||
public final static LobbyPlayer createAiPlayer(String name) {
|
||||
int avatarCount = GuiBase.getInterface().getAvatarCount();
|
||||
public final static LobbyPlayer createAiPlayer(final String name) {
|
||||
final int avatarCount = GuiBase.getInterface().getAvatarCount();
|
||||
return createAiPlayer(name, avatarCount == 0 ? 0 : MyRandom.getRandom().nextInt(avatarCount));
|
||||
}
|
||||
public final static LobbyPlayer createAiPlayer(String name, int avatarIndex) {
|
||||
public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex) {
|
||||
return createAiPlayer(name, avatarIndex, null);
|
||||
}
|
||||
public final static LobbyPlayer createAiPlayer(String name, int avatarIndex, Set<AIOption> options) {
|
||||
LobbyPlayerAi player = new LobbyPlayerAi(name, options);
|
||||
public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex, final Set<AIOption> options) {
|
||||
final LobbyPlayerAi player = new LobbyPlayerAi(name, options);
|
||||
|
||||
// TODO: implement specific AI profiles for quest mode.
|
||||
String lastProfileChosen = FModel.getPreferences().getPref(FPref.UI_CURRENT_AI_PROFILE);
|
||||
@@ -65,32 +64,20 @@ public final class GamePlayerUtil {
|
||||
return player;
|
||||
}
|
||||
|
||||
public Player getSingleOpponent(Player player) {
|
||||
if (player.getGame().getRegisteredPlayers().size() == 2) {
|
||||
for (Player p : player.getGame().getRegisteredPlayers()) {
|
||||
if (p.isOpponentOf(player)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setPlayerName() {
|
||||
String oldPlayerName = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
final String oldPlayerName = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
|
||||
String newPlayerName;
|
||||
try{
|
||||
if (StringUtils.isBlank(oldPlayerName)) {
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingFirstTimePrompt(), oldPlayerName);
|
||||
}
|
||||
else {
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingStandardPrompt(oldPlayerName), oldPlayerName);
|
||||
}
|
||||
} catch (IllegalStateException ise){
|
||||
//now is not a good time for this...
|
||||
newPlayerName = StringUtils.isBlank(oldPlayerName) ? "Human" : oldPlayerName;
|
||||
}
|
||||
try{
|
||||
if (StringUtils.isBlank(oldPlayerName)) {
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingFirstTimePrompt(), oldPlayerName);
|
||||
} else {
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingStandardPrompt(oldPlayerName), oldPlayerName);
|
||||
}
|
||||
} catch (final IllegalStateException ise){
|
||||
//now is not a good time for this...
|
||||
newPlayerName = StringUtils.isBlank(oldPlayerName) ? "Human" : oldPlayerName;
|
||||
}
|
||||
|
||||
FModel.getPreferences().setPref(FPref.PLAYER_NAME, newPlayerName);
|
||||
FModel.getPreferences().save();
|
||||
@@ -123,7 +110,7 @@ public final class GamePlayerUtil {
|
||||
playerName);
|
||||
}
|
||||
|
||||
private static String getVerifiedPlayerName(String newName, String oldName) {
|
||||
private static String getVerifiedPlayerName(String newName, final String oldName) {
|
||||
if (newName == null || !StringUtils.isAlphanumericSpace(newName)) {
|
||||
newName = (StringUtils.isBlank(oldName) ? "Human" : oldName);
|
||||
} else if (StringUtils.isWhitespace(newName)) {
|
||||
|
||||
@@ -82,14 +82,14 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return AbilityFactory.calculateAmount(card, "ChosenX", null);
|
||||
}*/
|
||||
|
||||
int chosenX = player.getController().chooseNumber(ability, source.toString() + " - Choose a Value for X", 0, maxValue);
|
||||
final int chosenX = player.getController().chooseNumber(ability, source.toString() + " - Choose a Value for X", 0, maxValue);
|
||||
ability.setSVar("ChosenX", Integer.toString(chosenX));
|
||||
source.setSVar("ChosenX", Integer.toString(chosenX));
|
||||
return chosenX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostAddMana cost) {
|
||||
public PaymentDecision visit(final CostAddMana cost) {
|
||||
Integer c = cost.convertAmount();
|
||||
if (c == null) {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
@@ -98,17 +98,18 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostChooseCreatureType cost) {
|
||||
String choice = controller.chooseSomeType("Creature", ability, new ArrayList<String>(CardType.Constant.CREATURE_TYPES), new ArrayList<String>(), true);
|
||||
if (null == choice)
|
||||
public PaymentDecision visit(final CostChooseCreatureType cost) {
|
||||
final String choice = controller.chooseSomeType("Creature", ability, new ArrayList<String>(CardType.Constant.CREATURE_TYPES), new ArrayList<String>(), true);
|
||||
if (null == choice) {
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.type(choice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostDiscard cost) {
|
||||
public PaymentDecision visit(final CostDiscard cost) {
|
||||
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
|
||||
String discardType = cost.getType();
|
||||
final String discardType = cost.getType();
|
||||
final String amount = cost.getAmount();
|
||||
|
||||
if (cost.payCostFromSource()) {
|
||||
@@ -141,13 +142,13 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.card(Aggregates.random(hand, c, new CardCollection()));
|
||||
}
|
||||
if (discardType.contains("+WithSameName")) {
|
||||
String type = discardType.replace("+WithSameName", "");
|
||||
final String type = discardType.replace("+WithSameName", "");
|
||||
hand = CardLists.getValidCards(hand, type.split(";"), player, source);
|
||||
final CardCollectionView landList2 = hand;
|
||||
hand = CardLists.filter(hand, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
for (Card card : landList2) {
|
||||
for (final Card card : landList2) {
|
||||
if (!card.equals(c) && card.getName().equals(c.getName())) {
|
||||
return true;
|
||||
}
|
||||
@@ -158,9 +159,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (c == 0) {
|
||||
return PaymentDecision.card(new CardCollection());
|
||||
}
|
||||
CardCollection discarded = new CardCollection();
|
||||
final CardCollection discarded = new CardCollection();
|
||||
while (c > 0) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, hand);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, hand);
|
||||
inp.setMessage("Select one of the cards with the same name to discard. Already chosen: " + discarded);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -169,15 +170,15 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
final Card first = inp.getFirstSelected();
|
||||
discarded.add(first);
|
||||
CardCollection filteredHand = CardLists.filter(hand, CardPredicates.nameEquals(first.getName()));
|
||||
final CardCollection filteredHand = CardLists.filter(hand, CardPredicates.nameEquals(first.getName()));
|
||||
filteredHand.remove(first);
|
||||
hand = filteredHand;
|
||||
c--;
|
||||
}
|
||||
return PaymentDecision.card(discarded);
|
||||
}
|
||||
|
||||
String type = new String(discardType);
|
||||
|
||||
final String type = new String(discardType);
|
||||
final String[] validType = type.split(";");
|
||||
hand = CardLists.getValidCards(hand, validType, player, source);
|
||||
|
||||
@@ -192,7 +193,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, hand);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, hand);
|
||||
inp.setMessage("Select %d more " + cost.getDescriptiveType() + " to discard.");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -203,7 +204,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostDamage cost) {
|
||||
public PaymentDecision visit(final CostDamage cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final int life = player.getLife();
|
||||
|
||||
@@ -226,7 +227,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostDraw cost) {
|
||||
public PaymentDecision visit(final CostDraw cost) {
|
||||
final String amount = cost.getAmount();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
@@ -242,9 +243,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostExile cost) {
|
||||
public PaymentDecision visit(final CostExile cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final Game game = player.getGame();
|
||||
final Game game = player.getGame();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
String type = cost.getType();
|
||||
@@ -257,7 +258,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
CardCollection list;
|
||||
if (cost.getFrom().equals(ZoneType.Stack)) {
|
||||
list = new CardCollection();
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
for (final SpellAbilityStackInstance si : game.getStack()) {
|
||||
list.add(si.getSourceCard());
|
||||
}
|
||||
}
|
||||
@@ -288,7 +289,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
if (cost.from == ZoneType.Battlefield || cost.from == ZoneType.Hand) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
inp.setMessage("Exile %d card(s) from your" + cost.from);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -299,10 +300,10 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (fromTopGrave) { return exileFromTopGraveType(ability, c, list); }
|
||||
if (!cost.sameZone) { return exileFromMiscZone(cost, ability, c, list); }
|
||||
|
||||
FCollectionView<Player> players = game.getPlayers();
|
||||
List<Player> payableZone = new ArrayList<Player>();
|
||||
for (Player p : players) {
|
||||
CardCollection enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
final FCollectionView<Player> players = game.getPlayers();
|
||||
final List<Player> payableZone = new ArrayList<Player>();
|
||||
for (final Player p : players) {
|
||||
final CardCollection enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
if (enoughType.size() < c) {
|
||||
list.removeAll((CardCollectionView)enoughType);
|
||||
}
|
||||
@@ -312,7 +313,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
return exileFromSame(cost, list, c, payableZone);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Inputs
|
||||
@@ -323,7 +324,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
// ExileFromTop<Num/Type{/TypeDescription}> (of library)
|
||||
// ExileSameGrave<Num/Type{/TypeDescription}>
|
||||
|
||||
private PaymentDecision exileFromSame(CostExile cost, CardCollectionView list, int nNeeded, List<Player> payableZone) {
|
||||
private PaymentDecision exileFromSame(final CostExile cost, final CardCollectionView list, final int nNeeded, final List<Player> payableZone) {
|
||||
if (nNeeded == 0) {
|
||||
return PaymentDecision.number(0);
|
||||
}
|
||||
@@ -342,18 +343,18 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
final CardCollection toExile = game.getCardList(controller.getGui().many("Exile from " + cost.getFrom(), "To be exiled", nNeeded, CardView.getCollection(typeList), null));
|
||||
return PaymentDecision.card(toExile);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostExileFromStack cost) {
|
||||
public PaymentDecision visit(final CostExileFromStack cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final Game game = player.getGame();
|
||||
final Game game = player.getGame();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
String type = cost.getType();
|
||||
List<SpellAbility> saList = new ArrayList<SpellAbility>();
|
||||
ArrayList<String> descList = new ArrayList<String>();
|
||||
final String type = cost.getType();
|
||||
final List<SpellAbility> saList = new ArrayList<SpellAbility>();
|
||||
final List<String> descList = new ArrayList<String>();
|
||||
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
for (final SpellAbilityStackInstance si : game.getStack()) {
|
||||
final Card stC = si.getSourceCard();
|
||||
final SpellAbility stSA = si.getSpellAbility(true).getRootAbility();
|
||||
if (stC.isValid(cost.getType().split(";"), ability.getActivatingPlayer(), source) && stSA.isSpell()) {
|
||||
@@ -383,8 +384,8 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (saList.size() < c) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<SpellAbility> exiled = new ArrayList<SpellAbility>();
|
||||
|
||||
final List<SpellAbility> exiled = new ArrayList<SpellAbility>();
|
||||
for (int i = 0; i < c; i++) {
|
||||
//Have to use the stack descriptions here because some copied spells have no description otherwise
|
||||
final String o = controller.getGui().oneOrNone("Exile from Stack", descList);
|
||||
@@ -394,7 +395,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
saList.remove(toExile);
|
||||
descList.remove(o);
|
||||
|
||||
|
||||
exiled.add(toExile);
|
||||
} else {
|
||||
return null;
|
||||
@@ -413,15 +414,15 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
return PaymentDecision.card(list);
|
||||
}
|
||||
|
||||
private Card getCard(CardView cardView) {
|
||||
|
||||
private Card getCard(final CardView cardView) {
|
||||
return controller.getGame().getCard(cardView);
|
||||
}
|
||||
|
||||
private PaymentDecision exileFromMiscZone(CostExile cost, SpellAbility sa, int nNeeded, CardCollection typeList) {
|
||||
private PaymentDecision exileFromMiscZone(final CostExile cost, final SpellAbility sa, final int nNeeded, final CardCollection typeList) {
|
||||
if (typeList.size() < nNeeded) { return null; }
|
||||
|
||||
CardCollection exiled = new CardCollection();
|
||||
final CardCollection exiled = new CardCollection();
|
||||
for (int i = 0; i < nNeeded; i++) {
|
||||
final Card c = getCard(controller.getGui().oneOrNone("Exile from " + cost.getFrom(), CardView.getCollection(typeList)));
|
||||
if (c == null) { return null; }
|
||||
@@ -432,22 +433,22 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.card(exiled);
|
||||
}
|
||||
|
||||
private PaymentDecision exileFromTopGraveType(SpellAbility sa, int nNeeded, CardCollection typeList) {
|
||||
private PaymentDecision exileFromTopGraveType(final SpellAbility sa, final int nNeeded, final CardCollection typeList) {
|
||||
if (typeList.size() < nNeeded) { return null; }
|
||||
|
||||
Collections.reverse(typeList);
|
||||
return PaymentDecision.card(Iterables.limit(typeList, nNeeded));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostExiledMoveToGrave cost) {
|
||||
public PaymentDecision visit(final CostExiledMoveToGrave cost) {
|
||||
Integer c = cost.convertAmount();
|
||||
if (c == null) {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
CardCollection list = CardLists.getValidCards(activator.getGame().getCardsIn(ZoneType.Exile), cost.getType().split(";"), activator, source);
|
||||
final CardCollection list = CardLists.getValidCards(activator.getGame().getCardsIn(ZoneType.Exile), cost.getType().split(";"), activator, source);
|
||||
|
||||
if (list.size() < c) {
|
||||
return null;
|
||||
@@ -457,7 +458,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostFlipCoin cost) {
|
||||
public PaymentDecision visit(final CostFlipCoin cost) {
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
|
||||
@@ -474,7 +475,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostGainControl cost) {
|
||||
public PaymentDecision visit(final CostGainControl cost) {
|
||||
final String amount = cost.getAmount();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
@@ -482,9 +483,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
final CardCollectionView list = player.getCardsIn(ZoneType.Battlefield);
|
||||
CardCollectionView validCards = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
|
||||
final CardCollectionView validCards = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, validCards);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, validCards);
|
||||
final String desc = cost.getTypeDescription() == null ? cost.getType() : cost.getTypeDescription();
|
||||
inp.setMessage("Gain control of %d " + desc);
|
||||
inp.showAndWait();
|
||||
@@ -495,7 +496,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostGainLife cost) {
|
||||
public PaymentDecision visit(final CostGainLife cost) {
|
||||
final String amount = cost.getAmount();
|
||||
|
||||
final int life = player.getLife();
|
||||
@@ -518,8 +519,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (cost.getCntPlayers() == Integer.MAX_VALUE) // applied to all players who can gain
|
||||
if (cost.getCntPlayers() == Integer.MAX_VALUE) {
|
||||
return PaymentDecision.players(oppsThatCanGainLife);
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(source.getName()).append(" - Choose an opponent to gain ").append(c).append(" life:");
|
||||
@@ -532,7 +534,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostMill cost) {
|
||||
public PaymentDecision visit(final CostMill cost) {
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
|
||||
@@ -546,14 +548,14 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.getController().confirmPayment(cost, "Mill " + c + " card" + (c == 1 ? "" : "s") + " from your library?")) {
|
||||
if (!player.getController().confirmPayment(cost, String.format("Mill %d card%s from your library?", c, c == 1 ? "" : "s"))) {
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.card(player.getCardsIn(ZoneType.Library, c));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostPayLife cost) {
|
||||
public PaymentDecision visit(final CostPayLife cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final int life = player.getLife();
|
||||
|
||||
@@ -566,7 +568,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (sVar.contains("LimitMax")) {
|
||||
limit = AbilityUtils.calculateAmount(source, sVar.split("LimitMax.")[1], ability);
|
||||
}
|
||||
int maxLifePayment = limit < life ? limit : life;
|
||||
final int maxLifePayment = limit < life ? limit : life;
|
||||
c = chooseXValue(maxLifePayment);
|
||||
} else {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
@@ -580,13 +582,13 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostPartMana cost) {
|
||||
public PaymentDecision visit(final CostPartMana cost) {
|
||||
// only interactive payment possible for now =(
|
||||
return new PaymentDecision(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostPutCardToLib cost) {
|
||||
public PaymentDecision visit(final CostPutCardToLib cost) {
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
|
||||
@@ -600,21 +602,21 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
|
||||
CardCollection list = CardLists.getValidCards(cost.sameZone ? player.getGame().getCardsIn(cost.getFrom()) : player.getCardsIn(cost.getFrom()), cost.getType().split(";"), player, source);
|
||||
final CardCollection list = CardLists.getValidCards(cost.sameZone ? player.getGame().getCardsIn(cost.getFrom()) : player.getCardsIn(cost.getFrom()), cost.getType().split(";"), player, source);
|
||||
|
||||
if (cost.from == ZoneType.Hand) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
inp.setMessage("Put %d card(s) from your " + cost.from);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
return inp.hasCancelled() ? null : PaymentDecision.card(inp.getSelected());
|
||||
}
|
||||
|
||||
|
||||
if (cost.sameZone){
|
||||
FCollectionView<Player> players = player.getGame().getPlayers();
|
||||
List<Player> payableZone = new ArrayList<Player>();
|
||||
for (Player p : players) {
|
||||
CardCollectionView enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
final FCollectionView<Player> players = player.getGame().getPlayers();
|
||||
final List<Player> payableZone = new ArrayList<Player>();
|
||||
for (final Player p : players) {
|
||||
final CardCollectionView enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
if (enoughType.size() < c) {
|
||||
list.removeAll(enoughType);
|
||||
} else {
|
||||
@@ -627,12 +629,12 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
|
||||
private PaymentDecision putFromMiscZone(SpellAbility sa, int nNeeded, CardCollection typeList, ZoneType fromZone) {
|
||||
private PaymentDecision putFromMiscZone(final SpellAbility sa, final int nNeeded, final CardCollection typeList, final ZoneType fromZone) {
|
||||
if (typeList.size() < nNeeded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CardCollection chosen = new CardCollection();
|
||||
final CardCollection chosen = new CardCollection();
|
||||
for (int i = 0; i < nNeeded; i++) {
|
||||
final Card c = getCard(controller.getGui().oneOrNone("Put from " + fromZone + " to library", CardView.getCollection(typeList)));
|
||||
if (c == null) {
|
||||
@@ -644,7 +646,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.card(chosen);
|
||||
}
|
||||
|
||||
private PaymentDecision putFromSame(CardCollectionView list, int nNeeded, List<Player> payableZone, ZoneType fromZone) {
|
||||
private PaymentDecision putFromSame(final CardCollectionView list, final int nNeeded, final List<Player> payableZone, final ZoneType fromZone) {
|
||||
if (nNeeded == 0) {
|
||||
return PaymentDecision.number(0);
|
||||
}
|
||||
@@ -653,13 +655,13 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CardCollection typeList = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
|
||||
final CardCollection typeList = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
if (typeList.size() < nNeeded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CardCollection chosen = new CardCollection();
|
||||
final CardCollection chosen = new CardCollection();
|
||||
for (int i = 0; i < nNeeded; i++) {
|
||||
final Card c = getCard(controller.getGui().oneOrNone("Put cards from " + fromZone + " to Library", CardView.getCollection(typeList)));
|
||||
if (c == null) {
|
||||
@@ -670,20 +672,20 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
return PaymentDecision.card(chosen);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostPutCounter cost) {
|
||||
Integer c = cost.getNumberOfCounters(ability);
|
||||
public PaymentDecision visit(final CostPutCounter cost) {
|
||||
final Integer c = cost.getNumberOfCounters(ability);
|
||||
|
||||
if (cost.payCostFromSource()) {
|
||||
cost.setLastPaidAmount(c);
|
||||
return PaymentDecision.number(c);
|
||||
}
|
||||
}
|
||||
|
||||
// Cards to use this branch: Scarscale Ritual, Wandering Mage - each adds only one counter
|
||||
CardCollectionView typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, ability.getHostCard());
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, typeList);
|
||||
// Cards to use this branch: Scarscale Ritual, Wandering Mage - each adds only one counter
|
||||
final CardCollectionView typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, ability.getHostCard());
|
||||
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, typeList);
|
||||
inp.setMessage("Put " + Lang.nounWithAmount(c, cost.getCounter().getName() + " counter") + " on " + cost.getDescriptiveType());
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -695,7 +697,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostReturn cost) {
|
||||
public PaymentDecision visit(final CostReturn cost) {
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
|
||||
@@ -717,9 +719,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
else {
|
||||
CardCollectionView validCards = CardLists.getValidCards(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ability.getActivatingPlayer(), ability.getHostCard());
|
||||
final CardCollectionView validCards = CardLists.getValidCards(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ability.getActivatingPlayer(), ability.getHostCard());
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, validCards);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, validCards);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.setMessage("Return %d " + cost.getType() + " " + cost.getType() + " card(s) to hand");
|
||||
inp.showAndWait();
|
||||
@@ -727,12 +729,12 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.card(inp.getSelected());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostReveal cost) {
|
||||
public PaymentDecision visit(final CostReveal cost) {
|
||||
final String amount = cost.getAmount();
|
||||
|
||||
if (cost.payCostFromSource()) {
|
||||
@@ -743,13 +745,13 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
InputSelectCardsFromList inp = null;
|
||||
if (cost.getType().equals("SameColor")) {
|
||||
Integer num = cost.convertAmount();
|
||||
final Integer num = cost.convertAmount();
|
||||
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
|
||||
final CardCollectionView hand2 = hand;
|
||||
hand = CardLists.filter(hand, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
for (Card card : hand2) {
|
||||
for (final Card card : hand2) {
|
||||
if (!card.equals(c) && card.sharesColorWith(c)) {
|
||||
return true;
|
||||
}
|
||||
@@ -764,8 +766,8 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
private static final long serialVersionUID = 8338626212893374798L;
|
||||
|
||||
@Override
|
||||
protected boolean onCardSelected(Card c, final List<Card> otherCardsToSelect, ITriggerEvent triggerEvent) {
|
||||
Card firstCard = Iterables.getFirst(this.selected, null);
|
||||
protected boolean onCardSelected(final Card c, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) {
|
||||
final Card firstCard = Iterables.getFirst(this.selected, null);
|
||||
if (firstCard != null && !CardPredicates.sharesColorWith(firstCard).apply(c)) {
|
||||
return false;
|
||||
}
|
||||
@@ -788,9 +790,10 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
num = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
}
|
||||
if (num == 0)
|
||||
return PaymentDecision.number(0);;
|
||||
|
||||
if (num == 0) {
|
||||
return PaymentDecision.number(0);
|
||||
};
|
||||
|
||||
inp = new InputSelectCardsFromList(controller, num, num, hand);
|
||||
inp.setMessage("Select %d more " + cost.getDescriptiveType() + " card(s) to reveal.");
|
||||
}
|
||||
@@ -803,7 +806,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostRemoveAnyCounter cost) {
|
||||
public PaymentDecision visit(final CostRemoveAnyCounter cost) {
|
||||
Integer c = cost.convertAmount();
|
||||
final String type = cost.getType();
|
||||
|
||||
@@ -821,22 +824,22 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return card.hasCounters();
|
||||
}
|
||||
});
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, list);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, list);
|
||||
inp.setMessage("Select " + cost.getDescriptiveType() + " to remove a counter");
|
||||
inp.setCancelAllowed(false);
|
||||
inp.showAndWait();
|
||||
Card selected = inp.getFirstSelected();
|
||||
final Card selected = inp.getFirstSelected();
|
||||
final Map<CounterType, Integer> tgtCounters = selected.getCounters();
|
||||
final ArrayList<CounterType> typeChoices = new ArrayList<CounterType>();
|
||||
for (CounterType key : tgtCounters.keySet()) {
|
||||
final List<CounterType> typeChoices = new ArrayList<CounterType>();
|
||||
for (final CounterType key : tgtCounters.keySet()) {
|
||||
if (tgtCounters.get(key) > 0) {
|
||||
typeChoices.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
String prompt = "Select type counters to remove";
|
||||
final String prompt = "Select type counters to remove";
|
||||
cost.setCounterType(controller.getGui().one(prompt, typeChoices));
|
||||
|
||||
|
||||
return PaymentDecision.card(selected, cost.getCounter());
|
||||
}
|
||||
|
||||
@@ -847,20 +850,20 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
private final CounterType counterType;
|
||||
private final CardCollectionView validChoices;
|
||||
|
||||
public InputSelectCardToRemoveCounter(final PlayerControllerHuman controller, int cntCounters, CounterType cType, CardCollectionView validCards) {
|
||||
public InputSelectCardToRemoveCounter(final PlayerControllerHuman controller, final int cntCounters, final CounterType cType, final CardCollectionView validCards) {
|
||||
super(controller, cntCounters, cntCounters);
|
||||
this.validChoices = validCards;
|
||||
counterType = cType;
|
||||
cardsChosen = cntCounters > 0 ? new HashMap<Card, Integer>() : null;
|
||||
cardsChosen = cntCounters > 0 ? new HashMap<Card, Integer>() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onCardSelected(Card c, final List<Card> otherCardsToSelect, ITriggerEvent triggerEvent) {
|
||||
protected boolean onCardSelected(final Card c, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) {
|
||||
if (!isValidChoice(c) || c.getCounters(counterType) <= getTimesSelected(c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int tc = getTimesSelected(c);
|
||||
final int tc = getTimesSelected(c);
|
||||
cardsChosen.put(c, tc + 1);
|
||||
|
||||
onSelectStateChanged(c, true);
|
||||
@@ -869,7 +872,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivateAction(Card c) {
|
||||
public String getActivateAction(final Card c) {
|
||||
if (!isValidChoice(c) || c.getCounters(counterType) <= getTimesSelected(c)) {
|
||||
return null;
|
||||
}
|
||||
@@ -883,29 +886,30 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
@Override
|
||||
protected boolean hasAllTargets() {
|
||||
int sum = getDistibutedCounters();
|
||||
final int sum = getDistibutedCounters();
|
||||
return sum >= max;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMessage() {
|
||||
return max == Integer.MAX_VALUE
|
||||
? String.format(message, getDistibutedCounters())
|
||||
: String.format(message, max - getDistibutedCounters());
|
||||
? String.format(message, getDistibutedCounters())
|
||||
: String.format(message, max - getDistibutedCounters());
|
||||
}
|
||||
|
||||
private int getDistibutedCounters() {
|
||||
int sum = 0;
|
||||
for (Entry<Card, Integer> kv : cardsChosen.entrySet()) {
|
||||
for (final Entry<Card, Integer> kv : cardsChosen.entrySet()) {
|
||||
sum += kv.getValue().intValue();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
protected final boolean isValidChoice(GameEntity choice) {
|
||||
|
||||
protected final boolean isValidChoice(final GameEntity choice) {
|
||||
return validChoices.contains(choice);
|
||||
}
|
||||
|
||||
public int getTimesSelected(Card c) {
|
||||
public int getTimesSelected(final Card c) {
|
||||
return cardsChosen.containsKey(c) ? cardsChosen.get(c).intValue() : 0;
|
||||
}
|
||||
|
||||
@@ -914,23 +918,23 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return cardsChosen.keySet();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostRemoveCounter cost) {
|
||||
public PaymentDecision visit(final CostRemoveCounter cost) {
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
final Integer c = cost.convertAmount();
|
||||
final String type = cost.getType();
|
||||
|
||||
String sVarAmount = ability.getSVar(amount);
|
||||
final String sVarAmount = ability.getSVar(amount);
|
||||
int cntRemoved = 1;
|
||||
if (c != null)
|
||||
if (c != null) {
|
||||
cntRemoved = c.intValue();
|
||||
else if (!"XChoice".equals(sVarAmount)) {
|
||||
} else if (!"XChoice".equals(sVarAmount)) {
|
||||
cntRemoved = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
|
||||
if (cost.payCostFromSource()) {
|
||||
int maxCounters = source.getCounters(cost.counter);
|
||||
final int maxCounters = source.getCounters(cost.counter);
|
||||
if (amount.equals("All")) {
|
||||
final CardView view = CardView.get(ability.getHostCard());
|
||||
if (!controller.getGui().confirm(view, "Remove all counters?")) {
|
||||
@@ -938,26 +942,28 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
cntRemoved = maxCounters;
|
||||
}
|
||||
else if (c == null && "XChoice".equals(sVarAmount)) {
|
||||
else if (c == null && "XChoice".equals(sVarAmount)) {
|
||||
cntRemoved = chooseXValue(maxCounters);
|
||||
}
|
||||
|
||||
if (maxCounters < cntRemoved)
|
||||
if (maxCounters < cntRemoved) {
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.card(source, cntRemoved >= 0 ? cntRemoved : maxCounters);
|
||||
|
||||
|
||||
} else if (type.equals("OriginalHost")) {
|
||||
int maxCounters = ability.getOriginalHost().getCounters(cost.counter);
|
||||
final int maxCounters = ability.getOriginalHost().getCounters(cost.counter);
|
||||
if (amount.equals("All")) {
|
||||
cntRemoved = maxCounters;
|
||||
}
|
||||
if (maxCounters < cntRemoved)
|
||||
if (maxCounters < cntRemoved) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return PaymentDecision.card(ability.getOriginalHost(), cntRemoved >= 0 ? cntRemoved : maxCounters);
|
||||
}
|
||||
|
||||
CardCollectionView validCards = CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source);
|
||||
final CardCollectionView validCards = CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source);
|
||||
if (cost.zone.equals(ZoneType.Battlefield)) {
|
||||
final InputSelectCardToRemoveCounter inp = new InputSelectCardToRemoveCounter(controller, cntRemoved, cost.counter, validCards);
|
||||
inp.setMessage("Remove %d " + cost.counter.getName() + " counters from " + cost.getDescriptiveType());
|
||||
@@ -971,18 +977,20 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
// triggers will fire when last is removed by executePayment.
|
||||
// They don't care how many were removed anyway
|
||||
// int sum = 0;
|
||||
for (Card crd : inp.getSelected()) {
|
||||
int removed = inp.getTimesSelected(crd);
|
||||
// sum += removed;
|
||||
if (removed < 2) continue;
|
||||
int oldVal = crd.getCounters().get(cost.counter).intValue();
|
||||
for (final Card crd : inp.getSelected()) {
|
||||
final int removed = inp.getTimesSelected(crd);
|
||||
// sum += removed;
|
||||
if (removed < 2) {
|
||||
continue;
|
||||
}
|
||||
final int oldVal = crd.getCounters().get(cost.counter).intValue();
|
||||
crd.getCounters().put(cost.counter, Integer.valueOf(oldVal - removed + 1));
|
||||
}
|
||||
return PaymentDecision.card(inp.getSelected(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Rift Elemental only - always removes 1 counter, so there will be no code for N counters.
|
||||
List<CardView> suspended = Lists.newArrayList();
|
||||
final List<CardView> suspended = Lists.newArrayList();
|
||||
for (final Card crd : validCards) {
|
||||
if (crd.getCounters(cost.counter) > 0) {
|
||||
suspended.add(CardView.get(crd));
|
||||
@@ -994,7 +1002,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostSacrifice cost) {
|
||||
public PaymentDecision visit(final CostSacrifice cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final String type = cost.getType();
|
||||
|
||||
@@ -1015,7 +1023,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
if (amount.equals("All")) {
|
||||
return PaymentDecision.card(list);
|
||||
}
|
||||
}
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
if (c == null) {
|
||||
@@ -1032,19 +1040,20 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (list.size() < c) {
|
||||
return null;
|
||||
}
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
inp.setMessage("Select a " + cost.getDescriptiveType() + " to sacrifice (%d left)");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
if (inp.hasCancelled())
|
||||
if (inp.hasCancelled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return PaymentDecision.card(inp.getSelected());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostTap cost) {
|
||||
public PaymentDecision visit(final CostTap cost) {
|
||||
// if (!canPay(ability, source, ability.getActivatingPlayer(),
|
||||
// payment.getCost()))
|
||||
// return false;
|
||||
@@ -1052,7 +1061,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostTapType cost) {
|
||||
public PaymentDecision visit(final CostTapType cost) {
|
||||
String type = cost.getType();
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
@@ -1088,7 +1097,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
typeList = CardLists.filter(typeList, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
for (Card card : list2) {
|
||||
for (final Card card : list2) {
|
||||
if (!card.equals(c) && card.sharesCreatureTypeWith(c)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1096,10 +1105,12 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (c == 0) return PaymentDecision.number(0);
|
||||
CardCollection tapped = new CardCollection();
|
||||
if (c == 0) {
|
||||
return PaymentDecision.number(0);
|
||||
}
|
||||
final CardCollection tapped = new CardCollection();
|
||||
while (c > 0) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, typeList);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, typeList);
|
||||
inp.setMessage("Select one of the cards to tap. Already chosen: " + tapped);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -1118,11 +1129,11 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
c--;
|
||||
}
|
||||
return PaymentDecision.card(tapped);
|
||||
}
|
||||
}
|
||||
|
||||
if (totalPower) {
|
||||
int i = Integer.parseInt(totalP);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 0, typeList.size(), typeList);
|
||||
final int i = Integer.parseInt(totalP);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 0, typeList.size(), typeList);
|
||||
inp.setMessage("Select a card to tap.");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -1133,7 +1144,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.card(inp.getSelected());
|
||||
}
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, typeList);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, typeList);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.setMessage("Select a " + cost.getDescriptiveType() + " to tap (%d left)");
|
||||
inp.showAndWait();
|
||||
@@ -1144,7 +1155,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostUntapType cost) {
|
||||
public PaymentDecision visit(final CostUntapType cost) {
|
||||
CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"),
|
||||
player, ability.getHostCard());
|
||||
typeList = CardLists.filter(typeList, Presets.TAPPED);
|
||||
@@ -1162,7 +1173,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
}
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, typeList);
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, typeList);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.setMessage("Select a " + cost.getDescriptiveType() + " to untap (%d left)");
|
||||
inp.showAndWait();
|
||||
@@ -1173,15 +1184,15 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostUntap cost) {
|
||||
public PaymentDecision visit(final CostUntap cost) {
|
||||
return PaymentDecision.number(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostUnattach cost) {
|
||||
public PaymentDecision visit(final CostUnattach cost) {
|
||||
final Card source = ability.getHostCard();
|
||||
|
||||
Card cardToUnattach = cost.findCardToUnattach(source, player, ability);
|
||||
|
||||
final Card cardToUnattach = cost.findCardToUnattach(source, player, ability);
|
||||
if (cardToUnattach != null && player.getController().confirmPayment(cost, "Unattach " + cardToUnattach.getName() + "?")) {
|
||||
return PaymentDecision.card(cardToUnattach);
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -47,7 +47,7 @@ import forge.util.FCollection;
|
||||
* <p>
|
||||
* SpellAbility_Requirements class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: HumanPlaySpellAbility.java 24317 2014-01-17 08:32:39Z Max mtg $
|
||||
*/
|
||||
@@ -62,7 +62,7 @@ public class HumanPlaySpellAbility {
|
||||
payment = payment0;
|
||||
}
|
||||
|
||||
public final void playAbility(boolean mayChooseTargets, boolean isFree, boolean skipStack) {
|
||||
public final void playAbility(final boolean mayChooseTargets, final boolean isFree, final boolean skipStack) {
|
||||
final Player human = ability.getActivatingPlayer();
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
@@ -75,9 +75,9 @@ public class HumanPlaySpellAbility {
|
||||
final Card c = ability.getHostCard();
|
||||
final CardPlayOption option = c.mayPlay(human);
|
||||
|
||||
boolean manaConversion = (ability.isSpell() && (c.hasKeyword("May spend mana as though it were mana of any color to cast CARDNAME")
|
||||
final boolean manaConversion = (ability.isSpell() && (c.hasKeyword("May spend mana as though it were mana of any color to cast CARDNAME")
|
||||
|| (option != null && option.isIgnoreManaCostColor())));
|
||||
boolean playerManaConversion = human.hasManaConversion()
|
||||
final boolean playerManaConversion = human.hasManaConversion()
|
||||
&& human.getController().confirmAction(ability, null, "Do you want to spend mana as though it were mana of any color to pay the cost?");
|
||||
if (ability instanceof Spell && !c.isCopiedSpell()) {
|
||||
fromZone = game.getZoneOf(c);
|
||||
@@ -106,7 +106,7 @@ public class HumanPlaySpellAbility {
|
||||
}
|
||||
// This line makes use of short-circuit evaluation of boolean values, that is each subsequent argument
|
||||
// is only executed or evaluated if the first argument does not suffice to determine the value of the expression
|
||||
boolean prerequisitesMet = announceValuesLikeX()
|
||||
final boolean prerequisitesMet = announceValuesLikeX()
|
||||
&& announceType()
|
||||
&& (!mayChooseTargets || setupTargets()) // if you can choose targets, then do choose them.
|
||||
&& (isFree || payment.payCost(new HumanCostDecision(controller, human, ability, ability.getHostCard())));
|
||||
@@ -160,12 +160,12 @@ public class HumanPlaySpellAbility {
|
||||
SpellAbility currentAbility = ability;
|
||||
final Card source = ability.getHostCard();
|
||||
do {
|
||||
TargetRestrictions tgt = currentAbility.getTargetRestrictions();
|
||||
final TargetRestrictions tgt = currentAbility.getTargetRestrictions();
|
||||
if (tgt != null && tgt.doesTarget()) {
|
||||
clearTargets(currentAbility);
|
||||
Player targetingPlayer;
|
||||
if (currentAbility.hasParam("TargetingPlayer")) {
|
||||
FCollection<Player> candidates = AbilityUtils.getDefinedPlayers(source, currentAbility.getParam("TargetingPlayer"), currentAbility);
|
||||
final FCollection<Player> candidates = AbilityUtils.getDefinedPlayers(source, currentAbility.getParam("TargetingPlayer"), currentAbility);
|
||||
// activator chooses targeting player
|
||||
targetingPlayer = ability.getActivatingPlayer().getController().chooseSingleEntityForEffect(
|
||||
candidates, currentAbility, "Choose the targeting player");
|
||||
@@ -173,8 +173,9 @@ public class HumanPlaySpellAbility {
|
||||
targetingPlayer = ability.getActivatingPlayer();
|
||||
}
|
||||
currentAbility.setTargetingPlayer(targetingPlayer);
|
||||
if (!targetingPlayer.getController().chooseTargetsFor(currentAbility))
|
||||
if (!targetingPlayer.getController().chooseTargetsFor(currentAbility)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final SpellAbility subAbility = currentAbility.getSubAbility();
|
||||
if (subAbility != null) {
|
||||
@@ -186,15 +187,15 @@ public class HumanPlaySpellAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
public final void clearTargets(SpellAbility ability) {
|
||||
TargetRestrictions tg = ability.getTargetRestrictions();
|
||||
public final void clearTargets(final SpellAbility ability) {
|
||||
final TargetRestrictions tg = ability.getTargetRestrictions();
|
||||
if (tg != null) {
|
||||
ability.resetTargets();
|
||||
tg.calculateStillToDivide(ability.getParam("DividedAsYouChoose"), ability.getHostCard(), ability);
|
||||
}
|
||||
}
|
||||
|
||||
private void rollbackAbility(final Zone fromZone, final CardStateName fromState, final int zonePosition) {
|
||||
private void rollbackAbility(final Zone fromZone, final CardStateName fromState, final int zonePosition) {
|
||||
// cancel ability during target choosing
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
@@ -213,24 +214,24 @@ public class HumanPlaySpellAbility {
|
||||
|
||||
private boolean announceValuesLikeX() {
|
||||
if (ability.isCopied()) { return true; } //don't re-announce for spell copies
|
||||
|
||||
|
||||
boolean needX = true;
|
||||
boolean allowZero = !ability.hasParam("XCantBe0");
|
||||
CostPartMana manaCost = ability.getPayCosts().getCostMana();
|
||||
PlayerController controller = ability.getActivatingPlayer().getController();
|
||||
Card card = ability.getHostCard();
|
||||
final boolean allowZero = !ability.hasParam("XCantBe0");
|
||||
final CostPartMana manaCost = ability.getPayCosts().getCostMana();
|
||||
final PlayerController controller = ability.getActivatingPlayer().getController();
|
||||
final Card card = ability.getHostCard();
|
||||
|
||||
// Announcing Requirements like Choosing X or Multikicker
|
||||
// SA Params as comma delimited list
|
||||
String announce = ability.getParam("Announce");
|
||||
final String announce = ability.getParam("Announce");
|
||||
if (announce != null) {
|
||||
for (String aVar : announce.split(",")) {
|
||||
String varName = aVar.trim();
|
||||
for (final String aVar : announce.split(",")) {
|
||||
final String varName = aVar.trim();
|
||||
|
||||
boolean isX = "X".equalsIgnoreCase(varName);
|
||||
final boolean isX = "X".equalsIgnoreCase(varName);
|
||||
if (isX) { needX = false; }
|
||||
|
||||
Integer value = controller.announceRequirements(ability, varName, allowZero && (!isX || manaCost == null || manaCost.canXbe0()));
|
||||
final Integer value = controller.announceRequirements(ability, varName, allowZero && (!isX || manaCost == null || manaCost.canXbe0()));
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -246,9 +247,9 @@ public class HumanPlaySpellAbility {
|
||||
}
|
||||
|
||||
if (needX && manaCost != null && manaCost.getAmountOfX() > 0) {
|
||||
String sVar = ability.getSVar("X"); //only prompt for new X value if card doesn't determine it another way
|
||||
final String sVar = ability.getSVar("X"); //only prompt for new X value if card doesn't determine it another way
|
||||
if ("Count$xPaid".equals(sVar) || sVar.isEmpty()) {
|
||||
Integer value = controller.announceRequirements(ability, "X", allowZero && manaCost.canXbe0());
|
||||
final Integer value = controller.announceRequirements(ability, "X", allowZero && manaCost.canXbe0());
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -262,19 +263,19 @@ public class HumanPlaySpellAbility {
|
||||
private boolean announceType() {
|
||||
if (ability.isCopied()) { return true; } //don't re-announce for spell copies
|
||||
|
||||
String announce = ability.getParam("AnnounceType");
|
||||
PlayerController pc = ability.getActivatingPlayer().getController();
|
||||
final String announce = ability.getParam("AnnounceType");
|
||||
final PlayerController pc = ability.getActivatingPlayer().getController();
|
||||
if (announce != null) {
|
||||
for (String aVar : announce.split(",")) {
|
||||
String varName = aVar.trim();
|
||||
for (final String aVar : announce.split(",")) {
|
||||
final String varName = aVar.trim();
|
||||
if ("CreatureType".equals(varName)) {
|
||||
final String choice = pc.chooseSomeType("Creature", ability, CardType.Constant.CREATURE_TYPES, Collections.<String>emptyList());
|
||||
ability.getHostCard().setChosenType(choice);
|
||||
}
|
||||
if ("ChooseNumber".equals(varName)) {
|
||||
int min = Integer.parseInt(ability.getParam("Min"));
|
||||
int max = Integer.parseInt(ability.getParam("Max"));
|
||||
int i = ability.getActivatingPlayer().getController().chooseNumber(ability,
|
||||
final int min = Integer.parseInt(ability.getParam("Min"));
|
||||
final int max = Integer.parseInt(ability.getParam("Max"));
|
||||
final int i = ability.getActivatingPlayer().getController().chooseNumber(ability,
|
||||
"Choose a number", min, max);
|
||||
ability.getHostCard().setChosenNumber(i);
|
||||
}
|
||||
@@ -283,7 +284,7 @@ public class HumanPlaySpellAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void enusureAbilityHasDescription(SpellAbility ability) {
|
||||
private static void enusureAbilityHasDescription(final SpellAbility ability) {
|
||||
if (!StringUtils.isBlank(ability.getStackDescription())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactor
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerController createMindSlaveController(Player master, Player slave) {
|
||||
public PlayerController createMindSlaveController(final Player master, final Player slave) {
|
||||
return new PlayerControllerHuman(slave, this, (PlayerControllerHuman)master.getController());
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactor
|
||||
return player;
|
||||
}
|
||||
|
||||
public void hear(LobbyPlayer player, String message) {
|
||||
//ostedMatch.getController().hear(player, message);
|
||||
@Override
|
||||
public void hear(final LobbyPlayer player, final String message) {
|
||||
//hostedMatch.getController().hear(player, message);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -82,7 +82,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
||||
|
||||
UI_VIBRATE_ON_LIFE_LOSS("true"),
|
||||
UI_VIBRATE_ON_LONG_PRESS("true"),
|
||||
|
||||
|
||||
UI_LANGUAGE("en-US"),
|
||||
|
||||
MATCH_HOT_SEAT_MODE("false"), //this only applies to mobile game
|
||||
@@ -162,12 +162,10 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
||||
|
||||
private final String strDefaultVal;
|
||||
|
||||
/** @param s0   {@link java.lang.String} */
|
||||
FPref(String s0) {
|
||||
private FPref(final String s0) {
|
||||
this.strDefaultVal = s0;
|
||||
}
|
||||
|
||||
/** @return {@link java.lang.String} */
|
||||
public String getDefault() {
|
||||
return strDefaultVal;
|
||||
}
|
||||
@@ -179,39 +177,28 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
||||
CONSTRUCTED_P7_DECK_STATE, CONSTRUCTED_P8_DECK_STATE };
|
||||
}
|
||||
|
||||
public static enum CardSizeType {
|
||||
tiny, smaller, small, medium, large, huge
|
||||
}
|
||||
|
||||
|
||||
public static enum StackOffsetType {
|
||||
tiny, small, medium, large
|
||||
}
|
||||
|
||||
|
||||
public static enum HomeMenus {
|
||||
constructed, draft, sealed, quest, settings, utilities
|
||||
}
|
||||
|
||||
/** Instantiates a ForgePreferences object. */
|
||||
public ForgePreferences() {
|
||||
super(ForgeConstants.MAIN_PREFS_FILE, FPref.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FPref[] getEnumValues() {
|
||||
return FPref.values();
|
||||
}
|
||||
|
||||
protected FPref valueOf(String name) {
|
||||
@Override
|
||||
protected FPref valueOf(final String name) {
|
||||
try {
|
||||
return FPref.valueOf(name);
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getPrefDefault(FPref key) {
|
||||
@Override
|
||||
protected String getPrefDefault(final FPref key) {
|
||||
return key.getDefault();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -40,7 +40,7 @@ public class ForgeProfileProperties {
|
||||
private static String cacheDir;
|
||||
private static String cardPicsDir;
|
||||
private static Map<String, String> cardPicsSubDirs;
|
||||
private static int serverPort;
|
||||
private static int serverPort;
|
||||
|
||||
private static final String USER_DIR_KEY = "userDir";
|
||||
private static final String CACHE_DIR_KEY = "cacheDir";
|
||||
@@ -52,22 +52,18 @@ public class ForgeProfileProperties {
|
||||
//prevent initializing static class
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Properties props = new Properties();
|
||||
File propFile = new File(ForgeConstants.PROFILE_FILE);
|
||||
final Properties props = new Properties();
|
||||
final File propFile = new File(ForgeConstants.PROFILE_FILE);
|
||||
try {
|
||||
if (propFile.canRead()) {
|
||||
props.load(new FileInputStream(propFile));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (final IOException e) {
|
||||
System.err.println("error while reading from profile properties file");
|
||||
}
|
||||
|
||||
Pair<String, String> defaults = getDefaultDirs();
|
||||
final Pair<String, String> defaults = getDefaultDirs();
|
||||
userDir = getDir(props, USER_DIR_KEY, defaults.getLeft());
|
||||
cacheDir = getDir(props, CACHE_DIR_KEY, defaults.getRight());
|
||||
cardPicsDir = getDir(props, CARD_PICS_DIR_KEY, cacheDir + "pics" + File.separator + "cards" + File.separator);
|
||||
@@ -83,7 +79,7 @@ public class ForgeProfileProperties {
|
||||
public static String getUserDir() {
|
||||
return userDir;
|
||||
}
|
||||
public static void setUserDir(String userDir0) {
|
||||
public static void setUserDir(final String userDir0) {
|
||||
userDir = userDir0;
|
||||
save();
|
||||
}
|
||||
@@ -91,8 +87,8 @@ public class ForgeProfileProperties {
|
||||
public static String getCacheDir() {
|
||||
return cacheDir;
|
||||
}
|
||||
public static void setCacheDir(String cacheDir0) {
|
||||
int idx = cardPicsDir.indexOf(cacheDir); //ensure card pics directory is updated too if within cache directory
|
||||
public static void setCacheDir(final String cacheDir0) {
|
||||
final int idx = cardPicsDir.indexOf(cacheDir); //ensure card pics directory is updated too if within cache directory
|
||||
if (idx != -1) {
|
||||
cardPicsDir = cacheDir0 + cardPicsDir.substring(idx + cacheDir.length());
|
||||
}
|
||||
@@ -103,8 +99,8 @@ public class ForgeProfileProperties {
|
||||
public static String getCardPicsDir() {
|
||||
return cardPicsDir;
|
||||
}
|
||||
public static void setCardPicsDir(String cardPicsDir0) {
|
||||
cardPicsDir = cardPicsDir0;
|
||||
public static void setCardPicsDir(final String cardPicsDir0) {
|
||||
cardPicsDir = cardPicsDir0;
|
||||
save();
|
||||
}
|
||||
|
||||
@@ -116,28 +112,29 @@ public class ForgeProfileProperties {
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
private static Map<String, String> getMap(Properties props, String propertyKey) {
|
||||
String strMap = props.getProperty(propertyKey, "").trim();
|
||||
private static Map<String, String> getMap(final Properties props, final String propertyKey) {
|
||||
final String strMap = props.getProperty(propertyKey, "").trim();
|
||||
return FileSection.parseToMap(strMap, "->", "|");
|
||||
}
|
||||
|
||||
private static int getInt(Properties props, String propertyKey, int defaultValue) {
|
||||
String strValue = props.getProperty(propertyKey, "").trim();
|
||||
if ( StringUtils.isNotBlank(strValue) && StringUtils.isNumeric(strValue) )
|
||||
private static int getInt(final Properties props, final String propertyKey, final int defaultValue) {
|
||||
final String strValue = props.getProperty(propertyKey, "").trim();
|
||||
if (StringUtils.isNotBlank(strValue) && StringUtils.isNumeric(strValue)) {
|
||||
return Integer.parseInt(strValue);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getDir(Properties props, String propertyKey, String defaultVal) {
|
||||
private static String getDir(final Properties props, final String propertyKey, final String defaultVal) {
|
||||
String retDir = props.getProperty(propertyKey, defaultVal).trim();
|
||||
if (retDir.isEmpty()) {
|
||||
// use default if dir is "defined" as an empty string in the properties file
|
||||
retDir = defaultVal;
|
||||
}
|
||||
|
||||
|
||||
// canonicalize
|
||||
retDir = new File(retDir).getAbsolutePath();
|
||||
|
||||
|
||||
// ensure path ends in a slash
|
||||
if (File.separatorChar == retDir.charAt(retDir.length() - 1)) {
|
||||
return retDir;
|
||||
@@ -148,18 +145,18 @@ public class ForgeProfileProperties {
|
||||
// returns a pair <userDir, cacheDir>
|
||||
private static Pair<String, String> getDefaultDirs() {
|
||||
if (!GuiBase.getInterface().isRunningOnDesktop()) { //special case for mobile devices
|
||||
String assetsDir = ForgeConstants.ASSETS_DIR;
|
||||
final String assetsDir = ForgeConstants.ASSETS_DIR;
|
||||
return Pair.of(assetsDir + "data" + File.separator, assetsDir + "cache" + File.separator);
|
||||
}
|
||||
|
||||
String osName = System.getProperty("os.name");
|
||||
String homeDir = System.getProperty("user.home");
|
||||
final String osName = System.getProperty("os.name");
|
||||
final String homeDir = System.getProperty("user.home");
|
||||
|
||||
if (StringUtils.isEmpty(osName) || StringUtils.isEmpty(homeDir)) {
|
||||
throw new RuntimeException("cannot determine OS and user home directory");
|
||||
}
|
||||
|
||||
String fallbackDataDir = String.format("%s/.forge", homeDir);
|
||||
|
||||
final String fallbackDataDir = String.format("%s/.forge", homeDir);
|
||||
|
||||
if (StringUtils.containsIgnoreCase(osName, "windows")) {
|
||||
// the split between appdata and localappdata on windows is relatively recent. If
|
||||
@@ -179,7 +176,7 @@ public class ForgeProfileProperties {
|
||||
}
|
||||
else if (StringUtils.containsIgnoreCase(osName, "mac os x")) {
|
||||
return Pair.of(String.format("%s/Library/Application Support/Forge", homeDir),
|
||||
String.format("%s/Library/Caches/Forge", homeDir));
|
||||
String.format("%s/Library/Caches/Forge", homeDir));
|
||||
}
|
||||
|
||||
// Linux and everything else
|
||||
@@ -187,13 +184,13 @@ public class ForgeProfileProperties {
|
||||
}
|
||||
|
||||
private static void save() {
|
||||
Pair<String, String> defaults = getDefaultDirs();
|
||||
String defaultUserDir = defaults.getLeft() + File.separator;
|
||||
String defaultCacheDir = defaults.getRight() + File.separator;
|
||||
String defaultCardPicsDir = defaultCacheDir + "pics" + File.separator + "cards" + File.separator;
|
||||
final Pair<String, String> defaults = getDefaultDirs();
|
||||
final String defaultUserDir = defaults.getLeft() + File.separator;
|
||||
final String defaultCacheDir = defaults.getRight() + File.separator;
|
||||
final String defaultCardPicsDir = defaultCacheDir + "pics" + File.separator + "cards" + File.separator;
|
||||
|
||||
//only append values that aren't equal to defaults
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
if (!userDir.equals(defaultUserDir)) { //ensure backslashes are escaped
|
||||
sb.append(USER_DIR_KEY + "=" + userDir.replace("\\", "\\\\") + "\n");
|
||||
}
|
||||
@@ -205,8 +202,8 @@ public class ForgeProfileProperties {
|
||||
}
|
||||
if (cardPicsSubDirs.size() > 0) {
|
||||
sb.append(CARD_PICS_SUB_DIRS_KEY + "=");
|
||||
boolean needDelim = false;
|
||||
for (Map.Entry<String, String> entry : cardPicsSubDirs.entrySet()) {
|
||||
final boolean needDelim = false;
|
||||
for (final Map.Entry<String, String> entry : cardPicsSubDirs.entrySet()) {
|
||||
if (needDelim) {
|
||||
sb.append("|");
|
||||
}
|
||||
@@ -222,12 +219,11 @@ public class ForgeProfileProperties {
|
||||
}
|
||||
else { //delete file if empty
|
||||
try {
|
||||
File file = new File(ForgeConstants.PROFILE_FILE);
|
||||
final File file = new File(ForgeConstants.PROFILE_FILE);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.properties;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A collection of name/value pairs with sorted keys and utility methods.
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Preferences {
|
||||
|
||||
/** The props. */
|
||||
private final Properties props;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for Preferences.
|
||||
* </p>
|
||||
*/
|
||||
public Preferences() {
|
||||
this.props = new Properties();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for Preferences.
|
||||
* </p>
|
||||
*
|
||||
* @param prefs
|
||||
* a {@link forge.properties.Preferences} object.
|
||||
*/
|
||||
public Preferences(final Preferences prefs) {
|
||||
this.props = prefs.props;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* keys.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link java.util.Enumeration} object.
|
||||
*/
|
||||
public final synchronized Enumeration<String> keys() {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
final Set<String> keysEnum = (Set) this.props.keySet();
|
||||
final Vector<String> keyList = new Vector<String>();
|
||||
keyList.addAll(keysEnum);
|
||||
Collections.sort(keyList);
|
||||
return keyList.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getInt.
|
||||
* </p>
|
||||
*
|
||||
* @param name
|
||||
* a {@link java.lang.String} object.
|
||||
* @param defaultValue
|
||||
* a int.
|
||||
* @return a int.
|
||||
*/
|
||||
public final int getInt(final String name, final int defaultValue) {
|
||||
final String value = this.props.getProperty(name);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (final NumberFormatException ex) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getBoolean.
|
||||
* </p>
|
||||
*
|
||||
* @param name
|
||||
* a {@link java.lang.String} object.
|
||||
* @param defaultValue
|
||||
* a boolean.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean getBoolean(final String name, final boolean defaultValue) {
|
||||
final String value = this.props.getProperty(name);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getLong.
|
||||
* </p>
|
||||
*
|
||||
* @param name
|
||||
* a {@link java.lang.String} object.
|
||||
* @param defaultValue
|
||||
* a long.
|
||||
* @return a long.
|
||||
*/
|
||||
public final long getLong(final String name, final long defaultValue) {
|
||||
final String value = this.props.getProperty(name);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Long.parseLong(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* set.
|
||||
* </p>
|
||||
*
|
||||
* @param key
|
||||
* a {@link java.lang.String} object.
|
||||
* @param value
|
||||
* a {@link java.lang.Object} object.
|
||||
*/
|
||||
public final void set(final String key, final Object value) {
|
||||
this.props.setProperty(key, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* get.
|
||||
* </p>
|
||||
*
|
||||
* @param key
|
||||
* a {@link java.lang.String} object.
|
||||
* @param value
|
||||
* a {@link java.lang.Object} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public final String get(final String key, final Object value) {
|
||||
String string = null;
|
||||
if (value != null) {
|
||||
string = String.valueOf(value);
|
||||
}
|
||||
return this.props.getProperty(key, string);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* load.
|
||||
* </p>
|
||||
*
|
||||
* @param stream
|
||||
* a {@link java.io.FileInputStream} object.
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public final void load(final FileInputStream stream) throws IOException {
|
||||
this.props.load(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* store.
|
||||
* </p>
|
||||
*
|
||||
* @param stream
|
||||
* a {@link java.io.FileOutputStream} object.
|
||||
* @param comments
|
||||
* a {@link java.lang.String} object.
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public final void store(final FileOutputStream stream, final String comments) throws IOException {
|
||||
this.props.store(stream, comments);
|
||||
}
|
||||
}
|
||||
@@ -6,19 +6,17 @@
|
||||
* 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.properties;
|
||||
|
||||
import forge.util.FileUtil;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
@@ -26,6 +24,8 @@ import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.util.FileUtil;
|
||||
|
||||
/**
|
||||
* Holds default preference values in an enum.
|
||||
* Loads preferred values when instantiated.
|
||||
@@ -35,25 +35,25 @@ public abstract class PreferencesStore<T extends Enum<T>> {
|
||||
private final Map<T, String> preferenceValues;
|
||||
private final String filename;
|
||||
|
||||
public PreferencesStore(String filename0, Class<T> clasz) {
|
||||
public PreferencesStore(final String filename0, final Class<T> clasz) {
|
||||
preferenceValues = new EnumMap<T, String>(clasz);
|
||||
filename = filename0;
|
||||
|
||||
List<String> lines = FileUtil.readFile(filename);
|
||||
|
||||
final List<String> lines = FileUtil.readFile(filename);
|
||||
for (String line : lines) {
|
||||
line = line.trim();
|
||||
if (line.startsWith("#") || (line.isEmpty())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] split = line.split("=");
|
||||
T pref = valueOf(split[0]);
|
||||
|
||||
final String[] split = line.split("=");
|
||||
final T pref = valueOf(split[0]);
|
||||
|
||||
if (null == pref) {
|
||||
System.out.println("unknown preference: " + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (split.length == 2) {
|
||||
this.setPref(pref, split[1]);
|
||||
} else if (split.length == 1 && line.endsWith("=")) {
|
||||
@@ -61,25 +61,28 @@ public abstract class PreferencesStore<T extends Enum<T>> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected abstract T[] getEnumValues();
|
||||
protected abstract T valueOf(String name);
|
||||
protected abstract String getPrefDefault(T key);
|
||||
|
||||
|
||||
public final void save() {
|
||||
BufferedWriter writer = null;
|
||||
try {
|
||||
writer = new BufferedWriter(new FileWriter(filename));
|
||||
for (T key : getEnumValues()) {
|
||||
for (final T key : getEnumValues()) {
|
||||
writer.write(key + "=" + getPref(key));
|
||||
writer.newLine();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
if (null != writer) {
|
||||
try { writer.close(); }
|
||||
catch (IOException e) { System.out.println("error while closing " + filename); }
|
||||
try {
|
||||
writer.close();
|
||||
} catch (final IOException e) {
|
||||
System.out.println("error while closing " + filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,15 +91,15 @@ public abstract class PreferencesStore<T extends Enum<T>> {
|
||||
this.preferenceValues.clear();
|
||||
}
|
||||
|
||||
public final void setPref(T q0, String s0) {
|
||||
public final void setPref(final T q0, final String s0) {
|
||||
preferenceValues.put(q0, s0);
|
||||
}
|
||||
|
||||
public final void setPref(T q0, boolean val) {
|
||||
public final void setPref(final T q0, final boolean val) {
|
||||
setPref(q0, String.valueOf(val));
|
||||
}
|
||||
|
||||
public final String getPref(T fp0) {
|
||||
public final String getPref(final T fp0) {
|
||||
String val;
|
||||
|
||||
val = preferenceValues.get(fp0);
|
||||
@@ -105,11 +108,11 @@ public abstract class PreferencesStore<T extends Enum<T>> {
|
||||
return val;
|
||||
}
|
||||
|
||||
public final int getPrefInt(T fp0) {
|
||||
public final int getPrefInt(final T fp0) {
|
||||
return Integer.parseInt(getPref(fp0));
|
||||
}
|
||||
|
||||
public final boolean getPrefBoolean(T fp0) {
|
||||
public final boolean getPrefBoolean(final T fp0) {
|
||||
return Boolean.parseBoolean(getPref(fp0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.properties;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* SavePreferencesListener interface.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SavePreferencesListener {
|
||||
/**
|
||||
* <p>
|
||||
* savePreferences.
|
||||
* </p>
|
||||
*/
|
||||
void savePreferences();
|
||||
}
|
||||
@@ -19,9 +19,8 @@ import forge.util.storage.IStorage;
|
||||
|
||||
public class QuestDraftUtils {
|
||||
private static final List<DraftMatchup> matchups = new ArrayList<DraftMatchup>();
|
||||
|
||||
|
||||
public static boolean matchInProgress = false;
|
||||
public static boolean aiMatchInProgress = false;
|
||||
private static boolean waitForUserInput = false;
|
||||
|
||||
public static void completeDraft(final DeckGroup finishedDraft) {
|
||||
@@ -56,76 +55,76 @@ public class QuestDraftUtils {
|
||||
if (matchups.size() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
matchups.clear();
|
||||
|
||||
QuestEventDraft draft = FModel.getQuest().getAchievements().getCurrentDraft();
|
||||
String[] currentStandings = draft.getStandings();
|
||||
|
||||
|
||||
final QuestEventDraft draft = FModel.getQuest().getAchievements().getCurrentDraft();
|
||||
final String[] currentStandings = draft.getStandings();
|
||||
|
||||
int currentSet = -1;
|
||||
|
||||
|
||||
for (int i = currentStandings.length - 1; i >= 0; i--) {
|
||||
if (!currentStandings[i].equals(QuestEventDraft.UNDETERMINED)) {
|
||||
currentSet = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (currentSet) {
|
||||
|
||||
case 7:
|
||||
addMatchup(0, 1, draft);
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
addMatchup(8, 9, draft);
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
addMatchup(12, 13, draft);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
default:
|
||||
return;
|
||||
|
||||
|
||||
case 7:
|
||||
addMatchup(0, 1, draft);
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
addMatchup(8, 9, draft);
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
addMatchup(12, 13, draft);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
update(gui);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void addMatchup(final int player1, final int player2, final QuestEventDraft draft) {
|
||||
|
||||
DraftMatchup matchup = new DraftMatchup();
|
||||
DeckGroup decks = FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME);
|
||||
|
||||
|
||||
final DraftMatchup matchup = new DraftMatchup();
|
||||
final DeckGroup decks = FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME);
|
||||
|
||||
int humanIndex = -1;
|
||||
int aiIndex = -1;
|
||||
|
||||
|
||||
if (draft.getStandings()[player1].equals(QuestEventDraft.HUMAN)) {
|
||||
humanIndex = player1;
|
||||
aiIndex = player2;
|
||||
@@ -133,36 +132,33 @@ public class QuestDraftUtils {
|
||||
humanIndex = player2;
|
||||
aiIndex = player1;
|
||||
}
|
||||
|
||||
|
||||
if (humanIndex > -1) {
|
||||
matchup.setHumanPlayer(new RegisteredPlayer(decks.getHumanDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()));
|
||||
|
||||
int aiName = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
|
||||
|
||||
int aiDeckIndex = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
|
||||
final int aiName = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
|
||||
|
||||
final int aiDeckIndex = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GamePlayerUtil.createAiPlayer(draft.getAINames()[aiName], draft.getAIIcons()[aiName])));
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
int aiName1 = Integer.parseInt(draft.getStandings()[player1]) - 1;
|
||||
int aiName2 = Integer.parseInt(draft.getStandings()[player2]) - 1;
|
||||
|
||||
final int aiName1 = Integer.parseInt(draft.getStandings()[player1]) - 1;
|
||||
final int aiName2 = Integer.parseInt(draft.getStandings()[player2]) - 1;
|
||||
|
||||
int aiDeckIndex = Integer.parseInt(draft.getStandings()[player1]) - 1;
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GamePlayerUtil.createAiPlayer(draft.getAINames()[aiName1], draft.getAIIcons()[aiName1])));
|
||||
|
||||
aiDeckIndex = Integer.parseInt(draft.getStandings()[player2]) - 1;
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GamePlayerUtil.createAiPlayer(draft.getAINames()[aiName2], draft.getAIIcons()[aiName2])));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
matchups.add(matchup);
|
||||
}
|
||||
|
||||
public static void update(final IGuiGame gui) {
|
||||
if (matchups.isEmpty()) {
|
||||
if (!matchInProgress) {
|
||||
aiMatchInProgress = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -177,11 +173,9 @@ public class QuestDraftUtils {
|
||||
|
||||
if (nextMatch.hasHumanPlayer()) {
|
||||
waitForUserInput = true;
|
||||
aiMatchInProgress = false;
|
||||
} else {
|
||||
gui.disableOverlay();
|
||||
waitForUserInput = false;
|
||||
aiMatchInProgress = true;
|
||||
}
|
||||
|
||||
final GameRules rules = new GameRules(GameType.QuestDraft);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,10 +11,6 @@ import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
|
||||
protected String buildDescription(final String [] input) {
|
||||
@@ -22,12 +18,12 @@ public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
if (input == null || input.length < 1) {
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
|
||||
String buildDesc = null;
|
||||
|
||||
for (String s : input) {
|
||||
|
||||
for (final String s : input) {
|
||||
if (s.startsWith("desc:") || s.startsWith("Desc:")) {
|
||||
String[] tmp = s.split(":");
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
buildDesc = new String(tmp[1]);
|
||||
} else {
|
||||
@@ -41,7 +37,7 @@ public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (buildDesc != null) {
|
||||
return buildDesc;
|
||||
}
|
||||
@@ -52,19 +48,19 @@ public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
if (input == null || input.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Predicate<PaperCard> filters = FModel.getQuest().getFormat().getFilterPrinted();
|
||||
Predicate<CardRules> filterRules = null;
|
||||
Predicate<PaperCard> filterRarity = null;
|
||||
|
||||
for (String s : input) {
|
||||
|
||||
for (final String s : input) {
|
||||
if (s.startsWith("sets:") || s.startsWith("Sets:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] setcodes = tmp[1].split(",");
|
||||
final String [] setcodes = tmp[1].split(",");
|
||||
if (setcodes.length > 0) {
|
||||
List<String> sets = new ArrayList<String>();
|
||||
for (String code : setcodes) {
|
||||
final List<String> sets = new ArrayList<String>();
|
||||
for (final String code : setcodes) {
|
||||
if (FModel.getMagicDb().getEditions().contains(code)) {
|
||||
// System.out.println("Set " + code + " was found!");
|
||||
sets.add(code);
|
||||
@@ -79,9 +75,9 @@ public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
} else if (s.startsWith("rules:") || s.startsWith("Rules:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] ruleCodes = tmp[1].split(",");
|
||||
final String [] ruleCodes = tmp[1].split(",");
|
||||
if (ruleCodes.length > 0) {
|
||||
for (String rule : ruleCodes) {
|
||||
for (final String rule : ruleCodes) {
|
||||
final Predicate<CardRules> newRule = BoosterUtils.parseRulesLimitation(rule);
|
||||
if (newRule != null) {
|
||||
filterRules = (filterRules == null ? newRule : Predicates.and(filterRules, newRule));
|
||||
@@ -92,9 +88,9 @@ public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
} else if (s.startsWith("rarity:") || s.startsWith("Rarity:")) {
|
||||
final String[] tmp = s.split(":");
|
||||
if (tmp.length > 1) {
|
||||
String [] rarityCodes = tmp[1].split(",");
|
||||
final String [] rarityCodes = tmp[1].split(",");
|
||||
if (rarityCodes.length > 0) {
|
||||
for (String rarity : rarityCodes) {
|
||||
for (final String rarity : rarityCodes) {
|
||||
if (rarity.startsWith("C") || rarity.startsWith("c")) {
|
||||
filterRarity = (filterRarity == null ? IPaperCard.Predicates.Presets.IS_COMMON : Predicates.or(filterRarity, IPaperCard.Predicates.Presets.IS_COMMON));
|
||||
} else if (rarity.startsWith("U") || rarity.startsWith("u")) {
|
||||
@@ -109,7 +105,7 @@ public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (filterRules != null) {
|
||||
final Predicate<PaperCard> rulesPrinted = Predicates.compose(filterRules, PaperCard.FN_GET_RULES);
|
||||
filters = Predicates.and(filters, rulesPrinted);
|
||||
@@ -120,6 +116,4 @@ public abstract class QuestRewardCard implements IQuestRewardCard {
|
||||
return filters;
|
||||
}
|
||||
|
||||
public abstract List<PaperCard> getChoices();
|
||||
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package forge.quest;
|
||||
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.util.ItemPool;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.util.ItemPool;
|
||||
|
||||
/**
|
||||
* Allows the player to choose a duplicate copy of a currently owned card.
|
||||
*
|
||||
*/
|
||||
@@ -17,7 +17,7 @@ public class QuestRewardCardDuplicate implements IQuestRewardCard {
|
||||
private final String description;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* The constructor. No parameters.
|
||||
*/
|
||||
public QuestRewardCardDuplicate() {
|
||||
@@ -26,7 +26,7 @@ public class QuestRewardCardDuplicate implements IQuestRewardCard {
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
@Override
|
||||
@@ -36,7 +36,7 @@ public class QuestRewardCardDuplicate implements IQuestRewardCard {
|
||||
|
||||
/**
|
||||
* The item type.
|
||||
*
|
||||
*
|
||||
* @return item type
|
||||
*/
|
||||
@Override
|
||||
@@ -52,14 +52,15 @@ public class QuestRewardCardDuplicate implements IQuestRewardCard {
|
||||
/**
|
||||
* Produces a list of options to choose from, in this case,
|
||||
* the player's current cards.
|
||||
*
|
||||
*
|
||||
* @return a List<CardPrinted> or null if could not create a list.
|
||||
*/
|
||||
@Override
|
||||
public final List<PaperCard> getChoices() {
|
||||
final ItemPool<PaperCard> playerCards = FModel.getQuest().getAssets().getCardPool();
|
||||
if (!playerCards.isEmpty()) { // Maybe a redundant check since it's hard to win a duel without any cards...
|
||||
|
||||
List<PaperCard> cardChoices = new ArrayList<PaperCard>();
|
||||
final List<PaperCard> cardChoices = new ArrayList<PaperCard>();
|
||||
for (final Map.Entry<PaperCard, Integer> card : playerCards) {
|
||||
cardChoices.add(card.getKey());
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -34,7 +34,6 @@ import forge.card.CardRules;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.GameRules;
|
||||
import forge.game.GameType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiGame;
|
||||
@@ -58,28 +57,18 @@ import forge.util.gui.SOptionPane;
|
||||
* QuestUtil class.
|
||||
* </p>
|
||||
* MODEL - Static utility methods to help with minor tasks around Quest.
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public class QuestUtil {
|
||||
/**
|
||||
* <p>
|
||||
* getComputerStartingCards.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link java.util.List} object.
|
||||
*/
|
||||
public static List<Card> getComputerStartingCards() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getComputerStartingCards.
|
||||
* </p>
|
||||
* Returns new card instances of extra AI cards in play at start of event.
|
||||
*
|
||||
*
|
||||
* @param qe
|
||||
* a {@link forge.quest.QuestEvent} object.
|
||||
* @return a {@link java.util.List} object.
|
||||
@@ -107,10 +96,10 @@ public class QuestUtil {
|
||||
final List<IPaperCard> list = new ArrayList<>();
|
||||
|
||||
for (int iSlot = 0; iSlot < QuestController.MAX_PET_SLOTS; iSlot++) {
|
||||
String petName = qc.getSelectedPet(iSlot);
|
||||
QuestPetController pet = qc.getPetsStorage().getPet(petName);
|
||||
final String petName = qc.getSelectedPet(iSlot);
|
||||
final QuestPetController pet = qc.getPetsStorage().getPet(petName);
|
||||
if (pet != null) {
|
||||
IPaperCard c = pet.getPetCard(qc.getAssets());
|
||||
final IPaperCard c = pet.getPetCard(qc.getAssets());
|
||||
if (c != null) {
|
||||
list.add(c);
|
||||
}
|
||||
@@ -126,7 +115,7 @@ public class QuestUtil {
|
||||
* </p>
|
||||
* Returns new card instances of extra human cards, including current
|
||||
* plant/pet configuration, and cards in play at start of quest.
|
||||
*
|
||||
*
|
||||
* @param qc
|
||||
* a {@link forge.quest.QuestController} object.
|
||||
* @param qe
|
||||
@@ -146,7 +135,7 @@ public class QuestUtil {
|
||||
* createToken.
|
||||
* </p>
|
||||
* Creates a card instance for token defined by property string.
|
||||
*
|
||||
*
|
||||
* @param s
|
||||
* Properties string of token
|
||||
* (TOKEN;W;1;1;sheep;type;type;type...)
|
||||
@@ -155,13 +144,13 @@ public class QuestUtil {
|
||||
public static PaperToken createToken(final String s) {
|
||||
final String[] properties = s.split(";", 6);
|
||||
|
||||
List<String> script = new ArrayList<>();
|
||||
final List<String> script = new ArrayList<>();
|
||||
script.add("Name:" + properties[4]);
|
||||
script.add("Colors:" + properties[1]);
|
||||
script.add("PT:"+ properties[2] + "/" + properties[3]);
|
||||
script.add("Types:" + properties[5].replace(';', ' '));
|
||||
script.add("Oracle:"); // tokens don't have texts yet
|
||||
String fileName = PaperToken.makeTokenFileName(properties[1], properties[2], properties[3], properties[4]);
|
||||
final String fileName = PaperToken.makeTokenFileName(properties[1], properties[2], properties[3], properties[4]);
|
||||
return new PaperToken(CardRules.fromScript(script), CardEdition.UNKNOWN, fileName);
|
||||
}
|
||||
|
||||
@@ -170,7 +159,7 @@ public class QuestUtil {
|
||||
* readExtraCard.
|
||||
* </p>
|
||||
* Creates single card for a string read from unique event properties.
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @return the card
|
||||
@@ -185,15 +174,15 @@ public class QuestUtil {
|
||||
// Standard card creation
|
||||
return FModel.getMagicDb().getCommonCards().getCardFromEdition(name, SetPreference.Latest);
|
||||
}
|
||||
|
||||
|
||||
public static void travelWorld() {
|
||||
if (!checkActiveQuest("Travel between worlds.")) {
|
||||
return;
|
||||
}
|
||||
List<QuestWorld> worlds = new ArrayList<>();
|
||||
final List<QuestWorld> worlds = new ArrayList<>();
|
||||
final QuestController qCtrl = FModel.getQuest();
|
||||
|
||||
for (QuestWorld qw : FModel.getWorlds()) {
|
||||
for (final QuestWorld qw : FModel.getWorlds()) {
|
||||
if (qCtrl.getWorld() != qw) {
|
||||
worlds.add(qw);
|
||||
}
|
||||
@@ -246,15 +235,15 @@ public class QuestUtil {
|
||||
qCtrl.save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static QuestEvent event;
|
||||
private static QuestEventDraft draftEvent;
|
||||
private static QuestEventDraft draftEvent;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* nextChallengeInWins.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a int.
|
||||
*/
|
||||
public static int nextChallengeInWins() {
|
||||
@@ -312,7 +301,7 @@ public class QuestUtil {
|
||||
view.getCbxPet().addItem("Don't summon a pet");
|
||||
|
||||
for (final QuestPetController pet : petList) {
|
||||
String name = "Summon " + pet.getName();
|
||||
final String name = "Summon " + pet.getName();
|
||||
view.getCbxPet().addItem(name);
|
||||
if (pet.getName().equals(currentPetName)) {
|
||||
view.getCbxPet().setSelectedItem(name);
|
||||
@@ -323,7 +312,7 @@ public class QuestUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (qCtrl.getAssets().hasItem(QuestItemType.CHARM)) {
|
||||
view.getCbCharm().setVisible(true);
|
||||
}
|
||||
@@ -354,7 +343,7 @@ public class QuestUtil {
|
||||
* - Pets<br>
|
||||
* - Current deck info<br>
|
||||
* - "Challenge In" info<br>
|
||||
*
|
||||
*
|
||||
* @param view0 {@link forge.quest.IVQuestStats}
|
||||
*/
|
||||
public static void updateQuestView(final IVQuestStats view0) {
|
||||
@@ -462,16 +451,16 @@ public class QuestUtil {
|
||||
}
|
||||
|
||||
public static boolean checkActiveQuest(final String location) {
|
||||
QuestController qc = FModel.getQuest();
|
||||
final QuestController qc = FModel.getQuest();
|
||||
if (qc == null || qc.getAssets() == null) {
|
||||
String msg = "Please create a Quest before attempting to " + location;
|
||||
final String msg = "Please create a Quest before attempting to " + location;
|
||||
SOptionPane.showErrorDialog(msg, "No Quest");
|
||||
System.out.println(msg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** */
|
||||
public static void showSpellShop() {
|
||||
if (!checkActiveQuest("Visit the Spell Shop.")) {
|
||||
@@ -494,12 +483,12 @@ public class QuestUtil {
|
||||
return;
|
||||
}
|
||||
final QuestController qData = FModel.getQuest();
|
||||
ImmutablePair<CardEdition, Integer> toUnlock = QuestUtilUnlockSets.chooseSetToUnlock(qData, false, null);
|
||||
final ImmutablePair<CardEdition, Integer> toUnlock = QuestUtilUnlockSets.chooseSetToUnlock(qData, false, null);
|
||||
if (toUnlock == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CardEdition unlocked = toUnlock.left;
|
||||
final CardEdition unlocked = toUnlock.left;
|
||||
qData.getAssets().subtractCredits(toUnlock.right);
|
||||
SOptionPane.showMessageDialog("You have successfully unlocked " + unlocked.getName() + "!",
|
||||
unlocked.getName() + " unlocked!", null);
|
||||
@@ -531,7 +520,7 @@ public class QuestUtil {
|
||||
Boolean forceAnte = null;
|
||||
int lifeAI = 20;
|
||||
if (event instanceof QuestEventChallenge) {
|
||||
QuestEventChallenge qc = ((QuestEventChallenge) event);
|
||||
final QuestEventChallenge qc = ((QuestEventChallenge) event);
|
||||
lifeAI = qc.getAILife();
|
||||
lifeHuman = qc.getHumanLife();
|
||||
|
||||
@@ -545,7 +534,7 @@ public class QuestUtil {
|
||||
|
||||
final RegisteredPlayer humanStart = new RegisteredPlayer(getDeckForNewGame());
|
||||
final RegisteredPlayer aiStart = new RegisteredPlayer(event.getEventDeck());
|
||||
|
||||
|
||||
if (lifeHuman != null) {
|
||||
humanStart.setStartingLife(lifeHuman);
|
||||
} else {
|
||||
@@ -554,7 +543,7 @@ public class QuestUtil {
|
||||
|
||||
if (useBazaar) {
|
||||
humanStart.setCardsOnBattlefield(QuestUtil.getHumanStartingCards(qData, event));
|
||||
aiStart.setStartingLife(lifeAI);
|
||||
aiStart.setStartingLife(lifeAI);
|
||||
aiStart.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event));
|
||||
}
|
||||
|
||||
@@ -612,16 +601,16 @@ public class QuestUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
Deck deck = getDeckForNewGame();
|
||||
final Deck deck = getDeckForNewGame();
|
||||
if (deck == null) {
|
||||
String msg = "Please select a Quest Deck.";
|
||||
final String msg = "Please select a Quest Deck.";
|
||||
SOptionPane.showErrorDialog(msg, "No Deck");
|
||||
System.out.println(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
String errorMessage = GameType.Quest.getDeckFormat().getDeckConformanceProblem(deck);
|
||||
final String errorMessage = GameType.Quest.getDeckFormat().getDeckConformanceProblem(deck);
|
||||
if (null != errorMessage) {
|
||||
SOptionPane.showErrorDialog("Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck");
|
||||
return false;
|
||||
@@ -642,7 +631,7 @@ public class QuestUtil {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
final char[] c = in.toCharArray();
|
||||
|
||||
for (char aC : c) {
|
||||
for (final char aC : c) {
|
||||
if (Character.isLetterOrDigit(aC) || (aC == '-') || (aC == '_') || (aC == ' ')) {
|
||||
out.append(aC);
|
||||
}
|
||||
@@ -651,7 +640,7 @@ public class QuestUtil {
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static void buyQuestItem(IQuestBazaarItem item) {
|
||||
public static void buyQuestItem(final IQuestBazaarItem item) {
|
||||
final QuestAssets qA = FModel.getQuest().getAssets();
|
||||
final int cost = item.getBuyingPrice(qA);
|
||||
if (cost >= 0 && (qA.getCredits() - cost) >= 0) {
|
||||
|
||||
@@ -20,8 +20,10 @@ package forge.quest;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.card.*;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
@@ -38,6 +40,7 @@ import forge.quest.data.QuestPreferences.QPref;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.ItemPool;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -626,9 +629,8 @@ public final class QuestUtilCards {
|
||||
));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private SealedProduct.Template getBoosterTemplate() {
|
||||
return new SealedProduct.Template(Lists.newArrayList(
|
||||
return new SealedProduct.Template(ImmutableList.of(
|
||||
Pair.of(BoosterSlots.COMMON, this.qpref.getPrefInt(QPref.BOOSTER_COMMONS)),
|
||||
Pair.of(BoosterSlots.UNCOMMON, this.qpref.getPrefInt(QPref.BOOSTER_UNCOMMONS)),
|
||||
Pair.of(BoosterSlots.RARE_MYTHIC, this.qpref.getPrefInt(QPref.BOOSTER_RARES))
|
||||
@@ -650,7 +652,6 @@ public final class QuestUtilCards {
|
||||
final int winPacks = this.qc.getAchievements().getWin() / winsForPack;
|
||||
final int totalPacks = Math.min(Math.max(levelPacks + winPacks, minPacks), maxPacks);
|
||||
|
||||
|
||||
SealedProduct.Template tpl = getShopBoosterTemplate();
|
||||
UnOpenedProduct unopened = qc.getFormat() == null ? new UnOpenedProduct(tpl) : new UnOpenedProduct(tpl, qc.getFormat().getFilterPrinted());
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package forge.quest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.card.CardEdition;
|
||||
@@ -15,7 +22,11 @@ import forge.game.player.PlayerStatistics;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IWinLoseView;
|
||||
import forge.item.*;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.item.TournamentPack;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
@@ -26,13 +37,6 @@ import forge.quest.data.QuestPreferences.QPref;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class QuestWinLoseController {
|
||||
private final GameView lastGame;
|
||||
private final IWinLoseView<? extends IButton> view;
|
||||
@@ -89,7 +93,7 @@ public class QuestWinLoseController {
|
||||
public void run() {
|
||||
if (isAnte) {
|
||||
// Won/lost cards should already be calculated (even in a draw)
|
||||
GameOutcome.AnteResult anteResult = lastGame.getAnteResult(questPlayer);
|
||||
final GameOutcome.AnteResult anteResult = lastGame.getAnteResult(questPlayer);
|
||||
if (anteResult != null) {
|
||||
if (anteResult.wonCards != null) {
|
||||
qc.getCards().addAllCards(anteResult.wonCards);
|
||||
@@ -104,7 +108,7 @@ public class QuestWinLoseController {
|
||||
if (matchIsNotOver) { return; } //skip remaining logic if match isn't over yet
|
||||
|
||||
// TODO: We don't have a enum for difficulty?
|
||||
int difficulty = qData.getAchievements().getDifficulty();
|
||||
final int difficulty = qData.getAchievements().getDifficulty();
|
||||
|
||||
final int wins = qData.getAchievements().getWin();
|
||||
// Win case
|
||||
@@ -124,7 +128,7 @@ public class QuestWinLoseController {
|
||||
awardRandomRare("You've won a random rare for winning against a very hard deck.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
awardWinStreakBonus();
|
||||
|
||||
// Random rare given at 50% chance (65% with luck upgrade)
|
||||
@@ -147,7 +151,7 @@ public class QuestWinLoseController {
|
||||
// Grant booster on a win, or on a loss in easy mode
|
||||
if (wonMatch || difficulty == 0) {
|
||||
final int outcome = wonMatch ? wins : qData.getAchievements().getLost();
|
||||
int winsPerBooster = FModel.getQuestPreferences().getPrefInt(DifficultyPrefs.WINS_BOOSTER, qData.getAchievements().getDifficulty());
|
||||
final int winsPerBooster = FModel.getQuestPreferences().getPrefInt(DifficultyPrefs.WINS_BOOSTER, qData.getAchievements().getDifficulty());
|
||||
if (winsPerBooster > 0 && (outcome + 1) % winsPerBooster == 0) {
|
||||
awardBooster();
|
||||
}
|
||||
@@ -156,7 +160,7 @@ public class QuestWinLoseController {
|
||||
});
|
||||
}
|
||||
|
||||
private void anteReport(final List<PaperCard> cardsWon, List<PaperCard> cardsLost) {
|
||||
private void anteReport(final List<PaperCard> cardsWon, final List<PaperCard> cardsLost) {
|
||||
// Generate Swing components and attach.
|
||||
if (cardsWon != null && !cardsWon.isEmpty()) {
|
||||
view.showCards("Spoils! Cards won from ante", cardsWon);
|
||||
@@ -196,14 +200,13 @@ public class QuestWinLoseController {
|
||||
qData.save();
|
||||
FModel.getQuestPreferences().save();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* awardEventCredits.
|
||||
* </p>
|
||||
* Generates and displays standard rewards for gameplay and skill level.
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void awardEventCredits() {
|
||||
// TODO use q.qdPrefs to write bonus credits in prefs file
|
||||
@@ -220,17 +223,17 @@ public class QuestWinLoseController {
|
||||
final double multiplier = qEvent.getDifficulty().getMultiplier();
|
||||
|
||||
credBase = (int) (base * multiplier);
|
||||
|
||||
|
||||
sb.append(StringUtils.capitalize(qEvent.getDifficulty().getTitle()));
|
||||
sb.append(" opponent: ").append(credBase).append(" credits.\n");
|
||||
|
||||
final int creditsForPreviousWins = (int) ((Double.parseDouble(FModel.getQuestPreferences()
|
||||
.getPref(QPref.REWARDS_WINS_MULTIPLIER)) * qData.getAchievements().getWin()));
|
||||
credBase += creditsForPreviousWins;
|
||||
|
||||
|
||||
sb.append("Bonus for previous wins: ").append(creditsForPreviousWins).append(
|
||||
creditsForPreviousWins != 1 ? " credits.\n" : " credit.\n");
|
||||
|
||||
creditsForPreviousWins != 1 ? " credits.\n" : " credit.\n");
|
||||
|
||||
// Gameplay bonuses (for each game win)
|
||||
boolean hasNeverLost = true;
|
||||
int lifeDifferenceCredits = 0;
|
||||
@@ -245,7 +248,7 @@ public class QuestWinLoseController {
|
||||
|
||||
// final PlayerStatistics aiRating = game.getStatistics(computer.getName());
|
||||
PlayerStatistics humanRating = null;
|
||||
for (Entry<LobbyPlayer, PlayerStatistics> kvRating : game) {
|
||||
for (final Entry<LobbyPlayer, PlayerStatistics> kvRating : game) {
|
||||
if (kvRating.getKey().equals(localHuman)) {
|
||||
humanRating = kvRating.getValue();
|
||||
continue;
|
||||
@@ -290,11 +293,11 @@ public class QuestWinLoseController {
|
||||
credGameplay += mulliganReward;
|
||||
sb.append(String.format("Mulliganed to zero and still won! Bonus: %d credits.\n", mulliganReward));
|
||||
}
|
||||
|
||||
|
||||
// Early turn bonus
|
||||
final int winTurn = game.getLastTurnNumber();
|
||||
final int turnCredits = getCreditsRewardForWinByTurn(winTurn);
|
||||
|
||||
|
||||
if (winTurn == 0) {
|
||||
sb.append("Won on turn zero!");
|
||||
}
|
||||
@@ -310,18 +313,18 @@ public class QuestWinLoseController {
|
||||
else if (winTurn <= 15) {
|
||||
sb.append("Won by turn 15!");
|
||||
}
|
||||
|
||||
|
||||
if (turnCredits > 0) {
|
||||
credGameplay += turnCredits;
|
||||
sb.append(String.format(" Bonus: %d credits.\n", turnCredits));
|
||||
}
|
||||
|
||||
|
||||
if (game.getLifeDelta() >= 50) {
|
||||
lifeDifferenceCredits += Math.max(Math.min((game.getLifeDelta() - 46) / 4, 750), 0);
|
||||
}
|
||||
|
||||
|
||||
} // End for(game)
|
||||
|
||||
|
||||
if (lifeDifferenceCredits > 0) {
|
||||
sb.append(String.format("Life total difference: %d credits.\n", lifeDifferenceCredits));
|
||||
}
|
||||
@@ -384,7 +387,7 @@ public class QuestWinLoseController {
|
||||
* awardRandomRare.
|
||||
* </p>
|
||||
* Generates and displays a random rare win case.
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void awardRandomRare(final String message) {
|
||||
final PaperCard c = qData.getCards().addRandomRare();
|
||||
@@ -393,69 +396,69 @@ public class QuestWinLoseController {
|
||||
|
||||
view.showCards(message, cardsWon);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* awardWinStreakBonus.
|
||||
* </p>
|
||||
* Generates and displays a reward for maintaining a win streak.
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void awardWinStreakBonus() {
|
||||
int currentStreak = (qData.getAchievements().getWinStreakCurrent() + 1) % 50;
|
||||
final int currentStreak = (qData.getAchievements().getWinStreakCurrent() + 1) % 50;
|
||||
|
||||
final List<PaperCard> cardsWon = new ArrayList<>();
|
||||
List<PaperCard> cardsToAdd;
|
||||
String typeWon = "";
|
||||
boolean addDraftToken = false;
|
||||
|
||||
|
||||
switch (currentStreak) {
|
||||
case 3:
|
||||
cardsWon.addAll(qData.getCards().addRandomCommon(1));
|
||||
typeWon = "common";
|
||||
break;
|
||||
case 5:
|
||||
cardsWon.addAll(qData.getCards().addRandomUncommon(1));
|
||||
typeWon = "uncommon";
|
||||
break;
|
||||
case 7:
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(1));
|
||||
case 3:
|
||||
cardsWon.addAll(qData.getCards().addRandomCommon(1));
|
||||
typeWon = "common";
|
||||
break;
|
||||
case 5:
|
||||
cardsWon.addAll(qData.getCards().addRandomUncommon(1));
|
||||
typeWon = "uncommon";
|
||||
break;
|
||||
case 7:
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(1));
|
||||
typeWon = "rare";
|
||||
break;
|
||||
case 10:
|
||||
cardsToAdd = qData.getCards().addRandomMythicRare(1);
|
||||
if (cardsToAdd != null) {
|
||||
cardsWon.addAll(cardsToAdd);
|
||||
typeWon = "mythic rare";
|
||||
} else {
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(3));
|
||||
typeWon = "rare";
|
||||
break;
|
||||
case 10:
|
||||
cardsToAdd = qData.getCards().addRandomMythicRare(1);
|
||||
if (cardsToAdd != null) {
|
||||
cardsWon.addAll(cardsToAdd);
|
||||
typeWon = "mythic rare";
|
||||
} else {
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(3));
|
||||
typeWon = "rare";
|
||||
}
|
||||
break;
|
||||
case 25:
|
||||
cardsToAdd = qData.getCards().addRandomMythicRare(5);
|
||||
if (cardsToAdd != null) {
|
||||
cardsWon.addAll(cardsToAdd);
|
||||
typeWon = "mythic rare";
|
||||
} else {
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(15));
|
||||
typeWon = "rare";
|
||||
}
|
||||
addDraftToken = true;
|
||||
break;
|
||||
case 0: //The 50th win in the streak is 0, since (50 % 50 == 0)
|
||||
cardsToAdd = qData.getCards().addRandomMythicRare(10);
|
||||
if (cardsToAdd != null) {
|
||||
cardsWon.addAll(cardsToAdd);
|
||||
typeWon = "mythic rare";
|
||||
} else {
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(30));
|
||||
typeWon = "rare";
|
||||
}
|
||||
addDraftToken = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 25:
|
||||
cardsToAdd = qData.getCards().addRandomMythicRare(5);
|
||||
if (cardsToAdd != null) {
|
||||
cardsWon.addAll(cardsToAdd);
|
||||
typeWon = "mythic rare";
|
||||
} else {
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(15));
|
||||
typeWon = "rare";
|
||||
}
|
||||
addDraftToken = true;
|
||||
break;
|
||||
case 0: //The 50th win in the streak is 0, since (50 % 50 == 0)
|
||||
cardsToAdd = qData.getCards().addRandomMythicRare(10);
|
||||
if (cardsToAdd != null) {
|
||||
cardsWon.addAll(cardsToAdd);
|
||||
typeWon = "mythic rare";
|
||||
} else {
|
||||
cardsWon.addAll(qData.getCards().addRandomRareNotMythic(30));
|
||||
typeWon = "rare";
|
||||
}
|
||||
addDraftToken = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (addDraftToken) {
|
||||
@@ -473,7 +476,7 @@ public class QuestWinLoseController {
|
||||
* awardJackpot.
|
||||
* </p>
|
||||
* Generates and displays jackpot win case.
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void awardJackpot() {
|
||||
final List<PaperCard> cardsWon = qData.getCards().addRandomRare(10);
|
||||
@@ -485,7 +488,7 @@ public class QuestWinLoseController {
|
||||
* awardBooster.
|
||||
* </p>
|
||||
* Generates and displays booster pack win case.
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void awardBooster() {
|
||||
List<PaperCard> cardsWon = null;
|
||||
@@ -493,10 +496,10 @@ public class QuestWinLoseController {
|
||||
String title;
|
||||
if (qData.getFormat() == null) {
|
||||
final List<GameFormat> formats = new ArrayList<GameFormat>();
|
||||
String preferredFormat = FModel.getQuestPreferences().getPref(QPref.BOOSTER_FORMAT);
|
||||
final String preferredFormat = FModel.getQuestPreferences().getPref(QPref.BOOSTER_FORMAT);
|
||||
|
||||
GameFormat pref = null;
|
||||
for (GameFormat f : FModel.getFormats().getOrderedList()) {
|
||||
for (final GameFormat f : FModel.getFormats().getOrderedList()) {
|
||||
formats.add(f);
|
||||
if (f.toString().equals(preferredFormat)) {
|
||||
pref = f;
|
||||
@@ -516,7 +519,7 @@ public class QuestWinLoseController {
|
||||
else {
|
||||
final List<String> sets = new ArrayList<String>();
|
||||
|
||||
for (SealedProduct.Template bd : FModel.getMagicDb().getBoosters()) {
|
||||
for (final SealedProduct.Template bd : FModel.getMagicDb().getBoosters()) {
|
||||
if (bd != null && qData.getFormat().isSetLegal(bd.getEdition())) {
|
||||
sets.add(bd.getEdition());
|
||||
}
|
||||
@@ -532,11 +535,11 @@ public class QuestWinLoseController {
|
||||
maxChoices += qData.getAssets().getItemLevel(QuestItemType.MEMBERSHIP_TOKEN);
|
||||
}
|
||||
|
||||
List<CardEdition> options = new ArrayList<CardEdition>();
|
||||
|
||||
while(!sets.isEmpty() && maxChoices > 0) {
|
||||
int ix = MyRandom.getRandom().nextInt(sets.size());
|
||||
String set = sets.get(ix);
|
||||
final List<CardEdition> options = new ArrayList<CardEdition>();
|
||||
|
||||
while (!sets.isEmpty() && maxChoices > 0) {
|
||||
final int ix = MyRandom.getRandom().nextInt(sets.size());
|
||||
final String set = sets.get(ix);
|
||||
sets.remove(ix);
|
||||
options.add(FModel.getMagicDb().getEditions().get(set));
|
||||
maxChoices--;
|
||||
@@ -544,7 +547,7 @@ public class QuestWinLoseController {
|
||||
|
||||
final CardEdition chooseEd = SGuiChoose.one("Choose bonus booster set", options);
|
||||
|
||||
IUnOpenedProduct product = new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(chooseEd.getCode()));
|
||||
final IUnOpenedProduct product = new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(chooseEd.getCode()));
|
||||
cardsWon = product.get();
|
||||
qData.getCards().addAllCards(cardsWon);
|
||||
title = "Bonus " + chooseEd.getName() + " booster pack!";
|
||||
@@ -561,7 +564,7 @@ public class QuestWinLoseController {
|
||||
* awardChallengeWin.
|
||||
* </p>
|
||||
* Generates and displays win case for challenge event.
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void awardChallengeWin() {
|
||||
final long questRewardCredits = ((QuestEventChallenge) qEvent).getCreditsReward();
|
||||
@@ -585,7 +588,7 @@ public class QuestWinLoseController {
|
||||
* @param message String, reward text to be displayed, if any
|
||||
*/
|
||||
private void awardSpecialReward(String message) {
|
||||
final List<InventoryItem> itemsWon = ((QuestEvent) qEvent).getCardRewardList();
|
||||
final List<InventoryItem> itemsWon = qEvent.getCardRewardList();
|
||||
|
||||
if (itemsWon == null || itemsWon.isEmpty()) {
|
||||
return;
|
||||
@@ -593,12 +596,12 @@ public class QuestWinLoseController {
|
||||
|
||||
final List<PaperCard> cardsWon = new ArrayList<PaperCard>();
|
||||
|
||||
for (InventoryItem ii : itemsWon) {
|
||||
for (final InventoryItem ii : itemsWon) {
|
||||
if (ii instanceof PaperCard) {
|
||||
cardsWon.add((PaperCard) ii);
|
||||
}
|
||||
else if (ii instanceof TournamentPack || ii instanceof BoosterPack) {
|
||||
List<PaperCard> boosterCards = new ArrayList<PaperCard>();
|
||||
final List<PaperCard> boosterCards = new ArrayList<PaperCard>();
|
||||
SealedProduct booster = null;
|
||||
if (ii instanceof BoosterPack) {
|
||||
booster = (BoosterPack) ((BoosterPack) ii).clone();
|
||||
@@ -640,7 +643,7 @@ public class QuestWinLoseController {
|
||||
* getLuckyCoinResult.
|
||||
* </p>
|
||||
* A chance check, for rewards like random rares.
|
||||
*
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean getLuckyCoinResult() {
|
||||
@@ -654,12 +657,12 @@ public class QuestWinLoseController {
|
||||
* getCreditsRewardForAltWin.
|
||||
* </p>
|
||||
* Retrieves credits for win under special conditions.
|
||||
*
|
||||
*
|
||||
* @param whyAiLost GameLossReason
|
||||
* @return int
|
||||
*/
|
||||
private int getCreditsRewardForAltWin(final GameLossReason whyAiLost) {
|
||||
QuestPreferences qp = FModel.getQuestPreferences();
|
||||
private static int getCreditsRewardForAltWin(final GameLossReason whyAiLost) {
|
||||
final QuestPreferences qp = FModel.getQuestPreferences();
|
||||
if (null == whyAiLost) {
|
||||
// Felidar, Helix Pinnacle, etc.
|
||||
return qp.getPrefInt(QPref.REWARDS_ALTERNATIVE);
|
||||
@@ -683,11 +686,11 @@ public class QuestWinLoseController {
|
||||
* getCreditsRewardForWinByTurn.
|
||||
* </p>
|
||||
* Retrieves credits for win on or under turn count.
|
||||
*
|
||||
* @param iTurn int - turn count
|
||||
*
|
||||
* @param iTurn int - turn count
|
||||
* @return int credits won
|
||||
*/
|
||||
private int getCreditsRewardForWinByTurn(final int iTurn) {
|
||||
private static int getCreditsRewardForWinByTurn(final int iTurn) {
|
||||
int credits;
|
||||
|
||||
if (iTurn <= 1) {
|
||||
|
||||
@@ -6,33 +6,34 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.quest.io;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import forge.card.MagicColor;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.card.MagicColor;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* ReadPriceList class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
@@ -41,7 +42,7 @@ public class ReadPriceList {
|
||||
/** Constant <code>comment="//"</code>. */
|
||||
private static final String COMMENT = "//";
|
||||
|
||||
private HashMap<String, Integer> priceMap;
|
||||
private Map<String, Integer> priceMap;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -66,17 +67,17 @@ public class ReadPriceList {
|
||||
* <p>
|
||||
* readFile.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param file
|
||||
* a {@link java.io.File} object.
|
||||
* @return a {@link java.util.HashMap} object.
|
||||
*/
|
||||
private HashMap<String, Integer> readFile(String file) {
|
||||
final HashMap<String, Integer> map = new HashMap<String, Integer>();
|
||||
private Map<String, Integer> readFile(final String file) {
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
final Random r = MyRandom.getRandom();
|
||||
|
||||
List<String> lines = FileUtil.readFile(file);
|
||||
for (String line : lines) {
|
||||
final List<String> lines = FileUtil.readFile(file);
|
||||
for (final String line : lines) {
|
||||
if (line.trim().length() == 0) {
|
||||
break;
|
||||
}
|
||||
@@ -124,7 +125,7 @@ public class ReadPriceList {
|
||||
* <p>
|
||||
* getPriceList.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a {@link java.util.Map} object.
|
||||
*/
|
||||
public final Map<String, Integer> getPriceList() {
|
||||
|
||||
@@ -33,7 +33,7 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.maps.MapOfLists;
|
||||
|
||||
/**
|
||||
/**
|
||||
* This class is in charge of converting any forge.game.event.Event to a SoundEffectType.
|
||||
*
|
||||
*/
|
||||
@@ -44,49 +44,67 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
this.player = lobbyPlayer;
|
||||
}
|
||||
|
||||
public SoundEffectType visit(GameEventCardDamaged event) { return SoundEffectType.Damage; }
|
||||
public SoundEffectType visit(GameEventCardDestroyed event) { return SoundEffectType.Destroy; }
|
||||
public SoundEffectType visit(GameEventCardAttachment event) { return SoundEffectType.Equip; }
|
||||
public SoundEffectType visit(GameEventCardChangeZone event) {
|
||||
ZoneType from = event.from == null ? null : event.from.getZoneType();
|
||||
ZoneType to = event.to.getZoneType();
|
||||
if( from == ZoneType.Library && to == ZoneType.Hand)
|
||||
return SoundEffectType.Draw;
|
||||
if( from == ZoneType.Hand && (to == ZoneType.Graveyard || to == ZoneType.Library) )
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardDamaged event) { return SoundEffectType.Damage; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardDestroyed event) { return SoundEffectType.Destroy; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardAttachment event) { return SoundEffectType.Equip; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardChangeZone event) {
|
||||
final ZoneType from = event.from == null ? null : event.from.getZoneType();
|
||||
final ZoneType to = event.to.getZoneType();
|
||||
if( from == ZoneType.Library && to == ZoneType.Hand) {
|
||||
return SoundEffectType.Draw;
|
||||
}
|
||||
if( from == ZoneType.Hand && (to == ZoneType.Graveyard || to == ZoneType.Library) ) {
|
||||
return SoundEffectType.Discard;
|
||||
|
||||
return to == ZoneType.Exile ? SoundEffectType.Exile : null;
|
||||
}
|
||||
|
||||
return to == ZoneType.Exile ? SoundEffectType.Exile : null;
|
||||
}
|
||||
public SoundEffectType visit(GameEventCardRegenerated event) { return SoundEffectType.Regen; }
|
||||
public SoundEffectType visit(GameEventCardSacrificed event) { return SoundEffectType.Sacrifice; }
|
||||
public SoundEffectType visit(GameEventCardCounters event) { return event.newValue > event.oldValue ? SoundEffectType.AddCounter : event.newValue < event.oldValue ? SoundEffectType.RemoveCounter : null; }
|
||||
public SoundEffectType visit(GameEventTurnEnded event) { return SoundEffectType.EndOfTurn; }
|
||||
public SoundEffectType visit(GameEventFlipCoin event) { return SoundEffectType.FlipCoin; }
|
||||
public SoundEffectType visit(GameEventPlayerLivesChanged event) { return event.newLives < event.oldLives ? SoundEffectType.LifeLoss : SoundEffectType.LifeGain; }
|
||||
public SoundEffectType visit(GameEventPlayerPoisoned event) { return SoundEffectType.Poison; }
|
||||
public SoundEffectType visit(GameEventShuffle event) { return SoundEffectType.Shuffle; }
|
||||
public SoundEffectType visit(GameEventTokenCreated event) { return SoundEffectType.Token; }
|
||||
public SoundEffectType visit(GameEventBlockersDeclared event) {
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardRegenerated event) { return SoundEffectType.Regen; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardSacrificed event) { return SoundEffectType.Sacrifice; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardCounters event) { return event.newValue > event.oldValue ? SoundEffectType.AddCounter : event.newValue < event.oldValue ? SoundEffectType.RemoveCounter : null; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventTurnEnded event) { return SoundEffectType.EndOfTurn; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventFlipCoin event) { return SoundEffectType.FlipCoin; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventPlayerLivesChanged event) { return event.newLives < event.oldLives ? SoundEffectType.LifeLoss : SoundEffectType.LifeGain; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventPlayerPoisoned event) { return SoundEffectType.Poison; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventShuffle event) { return SoundEffectType.Shuffle; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventTokenCreated event) { return SoundEffectType.Token; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventBlockersDeclared event) {
|
||||
final boolean isLocalHuman = event.defendingPlayer.getLobbyPlayer() == player;
|
||||
if (isLocalHuman)
|
||||
if (isLocalHuman) {
|
||||
return null; // already played sounds in interactive mode
|
||||
|
||||
for(MapOfLists<Card, Card> ab : event.blockers.values()) {
|
||||
for(Collection<Card> bb : ab.values()) {
|
||||
}
|
||||
|
||||
for (final MapOfLists<Card, Card> ab : event.blockers.values()) {
|
||||
for(final Collection<Card> bb : ab.values()) {
|
||||
if ( !bb.isEmpty() ) {
|
||||
// hasAnyBlocker = true;
|
||||
return SoundEffectType.Block;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Plays the sound corresponding to the outcome of the duel.
|
||||
*/
|
||||
public SoundEffectType visit(GameEventGameOutcome event) {
|
||||
boolean humanWonTheDuel = event.result.getWinningLobbyPlayer() == player;
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventGameOutcome event) {
|
||||
final boolean humanWonTheDuel = event.result.getWinningLobbyPlayer() == player;
|
||||
return humanWonTheDuel ? SoundEffectType.WinDuel : SoundEffectType.LoseDuel;
|
||||
}
|
||||
|
||||
@@ -94,12 +112,13 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
* Plays the sound corresponding to the card type/color when the card
|
||||
* ability resolves on the stack.
|
||||
*/
|
||||
public SoundEffectType visit(GameEventSpellResolved evt) {
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventSpellResolved evt) {
|
||||
if (evt.spell == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Card source = evt.spell.getHostCard();
|
||||
final Card source = evt.spell.getHostCard();
|
||||
if (evt.spell.isSpell()) {
|
||||
// if there's a specific effect for this particular card, play it and
|
||||
// we're done.
|
||||
@@ -129,12 +148,13 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
/**
|
||||
* Plays the sound corresponding to the change of the card's tapped state
|
||||
* (when a card is tapped or untapped).
|
||||
*
|
||||
*
|
||||
* @param tapped_state if true, the "tap" sound is played; otherwise, the
|
||||
* "untap" sound is played
|
||||
* @return the sound effect type
|
||||
*/
|
||||
public SoundEffectType visit(GameEventCardTapped event) {
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventCardTapped event) {
|
||||
return event.tapped ? SoundEffectType.Tap : SoundEffectType.Untap;
|
||||
}
|
||||
|
||||
@@ -144,7 +164,8 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
* @param land the land card that was played
|
||||
* @return the sound effect type
|
||||
*/
|
||||
public SoundEffectType visit(GameEventLandPlayed event) {
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventLandPlayed event) {
|
||||
if (event.land == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -155,14 +176,24 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
return SoundEffectType.ScriptedEffect;
|
||||
}
|
||||
|
||||
for (SpellAbility sa : event.land.getManaAbilities()) {
|
||||
String manaColors = sa.getManaPartRecursive().getOrigProduced();
|
||||
for (final SpellAbility sa : event.land.getManaAbilities()) {
|
||||
final String manaColors = sa.getManaPartRecursive().getOrigProduced();
|
||||
|
||||
if (manaColors.contains("B")) return SoundEffectType.BlackLand;
|
||||
if (manaColors.contains("U")) return SoundEffectType.BlueLand;
|
||||
if (manaColors.contains("G")) return SoundEffectType.GreenLand;
|
||||
if (manaColors.contains("R")) return SoundEffectType.RedLand;
|
||||
if (manaColors.contains("W")) return SoundEffectType.WhiteLand;
|
||||
if (manaColors.contains("B")) {
|
||||
return SoundEffectType.BlackLand;
|
||||
}
|
||||
if (manaColors.contains("U")) {
|
||||
return SoundEffectType.BlueLand;
|
||||
}
|
||||
if (manaColors.contains("G")) {
|
||||
return SoundEffectType.GreenLand;
|
||||
}
|
||||
if (manaColors.contains("R")) {
|
||||
return SoundEffectType.RedLand;
|
||||
}
|
||||
if (manaColors.contains("W")) {
|
||||
return SoundEffectType.WhiteLand;
|
||||
}
|
||||
}
|
||||
|
||||
// play a generic land sound if no other sound corresponded to it.
|
||||
@@ -188,12 +219,12 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
/**
|
||||
* Returns the value of the SoundEffect SVar of the card that triggered
|
||||
* the event, otherwise returns an empty string.
|
||||
*
|
||||
*
|
||||
* @param evt the event which is the source of the sound effect
|
||||
* @return a string containing the SoundEffect SVar, or empty string if
|
||||
* SVar:SoundEffect does not exist.
|
||||
*/
|
||||
public String getScriptedSoundEffectName(GameEvent evt) {
|
||||
public String getScriptedSoundEffectName(final GameEvent evt) {
|
||||
Card c = null;
|
||||
|
||||
if (evt instanceof GameEventSpellResolved) {
|
||||
@@ -207,19 +238,19 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
|
||||
|
||||
@Override
|
||||
public SoundEffectType visit(UiEventBlockerAssigned event) {
|
||||
public SoundEffectType visit(final UiEventBlockerAssigned event) {
|
||||
return event.attackerBeingBlocked == null ? null : SoundEffectType.Block;
|
||||
}
|
||||
@Override
|
||||
public SoundEffectType visit(UiEventAttackerDeclared event) {
|
||||
public SoundEffectType visit(final UiEventAttackerDeclared event) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public SoundEffectType visit(UiEventNextGameDecision event) {
|
||||
public SoundEffectType visit(final UiEventNextGameDecision event) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public SoundEffectType visit(GameEventCardPhased event) {
|
||||
public SoundEffectType visit(final GameEventCardPhased event) {
|
||||
return SoundEffectType.Phasing;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,8 @@ import forge.player.GamePlayerUtil;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Manages playback of all sounds for the client.
|
||||
*
|
||||
*/
|
||||
public class SoundSystem {
|
||||
public static final SoundSystem instance = new SoundSystem();
|
||||
@@ -32,25 +31,25 @@ public class SoundSystem {
|
||||
private SoundSystem() {
|
||||
this.visualizer = new EventVisualizer(GamePlayerUtil.getGuiPlayer());
|
||||
}
|
||||
private boolean isUsingAltSystem() {
|
||||
private static boolean isUsingAltSystem() {
|
||||
return FModel.getPreferences().getPrefBoolean(FPref.UI_ALT_SOUND_SYSTEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a resource based on the sound effect type from the SoundEffectType enumeration.
|
||||
*
|
||||
*
|
||||
* @param type the sound effect type.
|
||||
* @return a clip associated with the loaded resource, or emptySound if the resource
|
||||
* was unavailable or failed to load.
|
||||
*/
|
||||
protected IAudioClip fetchResource(SoundEffectType type) {
|
||||
protected IAudioClip fetchResource(final SoundEffectType type) {
|
||||
if (!FModel.getPreferences().getPrefBoolean(FPref.UI_ENABLE_SOUNDS)) {
|
||||
return emptySound;
|
||||
}
|
||||
|
||||
IAudioClip clip = loadedClips.get(type);
|
||||
if (clip == null) { // cache miss
|
||||
String resource = type.getResourceFileName();
|
||||
final String resource = type.getResourceFileName();
|
||||
clip = GuiBase.getInterface().createAudioClip(resource);
|
||||
if (clip == null) {
|
||||
clip = emptySound;
|
||||
@@ -66,7 +65,7 @@ public class SoundSystem {
|
||||
* @return a clip associated with the loaded resource, or emptySound if the resource
|
||||
* was unavailable or failed to load.
|
||||
*/
|
||||
protected IAudioClip fetchResource(String fileName) {
|
||||
protected IAudioClip fetchResource(final String fileName) {
|
||||
if (!FModel.getPreferences().getPrefBoolean(FPref.UI_ENABLE_SOUNDS)) {
|
||||
return emptySound;
|
||||
}
|
||||
@@ -86,12 +85,12 @@ public class SoundSystem {
|
||||
* Play the sound associated with the resource specified by the file name
|
||||
* ("synchronized" with other sounds of the same kind means: only one can play at a time).
|
||||
*/
|
||||
public void play(String resourceFileName, boolean isSynchronized) {
|
||||
public void play(final String resourceFileName, final boolean isSynchronized) {
|
||||
if (isUsingAltSystem()) {
|
||||
GuiBase.getInterface().startAltSoundSystem(ForgeConstants.SOUND_DIR + resourceFileName, isSynchronized);
|
||||
}
|
||||
else {
|
||||
IAudioClip snd = fetchResource(resourceFileName);
|
||||
final IAudioClip snd = fetchResource(resourceFileName);
|
||||
if (!isSynchronized || snd.isDone()) {
|
||||
snd.play();
|
||||
}
|
||||
@@ -101,12 +100,12 @@ public class SoundSystem {
|
||||
/**
|
||||
* Play the sound associated with the Sounds enumeration element.
|
||||
*/
|
||||
public void play(SoundEffectType type, boolean isSynchronized) {
|
||||
public void play(final SoundEffectType type, final boolean isSynchronized) {
|
||||
if (isUsingAltSystem()) {
|
||||
GuiBase.getInterface().startAltSoundSystem(ForgeConstants.SOUND_DIR + type.getResourceFileName(), isSynchronized);
|
||||
}
|
||||
else {
|
||||
IAudioClip snd = fetchResource(type);
|
||||
final IAudioClip snd = fetchResource(type);
|
||||
if (!isSynchronized || snd.isDone()) {
|
||||
snd.play();
|
||||
}
|
||||
@@ -116,39 +115,39 @@ public class SoundSystem {
|
||||
/**
|
||||
* Play the sound in a looping manner until 'stop' is called.
|
||||
*/
|
||||
public void loop(String resourceFileName) {
|
||||
public void loop(final String resourceFileName) {
|
||||
fetchResource(resourceFileName).loop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the sound in a looping manner until 'stop' is called.
|
||||
*/
|
||||
public void loop(SoundEffectType type) {
|
||||
public void loop(final SoundEffectType type) {
|
||||
fetchResource(type).loop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the sound associated with the given resource file name.
|
||||
*/
|
||||
public void stop(String resourceFileName) {
|
||||
public void stop(final String resourceFileName) {
|
||||
fetchResource(resourceFileName).stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the sound associated with the Sounds enumeration element.
|
||||
*/
|
||||
public void stop(SoundEffectType type) {
|
||||
public void stop(final SoundEffectType type) {
|
||||
fetchResource(type).stop();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void receiveEvent(GameEvent evt) {
|
||||
SoundEffectType effect = evt.visit(visualizer);
|
||||
public void receiveEvent(final GameEvent evt) {
|
||||
final SoundEffectType effect = evt.visit(visualizer);
|
||||
if (null == effect) {
|
||||
return;
|
||||
}
|
||||
if (effect == SoundEffectType.ScriptedEffect) {
|
||||
String resourceName = visualizer.getScriptedSoundEffectName(evt);
|
||||
final String resourceName = visualizer.getScriptedSoundEffectName(evt);
|
||||
if (!resourceName.isEmpty()) {
|
||||
play(resourceName, false);
|
||||
}
|
||||
@@ -156,20 +155,20 @@ public class SoundSystem {
|
||||
play(effect, effect.isSynced());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void receiveEvent(UiEvent evt) {
|
||||
SoundEffectType effect = evt.visit(visualizer);
|
||||
public void receiveEvent(final UiEvent evt) {
|
||||
final SoundEffectType effect = evt.visit(visualizer);
|
||||
if (null != effect) {
|
||||
play(effect, effect.isSynced());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Background Music
|
||||
private IAudioMusic currentTrack;
|
||||
private MusicPlaylist currentPlaylist;
|
||||
|
||||
public void setBackgroundMusic(MusicPlaylist playlist) {
|
||||
public void setBackgroundMusic(final MusicPlaylist playlist) {
|
||||
currentPlaylist = playlist;
|
||||
changeBackgroundTrack();
|
||||
}
|
||||
@@ -185,25 +184,22 @@ public class SoundSystem {
|
||||
return;
|
||||
}
|
||||
|
||||
String filename = currentPlaylist.getRandomFilename();
|
||||
final String filename = currentPlaylist.getRandomFilename();
|
||||
if (filename == null) { return; }
|
||||
|
||||
try {
|
||||
currentTrack = GuiBase.getInterface().createAudioMusic(filename);
|
||||
currentTrack.play(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
Thread.sleep(SoundSystem.DELAY);
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
} catch (final InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
changeBackgroundTrack(); //change track when music completes on its own
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
System.err.println("Unable to load music file: " + filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,20 @@ package forge.util.gui;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GuiBase;
|
||||
|
||||
public class SGuiChoose {
|
||||
public static final String[] defaultConfirmOptions = { "Yes", "No" };
|
||||
|
||||
/**
|
||||
* Convenience for getChoices(message, 0, 1, choices).
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* is automatically inferred.
|
||||
* @param message
|
||||
@@ -48,26 +44,6 @@ public class SGuiChoose {
|
||||
return choice.isEmpty() ? null : choice.get(0);
|
||||
}
|
||||
|
||||
// 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 = SGuiChoose.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;
|
||||
@@ -81,42 +57,25 @@ public class SGuiChoose {
|
||||
return choice.get(0);
|
||||
}
|
||||
|
||||
public static <T> List<T> noneOrMany(final String message, final Collection<T> choices) {
|
||||
return SGuiChoose.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) {
|
||||
SGuiChoose.getChoices(message, -1, -1, items);
|
||||
}
|
||||
public static <T> void reveal(final String message, final Collection<T> items) {
|
||||
SGuiChoose.getChoices(message, -1, -1, items);
|
||||
}
|
||||
|
||||
// Get Integer in range
|
||||
public static Integer getInteger(final String message) {
|
||||
return getInteger(message, 0, Integer.MAX_VALUE, false);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min) {
|
||||
return getInteger(message, min, Integer.MAX_VALUE, false);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max) {
|
||||
public static Integer getInteger(final String message, final int min, final int max) {
|
||||
return getInteger(message, min, max, false);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max, boolean sortDesc) {
|
||||
|
||||
public static Integer getInteger(final String message, final int min, final int max, final boolean sortDesc) {
|
||||
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) {
|
||||
final int count = max - min + 1;
|
||||
if (count > 100) {
|
||||
return getInteger(message, min, max, min + 99);
|
||||
}
|
||||
|
||||
@@ -133,20 +92,21 @@ public class SGuiChoose {
|
||||
}
|
||||
return SGuiChoose.oneOrNone(message, choices);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max, int cutoff) {
|
||||
|
||||
public static Integer getInteger(final String message, final int min, final int max, final 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>();
|
||||
final List<Object> choices = new ArrayList<Object>();
|
||||
for (int i = min; i <= cutoff; i++) {
|
||||
choices.add(Integer.valueOf(i));
|
||||
}
|
||||
choices.add("...");
|
||||
|
||||
Object choice = SGuiChoose.oneOrNone(message, choices);
|
||||
final Object choice = SGuiChoose.oneOrNone(message, choices);
|
||||
if (choice instanceof Integer || choice == null) {
|
||||
return (Integer)choice;
|
||||
}
|
||||
@@ -167,11 +127,11 @@ public class SGuiChoose {
|
||||
prompt += ":";
|
||||
|
||||
while (true) {
|
||||
String str = SOptionPane.showInputDialog(prompt, message);
|
||||
final String str = SOptionPane.showInputDialog(prompt, message);
|
||||
if (str == null) { return null; } // that is 'cancel'
|
||||
|
||||
if (StringUtils.isNumeric(str)) {
|
||||
Integer val = Integer.valueOf(str);
|
||||
final Integer val = Integer.valueOf(str);
|
||||
if (val >= min && val <= max) {
|
||||
return val;
|
||||
}
|
||||
@@ -192,13 +152,13 @@ public class SGuiChoose {
|
||||
return GuiBase.getInterface().getChoices(message, min, max, choices, selected, display);
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices) {
|
||||
public static <T> List<T> many(final String title, final String topCaption, final int cnt, final List<T> sourceChoices) {
|
||||
return many(title, topCaption, cnt, cnt, sourceChoices);
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices) {
|
||||
int m2 = min >= 0 ? sourceChoices.size() - min : -1;
|
||||
int m1 = max >= 0 ? sourceChoices.size() - max : -1;
|
||||
public static <T> List<T> many(final String title, final String topCaption, final int min, final int max, final List<T> sourceChoices) {
|
||||
final int m2 = min >= 0 ? sourceChoices.size() - min : -1;
|
||||
final int m1 = max >= 0 ? sourceChoices.size() - max : -1;
|
||||
return order(title, topCaption, m1, m2, sourceChoices, null);
|
||||
}
|
||||
|
||||
@@ -206,81 +166,9 @@ public class SGuiChoose {
|
||||
return order(title, top, 0, 0, sourceChoices, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user to insert an object into a list of other objects. The
|
||||
* current implementation requires the user to cancel in order to get the
|
||||
* new item to be the first item in the resulting list.
|
||||
*
|
||||
* @param title the dialog title.
|
||||
* @param newItem the object to insert.
|
||||
* @param oldItems the list of objects.
|
||||
* @return A shallow copy of the list of objects, with newItem inserted.
|
||||
*/
|
||||
public static <T> List<T> insertInList(final String title, final T newItem, final List<T> oldItems) {
|
||||
final T placeAfter = oneOrNone(title, oldItems);
|
||||
final int indexAfter = (placeAfter == null ? 0 : oldItems.indexOf(placeAfter) + 1);
|
||||
final List<T> result = Lists.newArrayListWithCapacity(oldItems.size() + 1);
|
||||
result.addAll(oldItems);
|
||||
result.add(indexAfter, newItem);
|
||||
return result;
|
||||
}
|
||||
|
||||
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) {
|
||||
return GuiBase.getInterface().order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices);
|
||||
}
|
||||
|
||||
// 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 = SGuiChoose.sortedGetChoices(message, 0, 1, choices, comparer);
|
||||
return choice.isEmpty() ? null : 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> T sortedOneOrNone(final String message, final List<T> choices, Comparator<T> comparer) {
|
||||
if ((choices == null) || choices.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = SGuiChoose.sortedGetChoices(message, 0, 1, choices, comparer);
|
||||
return choice.isEmpty() ? null : 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> T sortedOne(final String message, final T[] choices, Comparator<T> comparer) {
|
||||
final List<T> choice = SGuiChoose.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> T sortedOne(final String message, final List<T> choices, Comparator<T> comparer) {
|
||||
if ((choices == null) || (choices.size() == 0)) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = SGuiChoose.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 SGuiChoose.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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,69 +9,69 @@ public class SOptionPane {
|
||||
public static final FSkinProp WARNING_ICON = FSkinProp.ICO_WARNING;
|
||||
public static final FSkinProp ERROR_ICON = FSkinProp.ICO_ERROR;
|
||||
|
||||
public static void showMessageDialog(String message) {
|
||||
public static void showMessageDialog(final String message) {
|
||||
showMessageDialog(message, "Forge", INFORMATION_ICON);
|
||||
}
|
||||
|
||||
public static void showMessageDialog(String message, String title) {
|
||||
public static void showMessageDialog(final String message, final String title) {
|
||||
showMessageDialog(message, title, INFORMATION_ICON);
|
||||
}
|
||||
|
||||
public static void showErrorDialog(String message) {
|
||||
public static void showErrorDialog(final String message) {
|
||||
showMessageDialog(message, "Forge", ERROR_ICON);
|
||||
}
|
||||
|
||||
public static void showErrorDialog(String message, String title) {
|
||||
public static void showErrorDialog(final String message, final String title) {
|
||||
showMessageDialog(message, title, ERROR_ICON);
|
||||
}
|
||||
|
||||
public static void showMessageDialog(String message, String title, FSkinProp icon) {
|
||||
public static void showMessageDialog(final String message, final String title, final FSkinProp icon) {
|
||||
showOptionDialog(message, title, icon, new String[] {"OK"}, 0);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message) {
|
||||
public static boolean showConfirmDialog(final String message) {
|
||||
return showConfirmDialog(message, "Forge");
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title) {
|
||||
public static boolean showConfirmDialog(final String message, final String title) {
|
||||
return showConfirmDialog(message, title, "Yes", "No", true);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title, boolean defaultYes) {
|
||||
public static boolean showConfirmDialog(final String message, final String title, final boolean defaultYes) {
|
||||
return showConfirmDialog(message, title, "Yes", "No", defaultYes);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText) {
|
||||
public static boolean showConfirmDialog(final String message, final String title, final String yesButtonText, final String noButtonText) {
|
||||
return showConfirmDialog(message, title, yesButtonText, noButtonText, true);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText, boolean defaultYes) {
|
||||
String[] options = {yesButtonText, noButtonText};
|
||||
int reply = SOptionPane.showOptionDialog(message, title, QUESTION_ICON, options, defaultYes ? 0 : 1);
|
||||
public static boolean showConfirmDialog(final String message, final String title, final String yesButtonText, final String noButtonText, final boolean defaultYes) {
|
||||
final String[] options = {yesButtonText, noButtonText};
|
||||
final int reply = SOptionPane.showOptionDialog(message, title, QUESTION_ICON, options, defaultYes ? 0 : 1);
|
||||
return (reply == 0);
|
||||
}
|
||||
|
||||
public static int showOptionDialog(String message, String title, FSkinProp icon, String[] options) {
|
||||
public static int showOptionDialog(final String message, final String title, final FSkinProp icon, final String[] options) {
|
||||
return showOptionDialog(message, title, icon, options, 0);
|
||||
}
|
||||
|
||||
public static int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption) {
|
||||
public static int showOptionDialog(final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) {
|
||||
return GuiBase.getInterface().showOptionDialog(message, title, icon, options, defaultOption);
|
||||
}
|
||||
|
||||
public static String showInputDialog(String message, String title) {
|
||||
public static String showInputDialog(final String message, final String title) {
|
||||
return showInputDialog(message, title, null, "", null);
|
||||
}
|
||||
|
||||
public static String showInputDialog(String message, String title, FSkinProp icon) {
|
||||
public static String showInputDialog(final String message, final String title, final FSkinProp icon) {
|
||||
return showInputDialog(message, title, icon, "", null);
|
||||
}
|
||||
|
||||
public static String showInputDialog(String message, String title, FSkinProp icon, String initialInput) {
|
||||
public static String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput) {
|
||||
return showInputDialog(message, title, icon, initialInput, null);
|
||||
}
|
||||
|
||||
public static String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions) {
|
||||
public static String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) {
|
||||
return GuiBase.getInterface().showInputDialog(message, title, icon, initialInput, inputOptions);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user