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:
elcnesh
2015-05-01 19:27:48 +00:00
parent 9f499117dc
commit bfdcaa6a1a
258 changed files with 7349 additions and 19480 deletions

View File

@@ -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('.');

View File

@@ -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() {
}
};
}

View File

@@ -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 + ")";
}

View File

@@ -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");
}

View File

@@ -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")) {

View File

@@ -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));
}
};
}

View File

@@ -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);
}};
}
/**

View File

@@ -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);
}
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}
};

View File

@@ -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");
}
}

View File

@@ -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();
}
});

View File

@@ -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
*/
}

View File

@@ -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];

View File

@@ -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());

View File

@@ -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);

View File

@@ -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);

View File

@@ -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() {
}
}

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -0,0 +1,8 @@
package forge.interfaces;
public interface IComponent {
boolean isEnabled();
void setEnabled(boolean b0);
boolean isVisible();
void setVisible(boolean b0);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -1,7 +0,0 @@
package forge.interfaces;
public interface IGuiTimer {
void setInterval(int interval0);
void start();
void stop();
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -0,0 +1,6 @@
package forge.interfaces;
public interface ITextComponent extends IComponent {
String getText();
void setText(String text0);
}

View File

@@ -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();
}

View File

@@ -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 &emsp; {@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 &emsp; {@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 &emsp; {@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);
}
}

View File

@@ -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);

View File

@@ -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]));

View File

@@ -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
*/

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -1,6 +0,0 @@
package forge.match;
public enum MatchButtonType {
OK,
CANCEL;
}

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -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
}
}

View File

@@ -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())

View File

@@ -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();

View File

@@ -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() {

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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()));
}
}
}
}

View File

@@ -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)) {

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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 &emsp; {@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();
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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());
}

View File

@@ -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) {

View File

@@ -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());

View File

@@ -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) {

View File

@@ -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() {

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}