mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Merge GuiRefactoring back into trunk.
Note that this changes ALL the display code to not pass game objects directly into the GUI, so bear that in mind when merging local changes (and in future commits).
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
package forge;
|
||||
|
||||
import forge.util.ThreadUtil;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.util.ThreadUtil;
|
||||
|
||||
public class FThreads {
|
||||
private FThreads() { } // no instances supposed
|
||||
@@ -15,8 +15,8 @@ public class FThreads {
|
||||
* @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) {
|
||||
public static void assertExecutedByEdt(final IGuiBase gui, final boolean mustBeEDT) {
|
||||
if (isGuiThread(gui) != mustBeEDT) {
|
||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
final String methodName = trace[2].getClassName() + "." + trace[2].getMethodName();
|
||||
String modalOperator = mustBeEDT ? " must be" : " may not be";
|
||||
@@ -24,16 +24,16 @@ public class FThreads {
|
||||
}
|
||||
}
|
||||
|
||||
public static void invokeInEdtLater(Runnable runnable) {
|
||||
GuiBase.getInterface().invokeInEdtLater(runnable);
|
||||
public static void invokeInEdtLater(final IGuiBase gui, final Runnable runnable) {
|
||||
gui.invokeInEdtLater(runnable);
|
||||
}
|
||||
|
||||
public static void invokeInEdtNowOrLater(Runnable proc) {
|
||||
if (isGuiThread()) {
|
||||
public static void invokeInEdtNowOrLater(final IGuiBase gui, final Runnable proc) {
|
||||
if (isGuiThread(gui)) {
|
||||
proc.run();
|
||||
}
|
||||
else {
|
||||
invokeInEdtLater(proc);
|
||||
invokeInEdtLater(gui, proc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ public class FThreads {
|
||||
* the Runnable to run
|
||||
* @see fgd.SwingUtilities#invokeLater(Runnable)
|
||||
*/
|
||||
public static void invokeInEdtAndWait(final Runnable proc) {
|
||||
GuiBase.getInterface().invokeInEdtAndWait(proc);
|
||||
public static void invokeInEdtAndWait(final IGuiBase gui, final Runnable proc) {
|
||||
gui.invokeInEdtAndWait(proc);
|
||||
}
|
||||
|
||||
private static int backgroundThreadCount;
|
||||
@@ -60,31 +60,31 @@ public class FThreads {
|
||||
backgroundThreadCount++;
|
||||
}
|
||||
|
||||
public static boolean isGuiThread() {
|
||||
return GuiBase.getInterface().isGuiThread();
|
||||
public static boolean isGuiThread(IGuiBase gui) {
|
||||
return gui.isGuiThread();
|
||||
}
|
||||
|
||||
public static void delayInEDT(int milliseconds, final Runnable inputUpdater) {
|
||||
public static void delayInEDT(final IGuiBase gui, final int milliseconds, final Runnable inputUpdater) {
|
||||
Runnable runInEdt = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FThreads.invokeInEdtNowOrLater(inputUpdater);
|
||||
FThreads.invokeInEdtNowOrLater(gui, inputUpdater);
|
||||
}
|
||||
};
|
||||
ThreadUtil.delay(milliseconds, runInEdt);
|
||||
}
|
||||
|
||||
public static String debugGetCurrThreadId() {
|
||||
return isGuiThread() ? "EDT" : Thread.currentThread().getName();
|
||||
public static String debugGetCurrThreadId(final IGuiBase gui) {
|
||||
return isGuiThread(gui) ? "EDT" : Thread.currentThread().getName();
|
||||
}
|
||||
|
||||
public static String prependThreadId(String message) {
|
||||
return debugGetCurrThreadId() + " > " + message;
|
||||
public static String prependThreadId(final IGuiBase gui, String message) {
|
||||
return debugGetCurrThreadId(gui) + " > " + message;
|
||||
}
|
||||
|
||||
public static void dumpStackTrace(PrintStream stream) {
|
||||
public static void dumpStackTrace(final IGuiBase gui, final PrintStream stream) {
|
||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
stream.printf("%s > %s called from %s%n", debugGetCurrThreadId(),
|
||||
stream.printf("%s > %s called from %s%n", debugGetCurrThreadId(gui),
|
||||
trace[2].getClassName() + "." + trace[2].getMethodName(), trace[3].toString());
|
||||
int i = 0;
|
||||
for (StackTraceElement se : trace) {
|
||||
@@ -93,7 +93,7 @@ public class FThreads {
|
||||
}
|
||||
}
|
||||
|
||||
public static String debugGetStackTraceItem(int depth, boolean shorter) {
|
||||
public static String debugGetStackTraceItem(final IGuiBase gui, final int depth, final boolean shorter) {
|
||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||
String lastItem = trace[depth].toString();
|
||||
if (shorter) {
|
||||
@@ -101,13 +101,13 @@ public class FThreads {
|
||||
lastPeriod = lastItem.lastIndexOf('.', lastPeriod-1);
|
||||
lastPeriod = lastItem.lastIndexOf('.', lastPeriod-1);
|
||||
lastItem = lastItem.substring(lastPeriod+1);
|
||||
return String.format("%s > from %s", debugGetCurrThreadId(), lastItem);
|
||||
return String.format("%s > from %s", debugGetCurrThreadId(gui), lastItem);
|
||||
}
|
||||
return String.format("%s > %s called from %s", debugGetCurrThreadId(),
|
||||
return String.format("%s > %s called from %s", debugGetCurrThreadId(gui),
|
||||
trace[2].getClassName() + "." + trace[2].getMethodName(), lastItem);
|
||||
}
|
||||
|
||||
public static String debugGetStackTraceItem(int depth) {
|
||||
return debugGetStackTraceItem(depth, false);
|
||||
public static String debugGetStackTraceItem(final IGuiBase gui, final int depth) {
|
||||
return debugGetStackTraceItem(gui, depth, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package forge;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
|
||||
public class GuiBase {
|
||||
private static IGuiBase guiInterface;
|
||||
|
||||
public static IGuiBase getInterface() {
|
||||
return guiInterface;
|
||||
}
|
||||
public static void setInterface(IGuiBase i0) {
|
||||
guiInterface = i0;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import org.w3c.dom.Element;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
public abstract class Achievement {
|
||||
@@ -67,7 +68,7 @@ public abstract class Achievement {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void update(Player player) {
|
||||
public void update(IGuiBase gui, Player player) {
|
||||
current = evaluate(player, player.getGame(), current);
|
||||
if (current > best) {
|
||||
int oldBest = best;
|
||||
@@ -98,7 +99,7 @@ public abstract class Achievement {
|
||||
}
|
||||
}
|
||||
if (type != null) {
|
||||
SOptionPane.showMessageDialog("You've earned a " + type + " trophy!\n\n" +
|
||||
SOptionPane.showMessageDialog(gui, "You've earned a " + type + " trophy!\n\n" +
|
||||
displayName + " - " + desc, "Achievement Earned", image);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.w3c.dom.NodeList;
|
||||
import forge.game.GameType;
|
||||
import forge.game.player.Player;
|
||||
import forge.interfaces.IComboBox;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileUtil;
|
||||
@@ -50,9 +51,9 @@ public abstract class AchievementCollection implements Iterable<Achievement> {
|
||||
achievements.put(name, achievement);
|
||||
}
|
||||
|
||||
public void updateAll(Player player) {
|
||||
public void updateAll(IGuiBase gui, Player player) {
|
||||
for (Achievement achievement : achievements.values()) {
|
||||
achievement.update(player);
|
||||
achievement.update(gui, player);
|
||||
}
|
||||
save();
|
||||
}
|
||||
|
||||
@@ -6,20 +6,18 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.InventoryItemFromSet;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.util.Lang;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
|
||||
public class CardDetailUtil {
|
||||
private CardDetailUtil() {
|
||||
@@ -51,19 +49,25 @@ public class CardDetailUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static DetailColors getBorderColor(final Card card, boolean canShow) {
|
||||
return getBorderColors(card.determineColor(), card.isLand(), canShow, false).get(0);
|
||||
public static DetailColors getBorderColor(final CardStateView card) {
|
||||
if (card == null) {
|
||||
return getBorderColors(null, false, false, false).iterator().next();
|
||||
}
|
||||
return getBorderColors(card.getColors(), card.isLand(), card.getCard().isUiDisplayable(), 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 Card card, boolean canShow, boolean supportMultiple) {
|
||||
return getBorderColors(card.determineColor(), card.isLand(), canShow, supportMultiple);
|
||||
public static List<DetailColors> getBorderColors(final CardStateView card) {
|
||||
if (card == null) {
|
||||
return getBorderColors(null, false, false, true);
|
||||
}
|
||||
return getBorderColors(card.getColors(), card.isLand(), card.getCard().isUiDisplayable(), true);
|
||||
}
|
||||
public static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
||||
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
||||
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
||||
|
||||
if (!canShow) {
|
||||
if (cardColors == null || !canShow) {
|
||||
borderColors.add(DetailColors.FACE_DOWN);
|
||||
}
|
||||
else if (cardColors.isColorless()) {
|
||||
@@ -157,13 +161,18 @@ public class CardDetailUtil {
|
||||
return item.getName();
|
||||
}
|
||||
|
||||
public static String formatCardType(final Card card) {
|
||||
final ArrayList<String> list = card.getType();
|
||||
public static String formatCardName(final CardStateView card) {
|
||||
final String name = card.getName();
|
||||
return StringUtils.isEmpty(name) ? "(no name)" : name.trim();
|
||||
}
|
||||
|
||||
public static String formatCardType(final CardStateView card) {
|
||||
final List<String> list = card.getType();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
final ArrayList<String> superTypes = new ArrayList<String>();
|
||||
final ArrayList<String> cardTypes = new ArrayList<String>();
|
||||
final ArrayList<String> subTypes = new ArrayList<String>();
|
||||
final List<String> superTypes = new ArrayList<String>();
|
||||
final List<String> cardTypes = new ArrayList<String>();
|
||||
final List<String> subTypes = new ArrayList<String>();
|
||||
final boolean allCreatureTypes = list.contains("AllCreatureTypes");
|
||||
|
||||
for (final String t : list) {
|
||||
@@ -197,13 +206,13 @@ public class CardDetailUtil {
|
||||
sb.append(type).append(" ");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
public static String formatPowerToughness(final Card card) {
|
||||
public static String formatPowerToughness(final CardStateView card) {
|
||||
StringBuilder ptText = new StringBuilder();
|
||||
if (card.isCreature()) {
|
||||
ptText.append(card.getNetAttack()).append(" / ").append(card.getNetDefense());
|
||||
ptText.append(card.getPower()).append(" / ").append(card.getToughness());
|
||||
}
|
||||
|
||||
if (card.isPlaneswalker()) {
|
||||
@@ -215,16 +224,18 @@ public class CardDetailUtil {
|
||||
ptText.append("Loyalty: ");
|
||||
}
|
||||
|
||||
ptText.append(card.getCurrentLoyalty());
|
||||
ptText.append(card.getLoyalty());
|
||||
}
|
||||
return ptText.toString();
|
||||
}
|
||||
|
||||
public static String formatCardId(final Card card) {
|
||||
return card.getUniqueNumber() > 0 ? "[" + card.getUniqueNumber() + "]" : "";
|
||||
|
||||
public static String formatCardId(final CardStateView card) {
|
||||
final int id = card.getCard().getId();
|
||||
return id > 0 ? "[" + id + "]" : "";
|
||||
}
|
||||
|
||||
public static String composeCardText(final Card card, final boolean canShow) {
|
||||
public static String composeCardText(final CardStateView state) {
|
||||
final CardView card = state.getCard();
|
||||
final StringBuilder area = new StringBuilder();
|
||||
|
||||
// Token
|
||||
@@ -232,27 +243,25 @@ public class CardDetailUtil {
|
||||
area.append("Token");
|
||||
}
|
||||
|
||||
if (canShow) {
|
||||
// card text
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
String text = card.getText();
|
||||
// LEVEL [0-9]+-[0-9]+
|
||||
// LEVEL [0-9]+\+
|
||||
|
||||
String regex = "LEVEL [0-9]+-[0-9]+ ";
|
||||
text = text.replaceAll(regex, "$0\r\n");
|
||||
|
||||
regex = "LEVEL [0-9]+\\+ ";
|
||||
text = text.replaceAll(regex, "\r\n$0\r\n");
|
||||
|
||||
// displays keywords that have dots in them a little better:
|
||||
regex = "\\., ";
|
||||
text = text.replaceAll(regex, ".\r\n");
|
||||
|
||||
area.append(text);
|
||||
// card text
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
String text = state.getText();
|
||||
// LEVEL [0-9]+-[0-9]+
|
||||
// LEVEL [0-9]+\+
|
||||
|
||||
String regex = "LEVEL [0-9]+-[0-9]+ ";
|
||||
text = text.replaceAll(regex, "$0\r\n");
|
||||
|
||||
regex = "LEVEL [0-9]+\\+ ";
|
||||
text = text.replaceAll(regex, "\r\n$0\r\n");
|
||||
|
||||
// displays keywords that have dots in them a little better:
|
||||
regex = "\\., ";
|
||||
text = text.replaceAll(regex, ".\r\n");
|
||||
|
||||
area.append(text);
|
||||
|
||||
if (card.isPhasedOut()) {
|
||||
if (area.length() != 0) {
|
||||
@@ -262,8 +271,8 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// text changes
|
||||
final Map<String, String> changedColorWords = card.getChangedTextColorWords(),
|
||||
changedTypes = card.getChangedTextTypeWords();
|
||||
final Map<String, String> changedColorWords = state.getChangedColorWords(),
|
||||
changedTypes = state.getChangedTypes();
|
||||
if (!(changedColorWords.isEmpty() && changedTypes.isEmpty())) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
@@ -292,35 +301,27 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// counter text
|
||||
final CounterType[] counters = CounterType.values();
|
||||
for (final CounterType counter : counters) {
|
||||
if (card.getCounters(counter) != 0) {
|
||||
for (final Entry<CounterType, Integer> c : card.getCounters().entrySet()) {
|
||||
if (c.getValue().intValue() != 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append(counter.getName() + " counters: ");
|
||||
area.append(card.getCounters(counter));
|
||||
area.append(c.getKey().getName() + " counters: ");
|
||||
area.append(c.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (card.isCreature()) {
|
||||
int damage = card.getDamage();
|
||||
if (state.isCreature()) {
|
||||
final int damage = card.getDamage();
|
||||
if (damage > 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Damage: " + damage);
|
||||
}
|
||||
int assigned = card.getTotalAssignedDamage();
|
||||
if (assigned > 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Assigned Damage: " + assigned);
|
||||
}
|
||||
}
|
||||
if (card.isPlaneswalker()) {
|
||||
int assigned = card.getTotalAssignedDamage();
|
||||
if (state.isCreature() || state.isPlaneswalker()) {
|
||||
final int assigned = card.getAssignedDamage();
|
||||
if (assigned > 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
@@ -330,43 +331,20 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// Regeneration Shields
|
||||
final int regenShields = card.getShield().size();
|
||||
final int regenShields = card.getRegenerationShields();
|
||||
if (regenShields > 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Regeneration Shield(s): ").append(regenShields);
|
||||
area.append("Regeneration Shields: ").append(regenShields);
|
||||
}
|
||||
|
||||
// Damage Prevention
|
||||
final int preventNextDamage = card.getPreventNextDamageTotalShields();
|
||||
final int preventNextDamage = card.getPreventNextDamage();
|
||||
if (preventNextDamage > 0) {
|
||||
area.append("\n");
|
||||
area.append("Prevent the next ").append(preventNextDamage).append(" damage that would be dealt to ");
|
||||
area.append(card.getName()).append(" this turn.");
|
||||
}
|
||||
|
||||
// top revealed
|
||||
if ((card.hasKeyword("Play with the top card of your library revealed.") || card
|
||||
.hasKeyword("Players play with the top card of their libraries revealed."))
|
||||
&& card.getController() != null
|
||||
&& (card.isInZone(ZoneType.Battlefield) || (card.isInZone(ZoneType.Command) && !card.isCommander()))
|
||||
&& !card.getController().getZone(ZoneType.Library).isEmpty()) {
|
||||
area.append("\r\nTop card of your library: ");
|
||||
area.append(card.getController().getCardsIn(ZoneType.Library, 1));
|
||||
if (card.hasKeyword("Players play with the top card of their libraries revealed.")) {
|
||||
for (final Player p : card.getController().getAllOtherPlayers()) {
|
||||
if (p.getZone(ZoneType.Library).isEmpty()) {
|
||||
area.append(p.getName());
|
||||
area.append("'s library is empty.");
|
||||
} else {
|
||||
area.append("\r\nTop card of ");
|
||||
area.append(p.getName());
|
||||
area.append("'s library: ");
|
||||
area.append(p.getCardsIn(ZoneType.Library, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
area.append(state.getName()).append(" this turn.");
|
||||
}
|
||||
|
||||
// chosen type
|
||||
@@ -380,12 +358,12 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// chosen color
|
||||
if (!card.getChosenColor().isEmpty()) {
|
||||
if (!card.getChosenColors().isEmpty()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("(chosen colors: ");
|
||||
area.append(card.getChosenColor());
|
||||
area.append(Lang.joinHomogenous(card.getChosenColors()));
|
||||
area.append(")");
|
||||
}
|
||||
|
||||
@@ -408,22 +386,22 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// equipping
|
||||
if (!card.getEquipping().isEmpty()) {
|
||||
if (card.getEquipping() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("=Equipping ");
|
||||
area.append(card.getEquipping().get(0));
|
||||
area.append(card.getEquipping());
|
||||
area.append("=");
|
||||
}
|
||||
|
||||
// equipped by
|
||||
if (!card.getEquippedBy().isEmpty()) {
|
||||
if (card.getEquippedBy().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("=Equipped by ");
|
||||
for (final Iterator<Card> it = card.getEquippedBy().iterator(); it.hasNext();) {
|
||||
for (final Iterator<CardView> it = card.getEquippedBy().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
@@ -433,35 +411,26 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// enchanting
|
||||
final GameEntity entity = card.getEnchanting();
|
||||
if (entity != null) {
|
||||
if (card.getEnchantingCard() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("*Enchanting ");
|
||||
|
||||
if (entity instanceof Card) {
|
||||
final Card c = (Card) entity;
|
||||
if (!GuiBase.getInterface().mayShowCard(c)) {
|
||||
area.append("Morph (");
|
||||
area.append(card.getUniqueNumber());
|
||||
area.append(")");
|
||||
} else {
|
||||
area.append(entity);
|
||||
}
|
||||
} else {
|
||||
area.append(entity);
|
||||
area.append("*Enchanting ").append(card.getEnchantingCard()).append("*");
|
||||
}
|
||||
if (card.getEnchantingPlayer() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("*");
|
||||
area.append("*Enchanting ").append(card.getEnchantingPlayer()).append("*");
|
||||
}
|
||||
|
||||
// enchanted by
|
||||
if (!card.getEnchantedBy().isEmpty()) {
|
||||
if (card.getEnchantedBy().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("*Enchanted by ");
|
||||
for (final Iterator<Card> it = card.getEnchantedBy().iterator(); it.hasNext();) {
|
||||
for (final Iterator<CardView> it = card.getEnchantedBy().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
@@ -471,12 +440,12 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// controlling
|
||||
if (card.getGainControlTargets().size() > 0) {
|
||||
if (card.getGainControlTargets().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("+Controlling: ");
|
||||
for (final Iterator<Card> it = card.getGainControlTargets().iterator(); it.hasNext();) {
|
||||
for (final Iterator<CardView> it = card.getGainControlTargets().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
@@ -491,17 +460,17 @@ public class CardDetailUtil {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("^Cloned via: ");
|
||||
area.append(card.getCloneOrigin().getName());
|
||||
area.append(card.getCloneOrigin().getOriginal().getName());
|
||||
area.append("^");
|
||||
}
|
||||
|
||||
// Imprint
|
||||
if (!card.getImprinted().isEmpty()) {
|
||||
if (card.getImprinted().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Imprinting: ");
|
||||
for (final Iterator<Card> it = card.getImprinted().iterator(); it.hasNext();) {
|
||||
for (final Iterator<CardView> it = card.getImprinted().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
@@ -510,12 +479,12 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// Haunt
|
||||
if (!card.getHauntedBy().isEmpty()) {
|
||||
if (card.getHauntedBy().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Haunted by: ");
|
||||
for (final Iterator<Card> it = card.getHauntedBy().iterator(); it.hasNext();) {
|
||||
for (final Iterator<CardView> it = card.getHauntedBy().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
@@ -530,16 +499,16 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
// must block
|
||||
if (card.getMustBlockCards() != null) {
|
||||
if (card.getMustBlock().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
String mustBlockThese = Lang.joinHomogenous(card.getMustBlockCards());
|
||||
final String mustBlockThese = Lang.joinHomogenous(card.getMustBlock());
|
||||
area.append("Must block " + mustBlockThese);
|
||||
}
|
||||
|
||||
//show current storm count for storm cards
|
||||
if (card.getKeyword().contains("Storm")) {
|
||||
/*show current storm count for storm cards
|
||||
if (state.hasStorm()) {
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
if (game != null) {
|
||||
if (area.length() != 0) {
|
||||
@@ -547,51 +516,8 @@ public class CardDetailUtil {
|
||||
}
|
||||
area.append("Current Storm Count: " + game.getStack().getCardsCastThisTurn().size());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return area.toString();
|
||||
}
|
||||
|
||||
public static boolean isCardFlippable(Card card) {
|
||||
return card.isDoubleFaced() || card.isFlipCard() || card.isFaceDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Card characteristic state machine.
|
||||
* <p>
|
||||
* Given a card and a state in terms of {@code CardCharacteristicName} this
|
||||
* will determine whether there is a valid alternate {@code CardCharacteristicName}
|
||||
* state for that card.
|
||||
*
|
||||
* @param card the {@code Card}
|
||||
* @param currentState not necessarily {@code card.getCurState()}
|
||||
* @return the alternate {@code CardCharacteristicName} state or default if not applicable
|
||||
*/
|
||||
public static CardCharacteristicName getAlternateState(final Card card, CardCharacteristicName currentState) {
|
||||
// Default. Most cards will only ever have an "Original" state represented by a single image.
|
||||
CardCharacteristicName alternateState = CardCharacteristicName.Original;
|
||||
|
||||
if (card.isDoubleFaced()) {
|
||||
if (currentState == CardCharacteristicName.Original) {
|
||||
alternateState = CardCharacteristicName.Transformed;
|
||||
}
|
||||
}
|
||||
else if (card.isFlipCard()) {
|
||||
if (currentState == CardCharacteristicName.Original) {
|
||||
alternateState = CardCharacteristicName.Flipped;
|
||||
}
|
||||
}
|
||||
else if (card.isFaceDown()) {
|
||||
if (currentState == CardCharacteristicName.Original) {
|
||||
alternateState = CardCharacteristicName.FaceDown;
|
||||
}
|
||||
else if (GuiBase.getInterface().mayShowCard(card)) {
|
||||
alternateState = CardCharacteristicName.Original;
|
||||
}
|
||||
else {
|
||||
alternateState = currentState;
|
||||
}
|
||||
}
|
||||
|
||||
return alternateState;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,20 +17,18 @@
|
||||
*/
|
||||
package forge.card;
|
||||
|
||||
import forge.CardStorageReader;
|
||||
import forge.card.CardRules;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
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;
|
||||
@@ -53,20 +51,21 @@ public final class CardScriptInfo {
|
||||
}
|
||||
|
||||
public boolean trySetText(String text0) {
|
||||
if (file == null) { return false; }
|
||||
if (file == null) { return false; }
|
||||
|
||||
try {
|
||||
PrintWriter p = new PrintWriter(file);
|
||||
p.print(text0);
|
||||
p.close();
|
||||
try {
|
||||
PrintWriter p = new PrintWriter(file);
|
||||
p.print(text0);
|
||||
p.close();
|
||||
|
||||
text = text0;
|
||||
return true;
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
SOptionPane.showErrorDialog("Problem writing file - " + file + " : " + ex);
|
||||
return false;
|
||||
}
|
||||
text = text0;
|
||||
return true;
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
System.err.println("Problem writing file - " + file);
|
||||
ex.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, CardScriptInfo> allScripts = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -1,33 +1,73 @@
|
||||
package forge.control;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.event.*;
|
||||
import forge.game.event.GameEvent;
|
||||
import forge.game.event.GameEventAnteCardsSelected;
|
||||
import forge.game.event.GameEventAttackersDeclared;
|
||||
import forge.game.event.GameEventBlockersDeclared;
|
||||
import forge.game.event.GameEventCardAttachment;
|
||||
import forge.game.event.GameEventCardChangeZone;
|
||||
import forge.game.event.GameEventCardCounters;
|
||||
import forge.game.event.GameEventCardDamaged;
|
||||
import forge.game.event.GameEventCardPhased;
|
||||
import forge.game.event.GameEventCardStatsChanged;
|
||||
import forge.game.event.GameEventCardTapped;
|
||||
import forge.game.event.GameEventCombatEnded;
|
||||
import forge.game.event.GameEventGameFinished;
|
||||
import forge.game.event.GameEventGameOutcome;
|
||||
import forge.game.event.GameEventManaPool;
|
||||
import forge.game.event.GameEventPlayerControl;
|
||||
import forge.game.event.GameEventPlayerLivesChanged;
|
||||
import forge.game.event.GameEventPlayerPoisoned;
|
||||
import forge.game.event.GameEventPlayerPriority;
|
||||
import forge.game.event.GameEventPlayerStatsChanged;
|
||||
import forge.game.event.GameEventShuffle;
|
||||
import forge.game.event.GameEventSpellAbilityCast;
|
||||
import forge.game.event.GameEventSpellRemovedFromStack;
|
||||
import forge.game.event.GameEventSpellResolved;
|
||||
import forge.game.event.GameEventTurnBegan;
|
||||
import forge.game.event.GameEventTurnPhase;
|
||||
import forge.game.event.GameEventZone;
|
||||
import forge.game.event.IGameEventVisitor;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.match.input.ButtonUtil;
|
||||
import forge.match.input.InputBase;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.Lang;
|
||||
import forge.util.ThreadUtil;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.maps.MapOfLists;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import forge.view.CardView;
|
||||
import forge.view.LocalGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
public FControlGameEventHandler() {
|
||||
|
||||
private final IGuiBase gui;
|
||||
private final LocalGameView gameView;
|
||||
public FControlGameEventHandler(final IGuiBase gui, final LocalGameView gameView) {
|
||||
this.gui = gui;
|
||||
this.gameView = gameView;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -40,11 +80,11 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
public Void visit(final GameEventTurnPhase ev) {
|
||||
if (phaseUpdPlanned.getAndSet(true)) return null;
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
phaseUpdPlanned.set(false);
|
||||
GuiBase.getInterface().updatePhase();
|
||||
gui.updatePhase();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
@@ -57,11 +97,11 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
@Override
|
||||
public Void visit(GameEventPlayerPriority event) {
|
||||
if (combatUpdPlanned.getAndSet(true)) { return null; }
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
combatUpdPlanned.set(false);
|
||||
GuiBase.getInterface().showCombat(GuiBase.getInterface().getGame().getCombat());
|
||||
gui.showCombat(gameView.getCombat());
|
||||
}
|
||||
});
|
||||
return null;
|
||||
@@ -72,17 +112,16 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
public Void visit(final GameEventTurnBegan event) {
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.UI_STACK_CREATURES) && event.turnOwner != null) {
|
||||
// anything except stack will get here
|
||||
updateZone(Pair.of(event.turnOwner, ZoneType.Battlefield));
|
||||
updateZone(Pair.of(gameView.getPlayerView(event.turnOwner), ZoneType.Battlefield));
|
||||
}
|
||||
|
||||
if (turnUpdPlanned.getAndSet(true)) { return null; }
|
||||
|
||||
final Game game = GuiBase.getInterface().getGame(); // to make sure control gets a correct game instance
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
turnUpdPlanned.set(false);
|
||||
GuiBase.getInterface().updateTurn(event, game);
|
||||
gui.updateTurn(gameView.getPlayerView(event.turnOwner));
|
||||
}
|
||||
});
|
||||
return null;
|
||||
@@ -90,27 +129,27 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventAnteCardsSelected ev) {
|
||||
List<Card> options = new ArrayList<Card>();
|
||||
for (final Entry<Player, Card> kv : ((GameEventAnteCardsSelected) ev).cards.entries()) {
|
||||
Card fakeCard = new Card(-1); //use fake card so real cards appear with proper formatting
|
||||
fakeCard.setName(" -- From " + Lang.getPossesive(kv.getKey().getName()) + " deck --");
|
||||
final List<CardView> options = Lists.newArrayList();
|
||||
for (final Entry<Player, Card> kv : ev.cards.entries()) {
|
||||
final CardView fakeCard = new CardView(true); //use fake card so real cards appear with proper formatting
|
||||
fakeCard.getOriginal().setName(" -- From " + Lang.getPossesive(kv.getKey().getName()) + " deck --");
|
||||
options.add(fakeCard);
|
||||
options.add(kv.getValue());
|
||||
options.add(gameView.getCardView(kv.getValue()));
|
||||
}
|
||||
SGuiChoose.reveal("These cards were chosen to ante", options);
|
||||
SGuiChoose.reveal(gui, "These cards were chosen to ante", options);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventPlayerControl ev) {
|
||||
if (GuiBase.getInterface().getGame().isGameOver()) {
|
||||
if (ev.player.getGame().isGameOver()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GuiBase.getInterface().updatePlayerControl();
|
||||
gui.updatePlayerControl();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
@@ -119,41 +158,26 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
private final Runnable unlockGameThreadOnGameOver = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GuiBase.getInterface().getInputQueue().onGameOver(true); // this will unlock any game threads waiting for inputs to complete
|
||||
gui.getInputQueue().onGameOver(true); // this will unlock any game threads waiting for inputs to complete
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventGameOutcome ev) {
|
||||
FThreads.invokeInEdtNowOrLater(unlockGameThreadOnGameOver);
|
||||
FThreads.invokeInEdtNowOrLater(gui, unlockGameThreadOnGameOver);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventGameFinished ev) {
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
InputBase.cancelAwaitNextInput(); //ensure "Waiting for opponent..." doesn't appear behind WinLo
|
||||
GuiBase.getInterface().showPromptMessage(""); //clear prompt behind WinLose overlay
|
||||
ButtonUtil.update("", "", false, false, false);
|
||||
GuiBase.getInterface().finishGame();
|
||||
|
||||
//update all achievements for GUI player after game finished
|
||||
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
if (game == null) {
|
||||
return;
|
||||
}
|
||||
for (Player p : game.getRegisteredPlayers()) {
|
||||
if (p.getController().getLobbyPlayer() == GuiBase.getInterface().getGuiPlayer()) {
|
||||
FModel.getAchievements(game.getRules().getGameType()).updateAll(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
InputBase.cancelAwaitNextInput(); //ensure "Waiting for opponent..." doesn't appear behind WinLo
|
||||
gui.showPromptMessage(""); //clear prompt behind WinLose overlay
|
||||
ButtonUtil.update(gui, "", "", false, false, false);
|
||||
gui.finishGame();
|
||||
gameView.updateAchievements();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
@@ -164,38 +188,38 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
@Override
|
||||
public void run() {
|
||||
stackUpdPlanned.set(false);
|
||||
GuiBase.getInterface().updateStack();
|
||||
gui.updateStack();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventSpellAbilityCast event) {
|
||||
if (!stackUpdPlanned.getAndSet(true)) {
|
||||
FThreads.invokeInEdtNowOrLater(updStack);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updStack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Void visit(GameEventSpellResolved event) {
|
||||
if (!stackUpdPlanned.getAndSet(true)) {
|
||||
FThreads.invokeInEdtNowOrLater(updStack);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updStack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Void visit(GameEventSpellRemovedFromStack event) {
|
||||
if (!stackUpdPlanned.getAndSet(true)) {
|
||||
FThreads.invokeInEdtNowOrLater(updStack);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updStack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private final List<Pair<Player, ZoneType>> zonesToUpdate = new Vector<Pair<Player, ZoneType>>();
|
||||
private final List<Pair<PlayerView, ZoneType>> zonesToUpdate = new Vector<Pair<PlayerView,ZoneType>>();
|
||||
private final Runnable updZones = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (zonesToUpdate) {
|
||||
GuiBase.getInterface().updateZones(zonesToUpdate);
|
||||
gui.updateZones(zonesToUpdate);
|
||||
zonesToUpdate.clear();
|
||||
}
|
||||
}
|
||||
@@ -205,16 +229,15 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
public Void visit(GameEventZone event) {
|
||||
if (event.player != null) {
|
||||
// anything except stack will get here
|
||||
updateZone(Pair.of(event.player, event.zoneType));
|
||||
updateZone(Pair.of(gameView.getPlayerView(event.player), event.zoneType));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardAttachment event) {
|
||||
// TODO Auto-generated method stub
|
||||
Game game = event.equipment.getGame();
|
||||
PlayerZone zEq = (PlayerZone)game.getZoneOf(event.equipment);
|
||||
final Game game = event.equipment.getGame();
|
||||
final PlayerZone zEq = (PlayerZone)game.getZoneOf(event.equipment);
|
||||
if (event.oldEntiy instanceof Card) {
|
||||
updateZone(game.getZoneOf((Card)event.oldEntiy));
|
||||
}
|
||||
@@ -224,11 +247,11 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
return updateZone(zEq);
|
||||
}
|
||||
|
||||
private Void updateZone(Zone z) {
|
||||
return updateZone(Pair.of(z.getPlayer(), z.getZoneType()));
|
||||
private Void updateZone(final Zone z) {
|
||||
return updateZone(Pair.of(gameView.getPlayerView(z.getPlayer()), z.getZoneType()));
|
||||
}
|
||||
|
||||
private Void updateZone(Pair<Player, ZoneType> kv) {
|
||||
private Void updateZone(final Pair<PlayerView, ZoneType> kv) {
|
||||
boolean needUpdate = false;
|
||||
synchronized (zonesToUpdate) {
|
||||
needUpdate = zonesToUpdate.isEmpty();
|
||||
@@ -237,47 +260,47 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
}
|
||||
if (needUpdate) {
|
||||
FThreads.invokeInEdtNowOrLater(updZones);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updZones);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private final Set<Card> cardsToUpdate = new HashSet<Card>();
|
||||
private final Set<CardView> cardsToUpdate = Sets.newHashSet();
|
||||
private final Runnable updCards = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (cardsToUpdate) {
|
||||
GuiBase.getInterface().updateCards(cardsToUpdate);
|
||||
gui.updateCards(cardsToUpdate);
|
||||
cardsToUpdate.clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardTapped event) {
|
||||
return updateSingleCard(event.card);
|
||||
public Void visit(final GameEventCardTapped event) {
|
||||
return updateSingleCard(gameView.getCardView(event.card));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardPhased event) {
|
||||
return updateSingleCard(event.card);
|
||||
public Void visit(final GameEventCardPhased event) {
|
||||
return updateSingleCard(gameView.getCardView(event.card));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardDamaged event) {
|
||||
return updateSingleCard(event.card);
|
||||
public Void visit(final GameEventCardDamaged event) {
|
||||
return updateSingleCard(gameView.getCardView(event.card));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardCounters event) {
|
||||
return updateSingleCard(event.card);
|
||||
public Void visit(final GameEventCardCounters event) {
|
||||
return updateSingleCard(gameView.getCardView(event.card));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventBlockersDeclared event) { // This is to draw icons on blockers declared by AI
|
||||
public Void visit(final GameEventBlockersDeclared event) { // This is to draw icons on blockers declared by AI
|
||||
for (MapOfLists<Card, Card> kv : event.blockers.values()) {
|
||||
for (Collection<Card> blockers : kv.values()) {
|
||||
updateManyCards(blockers);
|
||||
updateManyCards(gameView.getCardViews(blockers));
|
||||
}
|
||||
}
|
||||
return super.visit(event);
|
||||
@@ -286,13 +309,13 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
@Override
|
||||
public Void visit(GameEventAttackersDeclared event) {
|
||||
// Skip redraw for GUI player?
|
||||
if (event.player.getLobbyPlayer() == GuiBase.getInterface().getGuiPlayer()) {
|
||||
if (event.player.getLobbyPlayer() == gui.getGuiPlayer()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Update all attackers.
|
||||
// Although they might have been updated when they were apped, there could be someone with vigilance, not redrawn yet.
|
||||
updateManyCards(event.attackersMap.values());
|
||||
updateManyCards(gameView.getCardViews(event.attackersMap.values()));
|
||||
|
||||
return super.visit(event);
|
||||
}
|
||||
@@ -300,12 +323,12 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
@Override
|
||||
public Void visit(GameEventCombatEnded event) {
|
||||
// This should remove sword/shield icons from combatants by the time game moves to M2
|
||||
updateManyCards(event.attackers);
|
||||
updateManyCards(event.blockers);
|
||||
updateManyCards(gameView.getCardViews(event.attackers));
|
||||
updateManyCards(gameView.getCardViews(event.blockers));
|
||||
return null;
|
||||
}
|
||||
|
||||
private Void updateSingleCard(Card c) {
|
||||
private Void updateSingleCard(final CardView c) {
|
||||
boolean needUpdate = false;
|
||||
synchronized (cardsToUpdate) {
|
||||
needUpdate = cardsToUpdate.isEmpty();
|
||||
@@ -314,19 +337,30 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
}
|
||||
if (needUpdate) {
|
||||
FThreads.invokeInEdtNowOrLater(updCards);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updCards);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Void updateManyCards(Collection<Card> cc) {
|
||||
private Void updateManyCards(final Iterable<CardView> cc) {
|
||||
boolean needUpdate = false;
|
||||
synchronized (cardsToUpdate) {
|
||||
needUpdate = cardsToUpdate.isEmpty();
|
||||
cardsToUpdate.addAll(cc);
|
||||
Iterables.addAll(cardsToUpdate, cc);
|
||||
}
|
||||
if (needUpdate) {
|
||||
FThreads.invokeInEdtNowOrLater(updCards);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updCards);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCardChangeZone event) {
|
||||
if (event.from != null) {
|
||||
updateZone(event.from);
|
||||
}
|
||||
if (event.to != null) {
|
||||
updateZone(event.to);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -336,8 +370,23 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
*/
|
||||
@Override
|
||||
public Void visit(GameEventCardStatsChanged event) {
|
||||
GuiBase.getInterface().refreshCardDetails(event.cards);
|
||||
return updateManyCards(event.cards);
|
||||
final Iterable<CardView> cardViews = gameView.getCardViews(event.cards);
|
||||
gui.refreshCardDetails(cardViews);
|
||||
return updateManyCards(cardViews);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventPlayerStatsChanged event) {
|
||||
for (final Player p : event.players) {
|
||||
gui.refreshCardDetails(gameView.getCardViews(p.getAllCards()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventShuffle event) {
|
||||
updateZone(event.player.getZone(ZoneType.Library));
|
||||
return null;
|
||||
}
|
||||
|
||||
// Update manapool
|
||||
@@ -345,7 +394,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
private final Runnable updManaPool = new Runnable() {
|
||||
@Override public void run() {
|
||||
synchronized (manaPoolUpdate) {
|
||||
GuiBase.getInterface().updateManaPool(manaPoolUpdate);
|
||||
gui.updateManaPool(gameView.getPlayerViews(manaPoolUpdate));
|
||||
manaPoolUpdate.clear();
|
||||
}
|
||||
}
|
||||
@@ -361,7 +410,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
}
|
||||
if (invokeUpdate) {
|
||||
FThreads.invokeInEdtNowOrLater(updManaPool);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updManaPool);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -371,7 +420,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
private final Runnable updLives = new Runnable() {
|
||||
@Override public void run() {
|
||||
synchronized (livesUpdate) {
|
||||
GuiBase.getInterface().updateLives(livesUpdate);
|
||||
gui.updateLives(gameView.getPlayerViews(livesUpdate));
|
||||
livesUpdate.clear();
|
||||
}
|
||||
}
|
||||
@@ -386,7 +435,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
}
|
||||
if (invokeUpdate) {
|
||||
FThreads.invokeInEdtNowOrLater(updLives);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updLives);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -401,7 +450,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
}
|
||||
}
|
||||
if (invokeUpdate) {
|
||||
FThreads.invokeInEdtNowOrLater(updLives);
|
||||
FThreads.invokeInEdtNowOrLater(gui, updLives);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,49 @@
|
||||
package forge.control;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.game.event.*;
|
||||
import forge.match.input.InputPlaybackControl;
|
||||
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.game.Game;
|
||||
import forge.game.event.GameEvent;
|
||||
import forge.game.event.GameEventBlockersDeclared;
|
||||
import forge.game.event.GameEventGameFinished;
|
||||
import forge.game.event.GameEventGameStarted;
|
||||
import forge.game.event.GameEventLandPlayed;
|
||||
import forge.game.event.GameEventPlayerPriority;
|
||||
import forge.game.event.GameEventSpellAbilityCast;
|
||||
import forge.game.event.GameEventSpellResolved;
|
||||
import forge.game.event.GameEventTurnPhase;
|
||||
import forge.game.event.IGameEventVisitor;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.match.input.InputPlaybackControl;
|
||||
import forge.view.LocalGameView;
|
||||
|
||||
public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
private final InputPlaybackControl inputPlayback = new InputPlaybackControl(this);
|
||||
private InputPlaybackControl inputPlayback;
|
||||
private final AtomicBoolean paused = new AtomicBoolean(false);
|
||||
|
||||
private final CyclicBarrier gameThreadPauser = new CyclicBarrier(2);
|
||||
|
||||
public FControlGamePlayback() {
|
||||
private final IGuiBase gui;
|
||||
private final LocalGameView gameView;
|
||||
public FControlGamePlayback(final IGuiBase gui, final LocalGameView gameView) {
|
||||
this.gui = gui;
|
||||
this.gameView = gameView;
|
||||
}
|
||||
|
||||
private Game game;
|
||||
|
||||
public Game getGame() {
|
||||
return game;
|
||||
}
|
||||
|
||||
public void setGame(Game game) {
|
||||
this.game = game;
|
||||
this.inputPlayback = new InputPlaybackControl(gui, game, this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -50,13 +76,14 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
*/
|
||||
@Override
|
||||
public Void visit(GameEventTurnPhase ev) {
|
||||
boolean isUiToStop = GuiBase.getInterface().stopAtPhase(ev.playerTurn, ev.phase);
|
||||
boolean isUiToStop = gui.stopAtPhase(
|
||||
gameView.getPlayerView(ev.playerTurn), ev.phase);
|
||||
|
||||
switch(ev.phase) {
|
||||
case COMBAT_END:
|
||||
case COMBAT_DECLARE_ATTACKERS:
|
||||
case COMBAT_DECLARE_BLOCKERS:
|
||||
if (GuiBase.getInterface().getGame().getPhaseHandler().inCombat()) {
|
||||
if (getGame().getPhaseHandler().inCombat()) {
|
||||
pauseForEvent(combatDelay);
|
||||
}
|
||||
break;
|
||||
@@ -75,13 +102,13 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
*/
|
||||
@Override
|
||||
public Void visit(GameEventGameFinished event) {
|
||||
GuiBase.getInterface().getInputQueue().removeInput(inputPlayback);
|
||||
gui.getInputQueue().removeInput(inputPlayback);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventGameStarted event) {
|
||||
GuiBase.getInterface().getInputQueue().setInput(inputPlayback);
|
||||
gui.getInputQueue().setInput(inputPlayback);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -93,7 +120,12 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
|
||||
@Override
|
||||
public Void visit(final GameEventSpellResolved event) {
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { GuiBase.getInterface().setCard(event.spell.getHostCard()); } });
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
gui.setCard(gameView.getCardView(event.spell.getHostCard()));
|
||||
}
|
||||
});
|
||||
pauseForEvent(resolveDelay);
|
||||
return null;
|
||||
}
|
||||
@@ -103,7 +135,12 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
*/
|
||||
@Override
|
||||
public Void visit(final GameEventSpellAbilityCast event) {
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { GuiBase.getInterface().setCard(event.sa.getHostCard()); } });
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
gui.setCard(gameView.getCardView(event.sa.getHostCard()));
|
||||
}
|
||||
});
|
||||
pauseForEvent(castDelay);
|
||||
return null;
|
||||
}
|
||||
@@ -139,7 +176,7 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
|
||||
private void releaseGameThread() {
|
||||
// just need to run another thread through the barrier... not edt preferrably :)
|
||||
|
||||
GuiBase.getInterface().getGame().getAction().invoke(new Runnable() {
|
||||
getGame().getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
@@ -3,17 +3,20 @@ package forge.deck;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.itemmanager.IItemManager;
|
||||
|
||||
|
||||
public class ColorDeckGenerator extends DeckProxy implements Comparable<ColorDeckGenerator> {
|
||||
private final IGuiBase gui;
|
||||
private String name;
|
||||
private int index;
|
||||
private final IItemManager<DeckProxy> lstDecks;
|
||||
private final boolean isAi;
|
||||
|
||||
public ColorDeckGenerator(String name0, int index0, IItemManager<DeckProxy> lstDecks0, boolean isAi0) {
|
||||
public ColorDeckGenerator(final IGuiBase gui, String name0, int index0, IItemManager<DeckProxy> lstDecks0, boolean isAi0) {
|
||||
super();
|
||||
this.gui = gui;
|
||||
name = name0;
|
||||
index = index0;
|
||||
lstDecks = lstDecks0;
|
||||
@@ -42,7 +45,7 @@ public class ColorDeckGenerator extends DeckProxy implements Comparable<ColorDec
|
||||
for (DeckProxy deck : lstDecks.getSelectedItems()) {
|
||||
selection.add(deck.getName());
|
||||
}
|
||||
if (DeckgenUtil.colorCheck(selection)) {
|
||||
if (DeckgenUtil.colorCheck(gui, selection)) {
|
||||
return DeckgenUtil.buildColorDeck(selection, isAi);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package forge.deck;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
@@ -9,11 +15,6 @@ import forge.card.CardEdition;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.error.BugReporter;
|
||||
import forge.game.GameFormat;
|
||||
import forge.game.GameType;
|
||||
import forge.item.InventoryItem;
|
||||
@@ -28,12 +29,6 @@ import forge.util.IHasName;
|
||||
import forge.util.storage.IStorage;
|
||||
import forge.util.storage.StorageImmediatelySerialized;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
// Adding a generic to this class creates compile problems in ItemManager (that I can not fix)
|
||||
public class DeckProxy implements InventoryItem {
|
||||
protected IHasName deck;
|
||||
@@ -361,7 +356,7 @@ public class DeckProxy implements InventoryItem {
|
||||
StringBuilder errorBuilder = new StringBuilder();
|
||||
deck.getMain().addAll(gen.getThemeDeck(this.getName(), 60, errorBuilder));
|
||||
if (errorBuilder.length() > 0) {
|
||||
BugReporter.reportBug(errorBuilder.toString());
|
||||
throw new RuntimeException(errorBuilder.toString());
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.deck.generation.*;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.itemmanager.IItemManager;
|
||||
import forge.model.FModel;
|
||||
@@ -186,18 +187,18 @@ public class DeckgenUtil {
|
||||
* @param colors0 String[]
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean colorCheck(final List<String> colors0) {
|
||||
public static boolean colorCheck(final IGuiBase gui, final List<String> colors0) {
|
||||
boolean result = true;
|
||||
|
||||
if (colors0.size() == 4) {
|
||||
SOptionPane.showMessageDialog(
|
||||
SOptionPane.showMessageDialog(gui,
|
||||
"Sorry, four color generated decks aren't supported yet."
|
||||
+ "\n\rPlease use 2, 3, or 5 colors for this deck.",
|
||||
"Generate deck: 4 colors", SOptionPane.ERROR_ICON);
|
||||
result = false;
|
||||
}
|
||||
else if (colors0.size() > 5) {
|
||||
SOptionPane.showMessageDialog(
|
||||
SOptionPane.showMessageDialog(gui,
|
||||
"Generate deck: maximum five colors!",
|
||||
"Generate deck: too many colors", SOptionPane.ERROR_ICON);
|
||||
result = false;
|
||||
|
||||
@@ -19,6 +19,7 @@ package forge.deck.io;
|
||||
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
@@ -47,6 +48,8 @@ public class OldDeckParser {
|
||||
}
|
||||
};
|
||||
|
||||
private final IGuiBase gui;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
*
|
||||
@@ -56,8 +59,9 @@ public class OldDeckParser {
|
||||
* @param sealed2 the sealed2
|
||||
* @param cube2 the cube2
|
||||
*/
|
||||
public OldDeckParser(final IStorage<Deck> constructed2, final IStorage<DeckGroup> draft2,
|
||||
public OldDeckParser(final IGuiBase gui, final IStorage<Deck> constructed2, final IStorage<DeckGroup> draft2,
|
||||
final IStorage<DeckGroup> sealed2, final IStorage<Deck> cube2) {
|
||||
this.gui = gui;
|
||||
this.deckDir = new File(ForgeConstants.DECK_BASE_DIR);
|
||||
this.sealed = sealed2;
|
||||
this.constructed = constructed2;
|
||||
@@ -145,7 +149,7 @@ public class OldDeckParser {
|
||||
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");
|
||||
mayDelete = SOptionPane.showConfirmDialog(gui, msg, "Draft loading error");
|
||||
}
|
||||
|
||||
if (mayDelete) {
|
||||
@@ -181,7 +185,7 @@ public class OldDeckParser {
|
||||
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");
|
||||
allowDeleteUnsupportedConstructed = SOptionPane.showConfirmDialog(gui, msg, "Problem converting decks");
|
||||
}
|
||||
}
|
||||
if (importedOk || allowDeleteUnsupportedConstructed) {
|
||||
@@ -200,7 +204,7 @@ public class OldDeckParser {
|
||||
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");
|
||||
allowDeleteUnsupportedConstructed = SOptionPane.showConfirmDialog(gui, msg, "Problem converting decks");
|
||||
}
|
||||
}
|
||||
if (importedOk || allowDeleteUnsupportedConstructed) {
|
||||
@@ -252,7 +256,7 @@ public class OldDeckParser {
|
||||
}
|
||||
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")) {
|
||||
if (SOptionPane.showConfirmDialog(gui, 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();
|
||||
|
||||
@@ -17,31 +17,36 @@
|
||||
*/
|
||||
package forge.download;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.UiCommand;
|
||||
import forge.error.BugReporter;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IProgressBar;
|
||||
import forge.interfaces.ITextField;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.net.ConnectException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.UiCommand;
|
||||
import forge.error.BugReporter;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.interfaces.IProgressBar;
|
||||
import forge.interfaces.ITextField;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class GuiDownloadService implements Runnable {
|
||||
public static final Proxy.Type[] TYPES = Proxy.Type.values();
|
||||
@@ -53,12 +58,13 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
private IButton btnStart;
|
||||
private UiCommand cmdClose;
|
||||
private Runnable onUpdate;
|
||||
private IGuiBase gui;
|
||||
|
||||
private final UiCommand cmdStartDownload = new UiCommand() {
|
||||
@Override
|
||||
public void run() {
|
||||
//invalidate image cache so newly downloaded images will be loaded
|
||||
GuiBase.getInterface().clearImageCache();
|
||||
gui.clearImageCache();
|
||||
FThreads.invokeInBackgroundThread(GuiDownloadService.this);
|
||||
btnStart.setEnabled(false);
|
||||
}
|
||||
@@ -78,13 +84,14 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
protected GuiDownloadService() {
|
||||
}
|
||||
|
||||
public void initialize(ITextField txtAddress0, ITextField txtPort0, IProgressBar progressBar0, IButton btnStart0, UiCommand cmdClose0, final Runnable onReadyToStart, Runnable onUpdate0) {
|
||||
public void initialize(final IGuiBase gui, ITextField txtAddress0, ITextField txtPort0, IProgressBar progressBar0, IButton btnStart0, UiCommand cmdClose0, final Runnable onReadyToStart, Runnable onUpdate0) {
|
||||
txtAddress = txtAddress0;
|
||||
txtPort = txtPort0;
|
||||
progressBar = progressBar0;
|
||||
btnStart = btnStart0;
|
||||
cmdClose = cmdClose0;
|
||||
onUpdate = onUpdate0;
|
||||
this.gui = gui;
|
||||
|
||||
// Free up the EDT by assembling card list on a background thread
|
||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||
@@ -96,7 +103,7 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
FThreads.invokeInEdtLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (onReadyToStart != null) {
|
||||
@@ -123,7 +130,7 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
}
|
||||
btnStart.setEnabled(true);
|
||||
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
FThreads.invokeInEdtLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
btnStart.requestFocusInWindow();
|
||||
@@ -162,7 +169,7 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
}
|
||||
|
||||
private void update(final int count, final File dest) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
FThreads.invokeInEdtLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (onUpdate != null) {
|
||||
@@ -220,7 +227,7 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
p = new Proxy(TYPES[type], new InetSocketAddress(txtAddress.getText(), Integer.parseInt(txtPort.getText())));
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
BugReporter.reportException(ex,
|
||||
BugReporter.reportException(ex, gui,
|
||||
"Proxy connection could not be established!\nProxy address: %s\nProxy port: %s",
|
||||
txtAddress.getText(), txtPort.getText());
|
||||
return;
|
||||
|
||||
@@ -17,16 +17,21 @@
|
||||
*/
|
||||
package forge.error;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.util.BuildInfo;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
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;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import forge.FThreads;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.util.BuildInfo;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
/**
|
||||
* The class ErrorViewer. Enables showing and saving error messages that
|
||||
@@ -68,22 +73,22 @@ public class BugReporter {
|
||||
* 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) {
|
||||
public static void reportException(final Throwable ex, final IGuiBase gui, final String message) {
|
||||
if (ex == null) {
|
||||
return;
|
||||
}
|
||||
if (message != null) {
|
||||
System.err.printf("%s > %s%n", FThreads.debugGetCurrThreadId(), message);
|
||||
System.err.printf("%s > %s%n", FThreads.debugGetCurrThreadId(gui), message);
|
||||
}
|
||||
System.err.print(FThreads.debugGetCurrThreadId() + " > ");
|
||||
System.err.print(FThreads.debugGetCurrThreadId(gui) + " > ");
|
||||
ex.printStackTrace();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Description: [describe what you were doing when the crash occurred]\n\n");
|
||||
buildSpoilerHeader(sb, ex.getClass().getSimpleName());
|
||||
buildSpoilerHeader(gui, sb, ex.getClass().getSimpleName());
|
||||
sb.append("\n\n");
|
||||
if (null != message && !message.isEmpty()) {
|
||||
sb.append(FThreads.debugGetCurrThreadId()).append(" > ").append(message).append("\n");
|
||||
sb.append(FThreads.debugGetCurrThreadId(gui)).append(" > ").append(message).append("\n");
|
||||
}
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
@@ -100,49 +105,49 @@ public class BugReporter {
|
||||
else {
|
||||
sb.append(swStr);
|
||||
}
|
||||
|
||||
|
||||
buildSpoilerFooter(sb);
|
||||
|
||||
GuiBase.getInterface().showBugReportDialog("Report a crash", sb.toString(), true);
|
||||
gui.showBugReportDialog("Report a crash", sb.toString(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for reportException(ex, null).
|
||||
*/
|
||||
public static void reportException(final Throwable ex) {
|
||||
reportException(ex, null);
|
||||
public static void reportException(final Throwable ex, final IGuiBase gui) {
|
||||
reportException(ex, gui, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for reportException(ex, String.format(format, args)).
|
||||
*/
|
||||
public static void reportException(final Throwable ex, final String format, final Object... args) {
|
||||
reportException(ex, String.format(format, args));
|
||||
public static void reportException(final Throwable ex, final IGuiBase gui, final String format, final Object... args) {
|
||||
reportException(ex, gui, String.format(format, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a forum post template for reporting a bug.
|
||||
*/
|
||||
public static void reportBug(String details) {
|
||||
public static void reportBug(final IGuiBase gui, final String details) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Description: [describe the problem]\n\n");
|
||||
buildSpoilerHeader(sb, "General bug report");
|
||||
buildSpoilerHeader(gui, sb, "General bug report");
|
||||
if (null != details && !details.isEmpty()) {
|
||||
sb.append("\n\n");
|
||||
sb.append(details);
|
||||
}
|
||||
buildSpoilerFooter(sb);
|
||||
|
||||
GuiBase.getInterface().showBugReportDialog("Report a bug", sb.toString(), false);
|
||||
gui.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) {
|
||||
public static void reportThreadStacks(final IGuiBase gui,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");
|
||||
buildSpoilerHeader(gui, sb, "Thread stack dump");
|
||||
sb.append("\n\n");
|
||||
if (null != message && !message.isEmpty()) {
|
||||
sb.append(message);
|
||||
@@ -162,7 +167,7 @@ public class BugReporter {
|
||||
|
||||
sb.append(sw.toString());
|
||||
buildSpoilerFooter(sb);
|
||||
GuiBase.getInterface().showBugReportDialog("Thread stack dump", sb.toString(), false);
|
||||
gui.showBugReportDialog("Thread stack dump", sb.toString(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,9 +177,9 @@ public class BugReporter {
|
||||
reportThreadStacks(String.format(format, args));
|
||||
}
|
||||
|
||||
private static StringBuilder buildSpoilerHeader(StringBuilder sb, String reportTitle) {
|
||||
private static StringBuilder buildSpoilerHeader(final IGuiBase gui, final StringBuilder sb, final String reportTitle) {
|
||||
sb.append("[spoiler=").append(reportTitle).append("][code]");
|
||||
sb.append("\nForge Version: ").append(GuiBase.getInterface().getCurrentVersion());
|
||||
sb.append("\nForge Version: ").append(gui.getCurrentVersion());
|
||||
sb.append("\nOperating System: ").append(System.getProperty("os.name"))
|
||||
.append(" ").append(System.getProperty("os.version"))
|
||||
.append(" ").append(System.getProperty("os.arch"));
|
||||
@@ -188,19 +193,19 @@ public class BugReporter {
|
||||
return sb;
|
||||
}
|
||||
|
||||
public static void copyAndGoToForums(String text) {
|
||||
public static void copyAndGoToForums(final IGuiBase gui, final String text) {
|
||||
try {
|
||||
// copy text to clipboard
|
||||
GuiBase.getInterface().copyToClipboard(text);
|
||||
GuiBase.getInterface().browseToUrl(FORUM_URL);
|
||||
gui.copyToClipboard(text);
|
||||
gui.browseToUrl(FORUM_URL);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
SOptionPane.showMessageDialog("Sorry, a problem occurred while opening the forum in your default browser.",
|
||||
SOptionPane.showMessageDialog(gui, "Sorry, a problem occurred while opening the forum in your default browser.",
|
||||
"A problem occurred", SOptionPane.ERROR_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveToFile(String text) {
|
||||
public static void saveToFile(final IGuiBase gui, final String text) {
|
||||
File f;
|
||||
long curTime = System.currentTimeMillis();
|
||||
for (int i = 0;; i++) {
|
||||
@@ -211,7 +216,7 @@ public class BugReporter {
|
||||
}
|
||||
}
|
||||
|
||||
f = GuiBase.getInterface().getSaveFile(f);
|
||||
f = gui.getSaveFile(f);
|
||||
|
||||
try {
|
||||
final BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
||||
@@ -219,7 +224,7 @@ public class BugReporter {
|
||||
bw.close();
|
||||
}
|
||||
catch (final IOException ex) {
|
||||
SOptionPane.showMessageDialog("There was an error during saving. Sorry!\n" + ex,
|
||||
SOptionPane.showMessageDialog(gui, "There was an error during saving. Sorry!\n" + ex,
|
||||
"Error saving file", SOptionPane.ERROR_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.MultiplexOutputStream;
|
||||
|
||||
@@ -46,6 +47,7 @@ public class ExceptionHandler implements UncaughtExceptionHandler {
|
||||
System.setProperty("sun.awt.exception.handler", ExceptionHandler.class.getName());
|
||||
}
|
||||
|
||||
private static IGuiBase gui;
|
||||
private static PrintStream oldSystemOut;
|
||||
private static PrintStream oldSystemErr;
|
||||
private static OutputStream logFileStream;
|
||||
@@ -54,10 +56,12 @@ public class ExceptionHandler implements UncaughtExceptionHandler {
|
||||
* Call this at the beginning to make sure that the class is loaded and the
|
||||
* static initializer has run.
|
||||
*/
|
||||
public static void registerErrorHandling() {
|
||||
public static void registerErrorHandling(final IGuiBase gui) {
|
||||
//initialize log file
|
||||
File logFile = new File(ForgeConstants.LOG_FILE);
|
||||
|
||||
ExceptionHandler.gui = gui;
|
||||
|
||||
int i = 0;
|
||||
while (logFile.exists() && !logFile.delete()) {
|
||||
String pathname = logFile.getPath().replaceAll("[0-9]{0,2}.log$", String.valueOf(i++) + ".log");
|
||||
@@ -101,7 +105,7 @@ public class ExceptionHandler implements UncaughtExceptionHandler {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void uncaughtException(final Thread t, final Throwable ex) {
|
||||
BugReporter.reportException(ex);
|
||||
BugReporter.reportException(ex, gui);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,6 +116,6 @@ public class ExceptionHandler implements UncaughtExceptionHandler {
|
||||
* a {@link java.lang.Throwable} object.
|
||||
*/
|
||||
public final void handle(final Throwable ex) {
|
||||
BugReporter.reportException(ex);
|
||||
BugReporter.reportException(ex, gui);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package forge.events;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.view.CardView;
|
||||
import forge.view.GameEntityView;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
@@ -9,16 +9,16 @@ import forge.game.card.Card;
|
||||
*/
|
||||
public class UiEventAttackerDeclared extends UiEvent {
|
||||
|
||||
public final Card attacker;
|
||||
public final GameEntity defender;
|
||||
public final CardView attacker;
|
||||
public final GameEntityView defender;
|
||||
|
||||
public UiEventAttackerDeclared(Card card, GameEntity currentDefender) {
|
||||
public UiEventAttackerDeclared(final CardView card, final GameEntityView currentDefender) {
|
||||
attacker = card;
|
||||
defender = currentDefender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(IUiEventVisitor<T> visitor) {
|
||||
public <T> T visit(final IUiEventVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,6 @@ public class UiEventAttackerDeclared extends UiEvent {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return attacker.toString() + ( defender == null ? " removed from combat" : " declared to attack " + defender.getName() );
|
||||
return attacker.toString() + ( defender == null ? " removed from combat" : " declared to attack " + defender );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package forge.events;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.view.CardView;
|
||||
|
||||
public class UiEventBlockerAssigned extends UiEvent {
|
||||
|
||||
public final Card blocker;
|
||||
public final Card attackerBeingBlocked;
|
||||
public final CardView blocker;
|
||||
public final CardView attackerBeingBlocked;
|
||||
|
||||
public UiEventBlockerAssigned(Card card, Card currentAttacker) {
|
||||
public UiEventBlockerAssigned(final CardView card, final CardView currentAttacker) {
|
||||
blocker = card;
|
||||
attackerBeingBlocked = currentAttacker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(IUiEventVisitor<T> visitor) {
|
||||
public <T> T visit(final IUiEventVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
package forge.gauntlet;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.converters.Converter;
|
||||
import com.thoughtworks.xstream.converters.MarshallingContext;
|
||||
@@ -8,19 +21,11 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
|
||||
import forge.deck.CardPool;
|
||||
import forge.error.BugReporter;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.IgnoringXStream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class GauntletIO {
|
||||
/** Prompt in text field for new (unsaved) built gauntlets. */
|
||||
public static final String TXF_PROMPT = "[New Gauntlet]";
|
||||
@@ -85,7 +90,6 @@ public class GauntletIO {
|
||||
|
||||
return data;
|
||||
} catch (final Exception ex) {
|
||||
BugReporter.reportException(ex, "Error loading Gauntlet Data");
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
if (null != zin) {
|
||||
@@ -100,7 +104,6 @@ public class GauntletIO {
|
||||
final XStream xStream = GauntletIO.getSerializer(false);
|
||||
GauntletIO.savePacked(xStream, gd0);
|
||||
} catch (final Exception ex) {
|
||||
BugReporter.reportException(ex, "Error saving Gauntlet Data.");
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,26 +4,26 @@ import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.interfaces.IWinLoseView;
|
||||
import forge.model.FModel;
|
||||
import forge.view.IGameView;
|
||||
|
||||
public abstract class GauntletWinLoseController {
|
||||
private final Game lastGame;
|
||||
private final IGameView lastGame;
|
||||
private final IWinLoseView<? extends IButton> view;
|
||||
private final IGuiBase gui;
|
||||
|
||||
public GauntletWinLoseController(IWinLoseView<? extends IButton> view0, Game lastGame0) {
|
||||
public GauntletWinLoseController(IWinLoseView<? extends IButton> view0, final IGameView game0, final IGuiBase gui) {
|
||||
view = view0;
|
||||
lastGame = lastGame0;
|
||||
lastGame = game0;
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
public void showOutcome() {
|
||||
@@ -43,24 +43,22 @@ public abstract class GauntletWinLoseController {
|
||||
// Generic event record.
|
||||
lstEventRecords.set(gd.getCompleted(), "Ongoing");
|
||||
|
||||
final Match match = lastGame.getMatch();
|
||||
|
||||
// Match won't be saved until it is over. This opens up a cheat
|
||||
// or failsafe mechanism (depending on your perspective) in which
|
||||
// the player can restart Forge to replay a match.
|
||||
// Pretty sure this can't be fixed until in-game states can be
|
||||
// saved. Doublestrike 07-10-12
|
||||
LobbyPlayer questPlayer = GuiBase.getInterface().getQuestPlayer();
|
||||
LobbyPlayer questPlayer = gui.getQuestPlayer();
|
||||
|
||||
// In all cases, update stats.
|
||||
lstEventRecords.set(gd.getCompleted(), match.getGamesWonBy(questPlayer) + " - "
|
||||
+ (match.getPlayedGames().size() - match.getGamesWonBy(questPlayer)));
|
||||
lstEventRecords.set(gd.getCompleted(), lastGame.getGamesWonBy(questPlayer) + " - "
|
||||
+ (lastGame.getNumPlayedGamesInMatch() - lastGame.getGamesWonBy(questPlayer)));
|
||||
|
||||
if (match.isMatchOver()) {
|
||||
if (lastGame.isMatchOver()) {
|
||||
gd.setCompleted(gd.getCompleted() + 1);
|
||||
|
||||
// Win match case
|
||||
if (match.isWonBy(questPlayer)) {
|
||||
if (lastGame.isMatchWonBy(questPlayer)) {
|
||||
// Gauntlet complete: Remove save file
|
||||
if (gd.getCompleted() == lstDecks.size()) {
|
||||
icon = FSkinProp.ICO_QUEST_COIN;
|
||||
@@ -112,20 +110,19 @@ public abstract class GauntletWinLoseController {
|
||||
}
|
||||
|
||||
public final boolean actionOnContinue() {
|
||||
if (lastGame.getMatch().isMatchOver()) {
|
||||
if (lastGame.isMatchOver()) {
|
||||
// To change the AI deck, we have to create a new match.
|
||||
GauntletData gd = FModel.getGauntletData();
|
||||
Deck aiDeck = gd.getDecks().get(gd.getCompleted());
|
||||
List<RegisteredPlayer> players = Lists.newArrayList();
|
||||
IGuiBase fc = GuiBase.getInterface();
|
||||
players.add(new RegisteredPlayer(gd.getUserDeck()).setPlayer(fc.getGuiPlayer()));
|
||||
players.add(new RegisteredPlayer(aiDeck).setPlayer(fc.createAiPlayer()));
|
||||
players.add(new RegisteredPlayer(gd.getUserDeck()).setPlayer(gui.getGuiPlayer()));
|
||||
players.add(new RegisteredPlayer(aiDeck).setPlayer(gui.createAiPlayer()));
|
||||
|
||||
view.hide();
|
||||
saveOptions();
|
||||
GuiBase.getInterface().endCurrentGame();
|
||||
gui.endCurrentGame();
|
||||
|
||||
GuiBase.getInterface().startMatch(GameType.Gauntlet, players);
|
||||
gui.startMatch(GameType.Gauntlet, players);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -15,25 +15,22 @@ import forge.assets.FSkinProp;
|
||||
import forge.assets.ISkinImage;
|
||||
import forge.deck.CardPool;
|
||||
import forge.events.UiEvent;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.event.GameEventTurnBegan;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.IHasIcon;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.match.input.InputQueue;
|
||||
import forge.sound.IAudioClip;
|
||||
import forge.sound.IAudioMusic;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
import forge.view.CardView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.SpellAbilityView;
|
||||
|
||||
public interface IGuiBase {
|
||||
boolean isRunningOnDesktop();
|
||||
@@ -41,57 +38,54 @@ public interface IGuiBase {
|
||||
void invokeInEdtLater(Runnable runnable);
|
||||
void invokeInEdtAndWait(final Runnable proc);
|
||||
boolean isGuiThread();
|
||||
String getAssetsDir();
|
||||
boolean mayShowCard(Card card);
|
||||
ISkinImage getSkinIcon(FSkinProp skinProp);
|
||||
ISkinImage getUnskinnedIcon(String path);
|
||||
void showBugReportDialog(String title, String text, boolean showExitAppBtn);
|
||||
int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
||||
int showCardOptionDialog(Card card, String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
||||
int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
||||
<T> T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions);
|
||||
<T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display);
|
||||
<T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode);
|
||||
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode);
|
||||
List<PaperCard> sideboard(CardPool sideboard, CardPool main);
|
||||
String showFileDialog(String title, String defaultDir);
|
||||
File getSaveFile(File defaultFile);
|
||||
void showCardList(final String title, final String message, final List<PaperCard> list);
|
||||
boolean showBoxedProduct(final String title, final String message, final List<PaperCard> list);
|
||||
void fireEvent(UiEvent e);
|
||||
void setCard(Card card);
|
||||
void showCombat(Combat combat);
|
||||
void setUsedToPay(Card card, boolean b);
|
||||
void setHighlighted(Player player, boolean b);
|
||||
void setCard(CardView card);
|
||||
void showCombat(CombatView combat);
|
||||
void setUsedToPay(CardView card, boolean b);
|
||||
void setHighlighted(PlayerView player, boolean b);
|
||||
void showPromptMessage(String message);
|
||||
boolean stopAtPhase(Player playerTurn, PhaseType phase);
|
||||
boolean stopAtPhase(PlayerView playerTurn, PhaseType phase);
|
||||
InputQueue getInputQueue();
|
||||
Game getGame();
|
||||
IButton getBtnOK();
|
||||
IButton getBtnCancel();
|
||||
void focusButton(IButton button);
|
||||
void flashIncorrectAction();
|
||||
void updatePhase();
|
||||
void updateTurn(GameEventTurnBegan event, Game game);
|
||||
void updateTurn(PlayerView player);
|
||||
void updatePlayerControl();
|
||||
void enableOverlay();
|
||||
void disableOverlay();
|
||||
void finishGame();
|
||||
Object showManaPool(Player player);
|
||||
void hideManaPool(Player player, Object zoneToRestore);
|
||||
boolean openZones(List<ZoneType> zones, Map<Player, Object> players);
|
||||
void restoreOldZones(Map<Player, Object> playersToRestoreZonesFor);
|
||||
Object showManaPool(PlayerView player);
|
||||
void hideManaPool(PlayerView player, Object zoneToRestore);
|
||||
boolean openZones(Collection<ZoneType> zones, Map<PlayerView, Object> players);
|
||||
void restoreOldZones(Map<PlayerView, Object> playersToRestoreZonesFor);
|
||||
void updateStack();
|
||||
void updateZones(List<Pair<Player, ZoneType>> zonesToUpdate);
|
||||
void updateCards(Set<Card> cardsToUpdate);
|
||||
void refreshCardDetails(Collection<Card> cards);
|
||||
void updateManaPool(List<Player> manaPoolUpdate);
|
||||
void updateLives(List<Player> livesUpdate);
|
||||
void updateZones(List<Pair<PlayerView, ZoneType>> zonesToUpdate);
|
||||
void updateCards(Set<CardView> cardsToUpdate);
|
||||
void refreshCardDetails(Iterable<CardView> cards);
|
||||
void updateManaPool(List<PlayerView> manaPoolUpdate);
|
||||
void updateLives(List<PlayerView> livesUpdate);
|
||||
void endCurrentGame();
|
||||
void startMatch(GameType gauntletType, List<RegisteredPlayer> starter);
|
||||
void setPanelSelection(Card hostCard);
|
||||
Map<Card, Integer> getDamageToAssign(Card attacker, List<Card> blockers,
|
||||
int damageDealt, GameEntity defender, boolean overrideOrder);
|
||||
SpellAbility getAbilityToPlay(List<SpellAbility> abilities, ITriggerEvent triggerEvent);
|
||||
void setPanelSelection(CardView hostCard);
|
||||
Map<CardView, Integer> getDamageToAssign(CardView attacker, List<CardView> blockers,
|
||||
int damageDealt, GameEntityView defender, boolean overrideOrder);
|
||||
SpellAbilityView getAbilityToPlay(List<SpellAbilityView> abilities, ITriggerEvent triggerEvent);
|
||||
void hear(LobbyPlayer player, String message);
|
||||
int getAvatarCount();
|
||||
void copyToClipboard(String text);
|
||||
|
||||
@@ -25,6 +25,7 @@ import forge.card.UnOpenedProduct;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.card.Card;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
@@ -66,13 +67,13 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
|
||||
protected final List<Supplier<List<PaperCard>>> product = new ArrayList<Supplier<List<PaperCard>>>();
|
||||
|
||||
public static BoosterDraft createDraft(final LimitedPoolType draftType) {
|
||||
public static BoosterDraft createDraft(final IGuiBase gui, final LimitedPoolType draftType) {
|
||||
BoosterDraft draft = new BoosterDraft(draftType);
|
||||
if (!draft.generateProduct()) { return null; }
|
||||
if (!draft.generateProduct(gui)) { return null; }
|
||||
return draft;
|
||||
}
|
||||
|
||||
protected boolean generateProduct() {
|
||||
protected boolean generateProduct(final IGuiBase gui) {
|
||||
switch (this.draftFormat) {
|
||||
case Full: // Draft from all cards in Forge
|
||||
Supplier<List<PaperCard>> s = new UnOpenedProduct(SealedProduct.Template.genericBooster);
|
||||
@@ -95,12 +96,12 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
}
|
||||
}
|
||||
|
||||
final CardBlock block = SGuiChoose.oneOrNone("Choose Block", blocks);
|
||||
final CardBlock block = SGuiChoose.oneOrNone(gui, "Choose Block", blocks);
|
||||
if (block == null) { return false; }
|
||||
|
||||
final CardEdition[] cardSets = block.getSets();
|
||||
if (cardSets.length == 0) {
|
||||
SOptionPane.showErrorDialog(block.toString() + " does not contain any set combinations.");
|
||||
SOptionPane.showErrorDialog(gui, block.toString() + " does not contain any set combinations.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -118,16 +119,16 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
final int nPacks = block.getCntBoostersDraft();
|
||||
|
||||
if (sets.size() > 1) {
|
||||
final Object p = SGuiChoose.oneOrNone("Choose Set Combination", getSetCombos(sets));
|
||||
final Object p = SGuiChoose.oneOrNone(gui, "Choose Set Combination", getSetCombos(sets));
|
||||
if (p == null) { return false; }
|
||||
|
||||
final String[] pp = p.toString().split("/");
|
||||
for (int i = 0; i < nPacks; i++) {
|
||||
this.product.add(block.getBooster(pp[i]));
|
||||
this.product.add(block.getBooster(pp[i], gui));
|
||||
}
|
||||
}
|
||||
else {
|
||||
IUnOpenedProduct product1 = block.getBooster(sets.get(0));
|
||||
IUnOpenedProduct product1 = block.getBooster(sets.get(0), gui);
|
||||
|
||||
for (int i = 0; i < nPacks; i++) {
|
||||
this.product.add(product1);
|
||||
@@ -141,10 +142,10 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
final List<CustomLimited> myDrafts = this.loadCustomDrafts();
|
||||
|
||||
if (myDrafts.isEmpty()) {
|
||||
SOptionPane.showMessageDialog("No custom draft files found.");
|
||||
SOptionPane.showMessageDialog(gui, "No custom draft files found.");
|
||||
}
|
||||
else {
|
||||
final CustomLimited customDraft = SGuiChoose.oneOrNone("Choose Custom Draft", myDrafts);
|
||||
final CustomLimited customDraft = SGuiChoose.oneOrNone(gui, "Choose Custom Draft", myDrafts);
|
||||
if (customDraft == null) { return false; }
|
||||
|
||||
this.setupCustomDraft(customDraft);
|
||||
@@ -159,13 +160,13 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BoosterDraft createDraft(final LimitedPoolType draftType, final CardBlock block, final String[] boosters) {
|
||||
public static BoosterDraft createDraft(final IGuiBase gui, final LimitedPoolType draftType, final CardBlock block, final String[] boosters) {
|
||||
BoosterDraft draft = new BoosterDraft(draftType);
|
||||
|
||||
final int nPacks = boosters.length;
|
||||
|
||||
for (int i = 0; i < nPacks; i++) {
|
||||
draft.product.add(block.getBooster(boosters[i]));
|
||||
draft.product.add(block.getBooster(boosters[i], gui));
|
||||
}
|
||||
|
||||
IBoosterDraft.LAND_SET_CODE[0] = block.getLandSet();
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
*/
|
||||
package forge.limited;
|
||||
|
||||
import forge.GuiBase;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import forge.deck.Deck;
|
||||
import forge.game.GameType;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
@@ -25,9 +27,6 @@ import forge.interfaces.IGuiBase;
|
||||
import forge.model.FModel;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* GauntletMini class.
|
||||
@@ -39,6 +38,7 @@ import java.util.List;
|
||||
*/
|
||||
public class GauntletMini {
|
||||
|
||||
private final IGuiBase gui;
|
||||
private int rounds;
|
||||
private Deck humanDeck;
|
||||
private int currentRound;
|
||||
@@ -48,6 +48,10 @@ public class GauntletMini {
|
||||
private GameType gauntletType;
|
||||
private List<RegisteredPlayer> aiOpponents = new ArrayList<RegisteredPlayer>();
|
||||
|
||||
public GauntletMini(IGuiBase gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
// private final String humanName;
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
@@ -81,7 +85,7 @@ public class GauntletMini {
|
||||
}
|
||||
|
||||
currentRound++;
|
||||
GuiBase.getInterface().endCurrentGame();
|
||||
gui.endCurrentGame();
|
||||
startRound();
|
||||
}
|
||||
|
||||
@@ -135,11 +139,10 @@ public class GauntletMini {
|
||||
*/
|
||||
private void startRound() {
|
||||
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
|
||||
IGuiBase fc = GuiBase.getInterface();
|
||||
starter.add(new RegisteredPlayer(humanDeck).setPlayer(fc.getGuiPlayer()));
|
||||
starter.add(aiOpponents.get(currentRound - 1).setPlayer(fc.createAiPlayer()));
|
||||
starter.add(new RegisteredPlayer(humanDeck).setPlayer(gui.getGuiPlayer()));
|
||||
starter.add(aiOpponents.get(currentRound - 1).setPlayer(gui.createAiPlayer()));
|
||||
|
||||
fc.startMatch(gauntletType, starter);
|
||||
gui.startMatch(gauntletType, starter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
package forge.limited;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.interfaces.IWinLoseView;
|
||||
import forge.model.FModel;
|
||||
import forge.view.IGameView;
|
||||
|
||||
public abstract class LimitedWinLoseController {
|
||||
private final Game lastGame;
|
||||
private final boolean wonMatch;
|
||||
private final IWinLoseView<? extends IButton> view;
|
||||
private final IGameView lastGame;
|
||||
private final IGuiBase gui;
|
||||
private final boolean wonMatch;
|
||||
private GauntletMini gauntlet;
|
||||
private boolean nextRound = false;
|
||||
|
||||
public LimitedWinLoseController(IWinLoseView<? extends IButton> view0, Game lastGame0) {
|
||||
public LimitedWinLoseController(IWinLoseView<? extends IButton> view0, final IGameView game0, final IGuiBase gui) {
|
||||
view = view0;
|
||||
lastGame = lastGame0;
|
||||
gauntlet = FModel.getGauntletMini();
|
||||
wonMatch = lastGame.getMatch().isWonBy(GuiBase.getInterface().getGuiPlayer());
|
||||
lastGame = game0;
|
||||
this.gui = gui;
|
||||
gauntlet = FModel.getGauntletMini(gui);
|
||||
wonMatch = lastGame.isMatchWonBy(gui.getGuiPlayer());
|
||||
}
|
||||
|
||||
public void showOutcome() {
|
||||
@@ -29,10 +31,9 @@ public abstract class LimitedWinLoseController {
|
||||
resetView();
|
||||
nextRound = false;
|
||||
|
||||
if (lastGame.getOutcome().isWinner(GuiBase.getInterface().getGuiPlayer())) {
|
||||
if (lastGame.isWinner(gui.getGuiPlayer())) {
|
||||
gauntlet.addWin();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gauntlet.addLoss();
|
||||
}
|
||||
|
||||
@@ -41,7 +42,7 @@ public abstract class LimitedWinLoseController {
|
||||
showOutcome(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!lastGame.getMatch().isMatchOver()) {
|
||||
if (!lastGame.isMatchOver()) {
|
||||
showTournamentInfo("Tournament Info");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.model.CardBlock;
|
||||
@@ -66,12 +67,12 @@ public class SealedCardPoolGenerator {
|
||||
/** The Land set code. */
|
||||
private String landSetCode = null;
|
||||
|
||||
public static DeckGroup generateSealedDeck(boolean addBasicLands) {
|
||||
public static DeckGroup generateSealedDeck(final IGuiBase gui, final boolean addBasicLands) {
|
||||
final String prompt = "Choose Sealed Deck Format";
|
||||
final LimitedPoolType poolType = SGuiChoose.oneOrNone(prompt, LimitedPoolType.values());
|
||||
final LimitedPoolType poolType = SGuiChoose.oneOrNone(gui, prompt, LimitedPoolType.values());
|
||||
if (poolType == null) { return null; }
|
||||
|
||||
SealedCardPoolGenerator sd = new SealedCardPoolGenerator(poolType);
|
||||
SealedCardPoolGenerator sd = new SealedCardPoolGenerator(gui, poolType);
|
||||
if (sd.isEmpty()) { return null; }
|
||||
|
||||
final CardPool humanPool = sd.getCardPool(true);
|
||||
@@ -82,10 +83,10 @@ public class SealedCardPoolGenerator {
|
||||
// This seems to be limited by the MAX_DRAFT_PLAYERS constant
|
||||
// in DeckGroupSerializer.java. You could create more AI decks
|
||||
// but only the first seven would load. --BBU
|
||||
Integer rounds = SGuiChoose.getInteger("How many opponents are you willing to face?", 1, 7);
|
||||
Integer rounds = SGuiChoose.getInteger(gui, "How many opponents are you willing to face?", 1, 7);
|
||||
if (rounds == null) { return null; }
|
||||
|
||||
final String sDeckName = SOptionPane.showInputDialog(
|
||||
final String sDeckName = SOptionPane.showInputDialog(gui,
|
||||
"Save this card pool as:",
|
||||
"Save Card Pool",
|
||||
FSkinProp.ICO_QUESTION);
|
||||
@@ -96,7 +97,7 @@ public class SealedCardPoolGenerator {
|
||||
|
||||
final IStorage<DeckGroup> sealedDecks = FModel.getDecks().getSealed();
|
||||
if (sealedDecks.contains(sDeckName)) {
|
||||
if (!SOptionPane.showConfirmDialog(
|
||||
if (!SOptionPane.showConfirmDialog(gui,
|
||||
"'" + sDeckName + "' already exists. Do you want to replace it?",
|
||||
"Sealed Deck Game Exists")) {
|
||||
return null;
|
||||
@@ -154,11 +155,11 @@ public class SealedCardPoolGenerator {
|
||||
* @param poolType
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
private SealedCardPoolGenerator(final LimitedPoolType poolType) {
|
||||
private SealedCardPoolGenerator(final IGuiBase gui, final LimitedPoolType poolType) {
|
||||
switch(poolType) {
|
||||
case Full:
|
||||
// Choose number of boosters
|
||||
if (!chooseNumberOfBoosters(new UnOpenedProduct(SealedProduct.Template.genericBooster))) {
|
||||
if (!chooseNumberOfBoosters(gui, new UnOpenedProduct(SealedProduct.Template.genericBooster))) {
|
||||
return;
|
||||
}
|
||||
landSetCode = CardEdition.Predicates.getRandomSetWithAllBasicLands(FModel.getMagicDb().getEditions()).getCode();
|
||||
@@ -172,7 +173,7 @@ public class SealedCardPoolGenerator {
|
||||
blocks.add(b);
|
||||
}
|
||||
|
||||
final CardBlock block = SGuiChoose.oneOrNone("Choose Block", blocks);
|
||||
final CardBlock block = SGuiChoose.oneOrNone(gui, "Choose Block", blocks);
|
||||
if (block == null) { return; }
|
||||
|
||||
final int nPacks = block.getCntBoostersSealed();
|
||||
@@ -192,7 +193,7 @@ public class SealedCardPoolGenerator {
|
||||
throw new RuntimeException("Unsupported amount of packs (" + nPacks + ") in a Sealed Deck block!");
|
||||
}
|
||||
|
||||
final String p = setCombos.size() > 1 ? SGuiChoose.oneOrNone("Choose packs to play with", setCombos) : setCombos.get(0);
|
||||
final String p = setCombos.size() > 1 ? SGuiChoose.oneOrNone(gui, "Choose packs to play with", setCombos) : setCombos.get(0);
|
||||
if (p == null) { return; }
|
||||
|
||||
for (String pz : TextUtil.split(p, ',')) {
|
||||
@@ -200,12 +201,12 @@ public class SealedCardPoolGenerator {
|
||||
String setCode = pps[pps.length - 1];
|
||||
int nBoosters = pps.length > 1 ? Integer.parseInt(pps[0]) : 1;
|
||||
while (nBoosters-- > 0) {
|
||||
this.product.add(block.getBooster(setCode));
|
||||
this.product.add(block.getBooster(setCode, gui));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
IUnOpenedProduct prod = block.getBooster(sets.get(0));
|
||||
IUnOpenedProduct prod = block.getBooster(sets.get(0), gui);
|
||||
for (int i = 0; i < nPacks; i++) {
|
||||
this.product.add(prod);
|
||||
}
|
||||
@@ -243,16 +244,16 @@ public class SealedCardPoolGenerator {
|
||||
|
||||
// present list to user
|
||||
if (customs.isEmpty()) {
|
||||
SOptionPane.showMessageDialog("No custom sealed files found.");
|
||||
SOptionPane.showMessageDialog(gui, "No custom sealed files found.");
|
||||
return;
|
||||
}
|
||||
|
||||
final CustomLimited draft = SGuiChoose.oneOrNone("Choose Custom Sealed Pool", customs);
|
||||
final CustomLimited draft = SGuiChoose.oneOrNone(gui, "Choose Custom Sealed Pool", customs);
|
||||
if (draft == null) { return; }
|
||||
|
||||
UnOpenedProduct toAdd = new UnOpenedProduct(draft.getSealedProductTemplate(), draft.getCardPool());
|
||||
toAdd.setLimitedPool(draft.isSingleton());
|
||||
if (!chooseNumberOfBoosters(toAdd)) {
|
||||
if (!chooseNumberOfBoosters(gui, toAdd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -261,8 +262,8 @@ public class SealedCardPoolGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean chooseNumberOfBoosters(final IUnOpenedProduct product1) {
|
||||
Integer boosterCount = SGuiChoose.getInteger("How many booster packs?", 3, 12);
|
||||
private boolean chooseNumberOfBoosters(final IGuiBase gui, final IUnOpenedProduct product1) {
|
||||
Integer boosterCount = SGuiChoose.getInteger(gui, "How many booster packs?", 3, 12);
|
||||
if (boosterCount == null) { return false; }
|
||||
|
||||
for (int i = 0; i < boosterCount; i++) {
|
||||
|
||||
@@ -3,8 +3,10 @@ package forge.limited;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
@@ -18,9 +20,9 @@ public class WinstonDraft extends BoosterDraft {
|
||||
private Stack<PaperCard> deck; // main deck where all cards
|
||||
private List<List<PaperCard>> piles; // 3 piles to draft from
|
||||
|
||||
public static WinstonDraft createDraft(final LimitedPoolType draftType) {
|
||||
public static WinstonDraft createDraft(final IGuiBase gui, final LimitedPoolType draftType) {
|
||||
WinstonDraft draft = new WinstonDraft(draftType);
|
||||
if (!draft.generateProduct()) {
|
||||
if (!draft.generateProduct(gui)) {
|
||||
return null;
|
||||
}
|
||||
draft.initializeWinstonDraft();
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package forge.match;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
import forge.match.input.Input;
|
||||
import forge.match.input.InputPassPriority;
|
||||
|
||||
public class MatchUtil {
|
||||
public static boolean undoLastAction() {
|
||||
if (canUndoLastAction() && GuiBase.getInterface().getGame().stack.undo()) {
|
||||
Input currentInput = GuiBase.getInterface().getInputQueue().getInput();
|
||||
if (currentInput instanceof InputPassPriority) {
|
||||
currentInput.showMessageInitial(); //ensure prompt updated if needed
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean canUndoLastAction() {
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
if (game.stack.canUndo()) {
|
||||
Player player = game.getPhaseHandler().getPriorityPlayer();
|
||||
if (player != null && player.getLobbyPlayer() == GuiBase.getInterface().getGuiPlayer()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -17,29 +17,29 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiBase;
|
||||
|
||||
/**
|
||||
* Manages match UI OK/Cancel button enabling and focus
|
||||
*/
|
||||
public class ButtonUtil {
|
||||
public static void update(boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
|
||||
update("OK", "Cancel", okEnabled, cancelEnabled, focusOk);
|
||||
public static void update(final IGuiBase gui, boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
|
||||
update(gui, "OK", "Cancel", okEnabled, cancelEnabled, focusOk);
|
||||
}
|
||||
public static void update(String okLabel, String cancelLabel, boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
|
||||
IButton btnOk = GuiBase.getInterface().getBtnOK();
|
||||
IButton btnCancel = GuiBase.getInterface().getBtnCancel();
|
||||
public static void update(final IGuiBase gui, String okLabel, String cancelLabel, boolean okEnabled, boolean cancelEnabled, boolean focusOk) {
|
||||
IButton btnOk = gui.getBtnOK();
|
||||
IButton btnCancel = gui.getBtnCancel();
|
||||
|
||||
btnOk.setText(okLabel);
|
||||
btnCancel.setText(cancelLabel);
|
||||
btnOk.setEnabled(okEnabled);
|
||||
btnCancel.setEnabled(cancelEnabled);
|
||||
if (okEnabled && focusOk) {
|
||||
GuiBase.getInterface().focusButton(btnOk);
|
||||
gui.focusButton(btnOk);
|
||||
}
|
||||
else if (cancelEnabled) {
|
||||
GuiBase.getInterface().focusButton(btnCancel);
|
||||
gui.focusButton(btnCancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
|
||||
public interface Input {
|
||||
void showMessageInitial();
|
||||
|
||||
boolean selectCard(Card c, ITriggerEvent triggerEvent);
|
||||
|
||||
boolean selectCard(Card card, ITriggerEvent triggerEvent);
|
||||
|
||||
void selectAbility(SpellAbility ab);
|
||||
|
||||
void selectPlayer(Player player, ITriggerEvent triggerEvent);
|
||||
|
||||
@@ -17,9 +17,13 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.events.UiEventAttackerDeclared;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
@@ -31,13 +35,9 @@ import forge.game.combat.Combat;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* InputAttack class.
|
||||
@@ -56,7 +56,8 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
private final Player playerAttacks;
|
||||
private AttackingBand activeBand = null;
|
||||
|
||||
public InputAttack(Player attacks0, Combat combat0) {
|
||||
public InputAttack(PlayerControllerHuman controller, Player attacks0, Combat combat0) {
|
||||
super(controller);
|
||||
playerAttacks = attacks0;
|
||||
combat = combat0;
|
||||
defenders = combat.getDefenders();
|
||||
@@ -77,7 +78,9 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
List<Pair<Card, GameEntity>> mandatoryAttackers = CombatUtil.getMandatoryAttackers(playerAttacks, combat, defenders);
|
||||
for (Pair<Card, GameEntity> attacker : mandatoryAttackers) {
|
||||
combat.addAttacker(attacker.getLeft(), attacker.getRight());
|
||||
GuiBase.getInterface().fireEvent(new UiEventAttackerDeclared(attacker.getLeft(), attacker.getRight()));
|
||||
getGui().fireEvent(new UiEventAttackerDeclared(
|
||||
getController().getCardView(attacker.getLeft()),
|
||||
getController().getGameEntityView(attacker.getRight())));
|
||||
}
|
||||
updateMessage();
|
||||
}
|
||||
@@ -94,10 +97,10 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
|
||||
private void updatePrompt() {
|
||||
if (canCallBackAttackers()) {
|
||||
ButtonUtil.update("OK", "Call Back", true, true, true);
|
||||
ButtonUtil.update(getGui(), "OK", "Call Back", true, true, true);
|
||||
}
|
||||
else {
|
||||
ButtonUtil.update("OK", "Alpha Strike", true, true, true);
|
||||
ButtonUtil.update(getGui(), "OK", "Alpha Strike", true, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +228,9 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
combat.addAttacker(card, currentDefender, activeBand);
|
||||
activateBand(activeBand);
|
||||
|
||||
GuiBase.getInterface().fireEvent(new UiEventAttackerDeclared(card, currentDefender));
|
||||
getGui().fireEvent(new UiEventAttackerDeclared(
|
||||
getController().getCardView(card),
|
||||
getController().getGameEntityView(currentDefender)));
|
||||
}
|
||||
|
||||
private boolean canUndeclareAttacker(Card card) {
|
||||
@@ -238,49 +243,50 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
if (canUndeclareAttacker(card)) {
|
||||
// TODO Is there no way to attacks each turn cards to attack Planeswalkers?
|
||||
combat.removeFromCombat(card);
|
||||
GuiBase.getInterface().setUsedToPay(card, false);
|
||||
getGui().setUsedToPay(getController().getCardView(card), false);
|
||||
// When removing an attacker clear the attacking band
|
||||
activateBand(null);
|
||||
|
||||
GuiBase.getInterface().fireEvent(new UiEventAttackerDeclared(card, null));
|
||||
getGui().fireEvent(new UiEventAttackerDeclared(
|
||||
getController().getCardView(card), null));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private final void setCurrentDefender(GameEntity def) {
|
||||
private final void setCurrentDefender(final GameEntity def) {
|
||||
currentDefender = def;
|
||||
for (GameEntity ge : defenders) {
|
||||
for (final GameEntity ge : defenders) {
|
||||
if (ge instanceof Card) {
|
||||
GuiBase.getInterface().setUsedToPay((Card)ge, ge == def);
|
||||
getGui().setUsedToPay(getController().getCardView((Card) ge), ge == def);
|
||||
}
|
||||
else if (ge instanceof Player) {
|
||||
GuiBase.getInterface().setHighlighted((Player) ge, ge == def);
|
||||
getGui().setHighlighted(getController().getPlayerView((Player) ge), ge == def);
|
||||
}
|
||||
}
|
||||
|
||||
updateMessage();
|
||||
}
|
||||
|
||||
private final void activateBand(AttackingBand band) {
|
||||
private final void activateBand(final AttackingBand band) {
|
||||
if (activeBand != null) {
|
||||
for (Card card : activeBand.getAttackers()) {
|
||||
GuiBase.getInterface().setUsedToPay(card, false);
|
||||
for (final Card card : activeBand.getAttackers()) {
|
||||
getGui().setUsedToPay(getController().getCardView(card), false);
|
||||
}
|
||||
}
|
||||
activeBand = band;
|
||||
|
||||
if (activeBand != null) {
|
||||
for(Card card : activeBand.getAttackers()) {
|
||||
GuiBase.getInterface().setUsedToPay(card, true);
|
||||
for (final Card card : activeBand.getAttackers()) {
|
||||
getGui().setUsedToPay(getController().getCardView(card), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//only enable banding message and actions if a creature that can attack has banding
|
||||
private boolean isBandingPossible() {
|
||||
List<Card> possibleAttackers = playerAttacks.getCardsIn(ZoneType.Battlefield);
|
||||
for (Card c : Iterables.filter(possibleAttackers, CardPredicates.hasKeyword("Banding"))) {
|
||||
final List<Card> possibleAttackers = playerAttacks.getCardsIn(ZoneType.Battlefield);
|
||||
for (final Card c : Iterables.filter(possibleAttackers, CardPredicates.hasKeyword("Banding"))) {
|
||||
if (c.isCreature() && CombatUtil.canAttack(c, currentDefender, combat)) {
|
||||
return true;
|
||||
}
|
||||
@@ -296,6 +302,6 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
showMessage(message);
|
||||
|
||||
updatePrompt();
|
||||
GuiBase.getInterface().showCombat(combat); // redraw sword icons
|
||||
getGui().showCombat(getController().getCombat(combat)); // redraw sword icons
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,13 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
/**
|
||||
@@ -40,13 +41,25 @@ import forge.util.ITriggerEvent;
|
||||
public abstract class InputBase implements java.io.Serializable, Input {
|
||||
/** Constant <code>serialVersionUID=-6539552513871194081L</code>. */
|
||||
private static final long serialVersionUID = -6539552513871194081L;
|
||||
|
||||
private final PlayerControllerHuman controller;
|
||||
public InputBase(final PlayerControllerHuman controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
public final PlayerControllerHuman getController() {
|
||||
return this.controller;
|
||||
}
|
||||
public IGuiBase getGui() {
|
||||
return getController().getGui();
|
||||
}
|
||||
|
||||
private boolean finished = false;
|
||||
protected final boolean isFinished() { return finished; }
|
||||
protected final void setFinished() {
|
||||
finished = true;
|
||||
|
||||
if (allowAwaitNextInput()) {
|
||||
awaitNextInput();
|
||||
awaitNextInput(getGui());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,18 +70,18 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
private static final Timer awaitNextInputTimer = new Timer();
|
||||
private static TimerTask awaitNextInputTask;
|
||||
|
||||
public static void awaitNextInput() {
|
||||
public static void awaitNextInput(final IGuiBase gui) {
|
||||
//delay updating prompt to await next input briefly so buttons don't flicker disabled then enabled
|
||||
awaitNextInputTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
FThreads.invokeInEdtLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (awaitNextInputTimer) {
|
||||
if (awaitNextInputTask != null) {
|
||||
GuiBase.getInterface().showPromptMessage("Waiting for opponent...");
|
||||
ButtonUtil.update(false, false, false);
|
||||
gui.showPromptMessage("Waiting for opponent...");
|
||||
ButtonUtil.update(gui, false, false, false);
|
||||
awaitNextInputTask = null;
|
||||
}
|
||||
}
|
||||
@@ -108,7 +121,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectAbility(SpellAbility ab) { }
|
||||
public void selectAbility(final SpellAbility ab) { }
|
||||
|
||||
@Override
|
||||
public final void selectButtonCancel() {
|
||||
@@ -131,20 +144,20 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
protected boolean onCardSelected(final Card c, final ITriggerEvent triggerEvent) {
|
||||
return false;
|
||||
}
|
||||
protected void onPlayerSelected(final Player p, final ITriggerEvent triggerEvent) {}
|
||||
protected void onPlayerSelected(final Player player, final ITriggerEvent triggerEvent) {}
|
||||
protected void onCancel() {}
|
||||
protected void onOk() {}
|
||||
|
||||
// to remove need for CMatchUI dependence
|
||||
protected final void showMessage(String message) {
|
||||
GuiBase.getInterface().showPromptMessage(message);
|
||||
protected final void showMessage(final String message) {
|
||||
getGui().showPromptMessage(message);
|
||||
}
|
||||
|
||||
protected final void flashIncorrectAction() {
|
||||
GuiBase.getInterface().flashIncorrectAction();
|
||||
getGui().flashIncorrectAction();
|
||||
}
|
||||
|
||||
protected String getTurnPhasePriorityMessage(Game game) {
|
||||
protected String getTurnPhasePriorityMessage(final Game game) {
|
||||
final PhaseHandler ph = game.getPhaseHandler();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package forge.match.input;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.events.UiEventBlockerAssigned;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
@@ -27,9 +26,11 @@ import forge.game.combat.Combat;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.ThreadUtil;
|
||||
import forge.util.gui.SGuiDialog;
|
||||
import forge.view.CardView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -48,7 +49,8 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
private final Combat combat;
|
||||
private final Player defender;
|
||||
|
||||
public InputBlock(Player defender0, Combat combat0) {
|
||||
public InputBlock(final PlayerControllerHuman controller, final Player defender0, final Combat combat0) {
|
||||
super(controller);
|
||||
defender = defender0;
|
||||
combat = combat0;
|
||||
|
||||
@@ -56,7 +58,7 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
for (final Card attacker : combat.getAttackers()) {
|
||||
for (final Card c : CardLists.filter(defender.getCardsIn(ZoneType.Battlefield), Presets.CREATURES)) {
|
||||
if (CombatUtil.canBlock(attacker, c, combat)) {
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() { //must set current attacker on EDT
|
||||
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() { //must set current attacker on EDT
|
||||
@Override
|
||||
public void run() {
|
||||
setCurrentAttacker(attacker);
|
||||
@@ -72,7 +74,7 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
@Override
|
||||
protected final void showMessage() {
|
||||
// could add "Reset Blockers" button
|
||||
ButtonUtil.update(true, false, true);
|
||||
ButtonUtil.update(getGui(), true, false, true);
|
||||
|
||||
if (currentAttacker == null) {
|
||||
showMessage("Select another attacker to declare blockers for.");
|
||||
@@ -83,7 +85,7 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
showMessage(message);
|
||||
}
|
||||
|
||||
GuiBase.getInterface().showCombat(combat);
|
||||
getGui().showCombat(getController().getCombat(combat));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -95,12 +97,12 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
setCurrentAttacker(null);
|
||||
stop();
|
||||
}
|
||||
else {
|
||||
else {
|
||||
//must run in game thread to prevent problems for mobile game
|
||||
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SGuiDialog.message(blockErrors);
|
||||
SGuiDialog.message(getGui(), blockErrors);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -112,7 +114,8 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
boolean isCorrectAction = false;
|
||||
if (triggerEvent != null && triggerEvent.getButton() == 3 && card.getController() == defender) {
|
||||
combat.removeFromCombat(card);
|
||||
GuiBase.getInterface().fireEvent(new UiEventBlockerAssigned(card, (Card)null));
|
||||
getGui().fireEvent(new UiEventBlockerAssigned(
|
||||
getController().getCardView(card), (CardView) null));
|
||||
isCorrectAction = true;
|
||||
}
|
||||
else {
|
||||
@@ -127,14 +130,17 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
if (combat.isBlocking(card, currentAttacker)) {
|
||||
//if creature already blocking current attacker, remove blocker from combat
|
||||
combat.removeBlockAssignment(currentAttacker, card);
|
||||
GuiBase.getInterface().fireEvent(new UiEventBlockerAssigned(card, (Card)null));
|
||||
getGui().fireEvent(new UiEventBlockerAssigned(
|
||||
getController().getCardView(card), (CardView) null));
|
||||
isCorrectAction = true;
|
||||
}
|
||||
else {
|
||||
isCorrectAction = CombatUtil.canBlock(currentAttacker, card, combat);
|
||||
if (isCorrectAction) {
|
||||
combat.addBlocker(currentAttacker, card);
|
||||
GuiBase.getInterface().fireEvent(new UiEventBlockerAssigned(card, currentAttacker));
|
||||
getGui().fireEvent(new UiEventBlockerAssigned(
|
||||
getController().getCardView(card),
|
||||
getController().getCardView(currentAttacker)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,10 +154,10 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
return isCorrectAction;
|
||||
}
|
||||
|
||||
private void setCurrentAttacker(Card card) {
|
||||
private void setCurrentAttacker(final Card card) {
|
||||
currentAttacker = card;
|
||||
for (Card c : combat.getAttackers()) {
|
||||
GuiBase.getInterface().setUsedToPay(c, card == c);
|
||||
for (final Card c : combat.getAttackers()) {
|
||||
getGui().setUsedToPay(getController().getCardView(c), card == c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.player.PlayerControllerHuman;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* InputConfirm class.
|
||||
@@ -34,15 +36,16 @@ public class InputConfirm extends InputSyncronizedBase {
|
||||
private final boolean defaultYes;
|
||||
private boolean result;
|
||||
|
||||
public InputConfirm(String message0) {
|
||||
this(message0, "Yes", "No", true);
|
||||
public InputConfirm(final PlayerControllerHuman controller, String message0) {
|
||||
this(controller, message0, "Yes", "No", true);
|
||||
}
|
||||
|
||||
public InputConfirm(String message0, String yesButtonText0, String noButtonText0) {
|
||||
this(message0, yesButtonText0, noButtonText0, true);
|
||||
public InputConfirm(final PlayerControllerHuman controller, String message0, String yesButtonText0, String noButtonText0) {
|
||||
this(controller, message0, yesButtonText0, noButtonText0, true);
|
||||
}
|
||||
|
||||
public InputConfirm(String message0, String yesButtonText0, String noButtonText0, boolean defaultYes0) {
|
||||
public InputConfirm(final PlayerControllerHuman controller, String message0, String yesButtonText0, String noButtonText0, boolean defaultYes0) {
|
||||
super(controller);
|
||||
message = message0;
|
||||
yesButtonText = yesButtonText0;
|
||||
noButtonText = noButtonText0;
|
||||
@@ -53,7 +56,7 @@ public class InputConfirm extends InputSyncronizedBase {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected final void showMessage() {
|
||||
ButtonUtil.update(yesButtonText, noButtonText, true, true, defaultYes);
|
||||
ButtonUtil.update(getGui(), yesButtonText, noButtonText, true, true, defaultYes);
|
||||
showMessage(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,18 +17,19 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.GuiBase;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.Lang;
|
||||
import forge.util.ThreadUtil;
|
||||
import forge.util.gui.SGuiDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import forge.view.CardView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -49,7 +50,8 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
private final Player player;
|
||||
private final Player startingPlayer;
|
||||
|
||||
public InputConfirmMulligan(Player humanPlayer, Player startsGame, boolean commander) {
|
||||
public InputConfirmMulligan(final PlayerControllerHuman controller, final Player humanPlayer, final Player startsGame, final boolean commander) {
|
||||
super(controller);
|
||||
player = humanPlayer;
|
||||
isCommander = commander;
|
||||
startingPlayer = startsGame;
|
||||
@@ -70,11 +72,11 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
}
|
||||
|
||||
if (isCommander) {
|
||||
ButtonUtil.update("Keep", "Exile", true, false, true);
|
||||
ButtonUtil.update(getGui(), "Keep", "Exile", true, false, true);
|
||||
sb.append("Will you keep your hand or choose some cards to exile those and draw one less card?");
|
||||
}
|
||||
else {
|
||||
ButtonUtil.update("Keep", "Mulligan", true, true, true);
|
||||
ButtonUtil.update(getGui(), "Keep", "Mulligan", true, true, true);
|
||||
sb.append("Do you want to keep your hand?");
|
||||
}
|
||||
|
||||
@@ -98,8 +100,8 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
private void done() {
|
||||
if (isCommander) {
|
||||
// Clear the "selected" icon after clicking the done button
|
||||
for (Card c : this.selected) {
|
||||
GuiBase.getInterface().setUsedToPay(c, false);
|
||||
for (final Card c : this.selected) {
|
||||
getGui().setUsedToPay(getController().getCardView(c), false);
|
||||
}
|
||||
}
|
||||
stop();
|
||||
@@ -117,7 +119,8 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSerumPowder && SGuiDialog.confirm(c0, "Use " + c0.getName() + "'s ability?")) {
|
||||
final CardView cView = getController().getCardView(c0);
|
||||
if (isSerumPowder && SGuiDialog.confirm(getGui(), cView, "Use " + cView + "'s ability?")) {
|
||||
cardSelectLocked = true;
|
||||
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||
public void run() {
|
||||
@@ -134,14 +137,14 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
|
||||
|
||||
if (isCommander) { // allow to choose cards for partial paris
|
||||
if (selected.contains(c0)) {
|
||||
GuiBase.getInterface().setUsedToPay(c0, false);
|
||||
getGui().setUsedToPay(getController().getCardView(c0), false);
|
||||
selected.remove(c0);
|
||||
}
|
||||
else {
|
||||
GuiBase.getInterface().setUsedToPay(c0, true);
|
||||
getGui().setUsedToPay(getController().getCardView(c0), true);
|
||||
selected.add(c0);
|
||||
}
|
||||
ButtonUtil.update("Keep", "Exile", true, !selected.isEmpty(), true);
|
||||
ButtonUtil.update(getGui(), "Keep", "Exile", true, !selected.isEmpty(), true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
package forge.match.input;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.ThreadUtil;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
public class InputLockUI implements Input {
|
||||
private final AtomicInteger iCall = new AtomicInteger();
|
||||
|
||||
public InputLockUI(InputQueue inputQueue) {
|
||||
private IGuiBase gui;
|
||||
private final Game game;
|
||||
public InputLockUI(final Game game, final InputQueue inputQueue) {
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
private IGuiBase getGui() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public void setGui(final IGuiBase gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
public void showMessageInitial() {
|
||||
@@ -39,24 +49,24 @@ public class InputLockUI implements Input {
|
||||
public void run() {
|
||||
if ( ixCall != iCall.get() || !isActive()) // cancel the message if it's not from latest call or input is gone already
|
||||
return;
|
||||
FThreads.invokeInEdtLater(showMessageFromEdt);
|
||||
FThreads.invokeInEdtLater(getGui(), showMessageFromEdt);
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable showMessageFromEdt = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ButtonUtil.update("", "", false, false, false);
|
||||
ButtonUtil.update(getGui(), "", "", false, false, false);
|
||||
showMessage("Waiting for actions...");
|
||||
}
|
||||
};
|
||||
|
||||
protected final boolean isActive() {
|
||||
return GuiBase.getInterface().getInputQueue().getInput() == this;
|
||||
return getGui().getInputQueue().getInput() == this;
|
||||
}
|
||||
|
||||
protected void showMessage(String message) {
|
||||
GuiBase.getInterface().showPromptMessage(message);
|
||||
getGui().showPromptMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,7 +85,6 @@ public class InputLockUI implements Input {
|
||||
@Override
|
||||
public void selectButtonCancel() {
|
||||
//cancel auto pass for all players
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
for (Player player : game.getPlayers()) {
|
||||
player.getController().autoPassCancel();
|
||||
}
|
||||
|
||||
@@ -17,21 +17,19 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.GuiBase;
|
||||
import java.util.List;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.match.MatchUtil;
|
||||
import forge.model.FModel;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.ThreadUtil;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Input_PassPriority class.
|
||||
@@ -47,7 +45,8 @@ public class InputPassPriority extends InputSyncronizedBase {
|
||||
|
||||
private SpellAbility chosenSa;
|
||||
|
||||
public InputPassPriority(Player human) {
|
||||
public InputPassPriority(final PlayerControllerHuman controller, final Player human) {
|
||||
super(controller);
|
||||
player = human;
|
||||
}
|
||||
|
||||
@@ -56,11 +55,11 @@ public class InputPassPriority extends InputSyncronizedBase {
|
||||
public final void showMessage() {
|
||||
showMessage(getTurnPhasePriorityMessage(player.getGame()));
|
||||
chosenSa = null;
|
||||
if (MatchUtil.canUndoLastAction()) { //allow undoing with cancel button if can undo last action
|
||||
ButtonUtil.update("OK", "Undo", true, true, true);
|
||||
if (getController().canUndoLastAction()) { //allow undoing with cancel button if can undo last action
|
||||
ButtonUtil.update(getGui(), "OK", "Undo", true, true, true);
|
||||
}
|
||||
else { //otherwise allow ending turn with cancel button
|
||||
ButtonUtil.update("OK", "End Turn", true, true, true);
|
||||
ButtonUtil.update(getGui(), "OK", "End Turn", true, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,12 +77,12 @@ public class InputPassPriority extends InputSyncronizedBase {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected final void onCancel() {
|
||||
if (!MatchUtil.undoLastAction()) { //undo if possible
|
||||
if (!getController().tryUndoLastAction()) { //undo if possible
|
||||
//otherwise end turn
|
||||
passPriority(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.getController().autoPassUntil(PhaseType.CLEANUP);
|
||||
player.getController().autoPassUntilEndOfTurn();
|
||||
stop();
|
||||
}
|
||||
});
|
||||
@@ -98,10 +97,10 @@ public class InputPassPriority extends InputSyncronizedBase {
|
||||
private void passPriority(final Runnable runnable) {
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.UI_MANA_LOST_PROMPT)) {
|
||||
//if gui player has mana floating that will be lost if phase ended right now, prompt before passing priority
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
final Game game = player.getGame();
|
||||
if (game.getStack().isEmpty()) { //phase can't end right now if stack isn't empty
|
||||
Player player = game.getPhaseHandler().getPriorityPlayer();
|
||||
if (player != null && player.getManaPool().willManaBeLostAtEndOfPhase() && player.getLobbyPlayer() == GuiBase.getInterface().getGuiPlayer()) {
|
||||
if (player != null && player.getManaPool().willManaBeLostAtEndOfPhase() && player.getLobbyPlayer() == getGui().getGuiPlayer()) {
|
||||
ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread so dialog can be shown on mobile game
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -109,7 +108,7 @@ public class InputPassPriority extends InputSyncronizedBase {
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)) {
|
||||
message += " You will take mana burn damage equal to the amount of floating mana lost this way.";
|
||||
}
|
||||
if (SOptionPane.showOptionDialog(message, "Mana Floating", SOptionPane.WARNING_ICON, new String[]{"OK", "Cancel"}) == 0) {
|
||||
if (SOptionPane.showOptionDialog(getGui(), message, "Mana Floating", SOptionPane.WARNING_ICON, new String[]{"OK", "Cancel"}) == 0) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package forge.match.input;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.ai.ComputerUtilMana;
|
||||
import forge.ai.PlayerControllerAi;
|
||||
import forge.card.ColorSet;
|
||||
@@ -17,16 +22,11 @@ import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.spellability.AbilityManaPart;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.player.HumanPlay;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.Evaluator;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public abstract class InputPayMana extends InputSyncronizedBase {
|
||||
private static final long serialVersionUID = -9133423708688480255L;
|
||||
@@ -45,20 +45,21 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
||||
|
||||
private boolean locked = false;
|
||||
|
||||
protected InputPayMana(SpellAbility saPaidFor0, Player player0) {
|
||||
protected InputPayMana(final PlayerControllerHuman controller, final SpellAbility saPaidFor0, final Player player0) {
|
||||
super(controller);
|
||||
player = player0;
|
||||
game = player.getGame();
|
||||
saPaidFor = saPaidFor0;
|
||||
|
||||
//if player is floating mana, show mana pool to make it easier to use that mana
|
||||
wasFloatingMana = !player.getManaPool().isEmpty();
|
||||
zoneToRestore = wasFloatingMana ? GuiBase.getInterface().showManaPool(player) : null;
|
||||
zoneToRestore = wasFloatingMana ? getGui().showManaPool(getController().getPlayerView(player)) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
if (wasFloatingMana) { //hide mana pool if it was shown due to floating mana
|
||||
GuiBase.getInterface().hideManaPool(player, zoneToRestore);
|
||||
getGui().hideManaPool(getController().getPlayerView(player), zoneToRestore);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +245,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
||||
|
||||
final SpellAbility chosen;
|
||||
if (chosenAbility == null) {
|
||||
chosen = abilities.size() > 1 && choice ? SGuiChoose.one("Choose mana ability", abilities) : abilities.get(0);
|
||||
chosen = abilities.size() > 1 && choice ? SGuiChoose.one(getGui(), "Choose mana ability", abilities) : abilities.get(0);
|
||||
}
|
||||
else {
|
||||
chosen = chosenAbility;
|
||||
@@ -256,7 +257,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
||||
Runnable proc = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
HumanPlay.playSpellAbility(chosen.getActivatingPlayer(), chosen);
|
||||
HumanPlay.playSpellAbility(getController(), chosen.getActivatingPlayer(), chosen);
|
||||
player.getManaPool().payManaFromAbility(saPaidFor, InputPayMana.this.manaCost, chosen);
|
||||
|
||||
onManaAbilityPaid();
|
||||
@@ -370,10 +371,10 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
||||
|
||||
protected void updateButtons() {
|
||||
if (supportAutoPay()) {
|
||||
ButtonUtil.update("Auto", "Cancel", false, true, false);
|
||||
ButtonUtil.update(getGui(), "Auto", "Cancel", false, true, false);
|
||||
}
|
||||
else {
|
||||
ButtonUtil.update("", "Cancel", false, true, false);
|
||||
ButtonUtil.update(getGui(), "", "Cancel", false, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +393,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
||||
canPayManaCost = proc.getResult();
|
||||
}
|
||||
if (canPayManaCost) { //enabled Auto button if mana cost can be paid
|
||||
ButtonUtil.update("Auto", "Cancel", true, true, true);
|
||||
ButtonUtil.update(getGui(), "Auto", "Cancel", true, true, true);
|
||||
}
|
||||
}
|
||||
showMessage(getMessage());
|
||||
@@ -412,7 +413,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
||||
stop();
|
||||
}
|
||||
else {
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateMessage();
|
||||
|
||||
@@ -4,11 +4,12 @@ import forge.game.card.Card;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
public class InputPayManaOfCostPayment extends InputPayMana {
|
||||
public InputPayManaOfCostPayment(ManaCostBeingPaid cost, SpellAbility spellAbility, Player payer) {
|
||||
super(spellAbility, payer);
|
||||
public InputPayManaOfCostPayment(final PlayerControllerHuman controller, ManaCostBeingPaid cost, SpellAbility spellAbility, Player payer) {
|
||||
super(controller, spellAbility, payer);
|
||||
manaCost = cost;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import forge.game.card.Card;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
//pays the cost of a card played from the player's hand
|
||||
@@ -36,8 +37,8 @@ public class InputPayManaSimple extends InputPayMana {
|
||||
private final Card originalCard;
|
||||
private final ManaCost originalManaCost;
|
||||
|
||||
public InputPayManaSimple(final Game game, final SpellAbility sa, final ManaCostBeingPaid manaCostToPay) {
|
||||
super(sa, sa.getActivatingPlayer());
|
||||
public InputPayManaSimple(final PlayerControllerHuman controller, final Game game, final SpellAbility sa, final ManaCostBeingPaid manaCostToPay) {
|
||||
super(controller, sa, sa.getActivatingPlayer());
|
||||
this.originalManaCost = manaCostToPay.toManaCost();
|
||||
this.originalCard = sa.getHostCard();
|
||||
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
package forge.match.input;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.control.FControlGamePlayback;
|
||||
import forge.game.Game;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
|
||||
public class InputPlaybackControl extends InputSyncronizedBase implements InputSynchronized {
|
||||
private static final long serialVersionUID = 7979208993306642072L;
|
||||
|
||||
FControlGamePlayback control;
|
||||
final FControlGamePlayback control;
|
||||
|
||||
private boolean isPaused = false;
|
||||
private boolean isFast = false;
|
||||
|
||||
public InputPlaybackControl(FControlGamePlayback fControlGamePlayback) {
|
||||
private final IGuiBase gui;
|
||||
private final Game game;
|
||||
public InputPlaybackControl(final IGuiBase gui, final Game game, final FControlGamePlayback fControlGamePlayback) {
|
||||
super(null);
|
||||
this.gui = gui;
|
||||
this.game = game;
|
||||
control = fControlGamePlayback;
|
||||
setPause(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGuiBase getGui() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -29,7 +39,6 @@ public class InputPlaybackControl extends InputSyncronizedBase implements InputS
|
||||
//update message based on current turn and paused state
|
||||
private int currentTurn;
|
||||
public void updateTurnMessage() {
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
if (isPaused) {
|
||||
showMessage(getTurnPhasePriorityMessage(game));
|
||||
currentTurn = 0;
|
||||
@@ -46,10 +55,10 @@ public class InputPlaybackControl extends InputSyncronizedBase implements InputS
|
||||
private void setPause(boolean pause) {
|
||||
isPaused = pause;
|
||||
if (isPaused) {
|
||||
ButtonUtil.update("Resume", "Step", true, true, true);
|
||||
ButtonUtil.update(getGui(), "Resume", "Step", true, true, true);
|
||||
}
|
||||
else {
|
||||
ButtonUtil.update("Pause", isFast ? "1x Speed" : "10x Faster", true, true, true);
|
||||
ButtonUtil.update(getGui(), "Pause", isFast ? "1x Speed" : "10x Faster", true, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
package forge.match.input;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.player.Player;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public final class InputProliferate extends InputSelectManyBase<GameEntity> {
|
||||
private static final long serialVersionUID = -1779224307654698954L;
|
||||
private Map<GameEntity, CounterType> chosenCounters = new HashMap<GameEntity, CounterType>();
|
||||
|
||||
public InputProliferate() {
|
||||
super(1, Integer.MAX_VALUE);
|
||||
public InputProliferate(final PlayerControllerHuman controller) {
|
||||
super(controller, 1, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
protected String getMessage() {
|
||||
@@ -57,7 +61,7 @@ public final class InputProliferate extends InputSelectManyBase<GameEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
CounterType toAdd = choices.size() == 1 ? choices.get(0) : SGuiChoose.one("Select counter type", choices);
|
||||
CounterType toAdd = choices.size() == 1 ? choices.get(0) : SGuiChoose.one(getGui(), "Select counter type", choices);
|
||||
chosenCounters.put(card, toAdd);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,20 +17,20 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.game.Game;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.view.CardView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.SpellAbilityView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* GuiInput class.
|
||||
@@ -43,32 +43,40 @@ public class InputProxy implements Observer {
|
||||
|
||||
/** The input. */
|
||||
private AtomicReference<Input> input = new AtomicReference<Input>();
|
||||
private Game game = null;
|
||||
private final Game game;
|
||||
|
||||
// private static final boolean DEBUG_INPUT = true; // false;
|
||||
|
||||
public void setGame(Game game0) {
|
||||
game = game0;
|
||||
GuiBase.getInterface().getInputQueue().addObserver(this);
|
||||
|
||||
private final PlayerControllerHuman controller;
|
||||
public InputProxy(final PlayerControllerHuman controller, final Game game) {
|
||||
this.controller = controller;
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
public boolean passPriority() {
|
||||
return passPriority(null, null);
|
||||
private IGuiBase getGui() {
|
||||
return this.controller.getGui();
|
||||
}
|
||||
public boolean passPriority(Player p, PhaseType autoPassUntilPhase) {
|
||||
Input inp = getInput();
|
||||
if (inp != null && inp instanceof InputPassPriority) {
|
||||
if (p != null && autoPassUntilPhase != null) {
|
||||
p.getController().autoPassUntil(autoPassUntilPhase);
|
||||
|
||||
public boolean passPriority() {
|
||||
return passPriority(false);
|
||||
}
|
||||
public boolean passPriorityUntilEndOfTurn() {
|
||||
return passPriority(true);
|
||||
}
|
||||
private boolean passPriority(final boolean passUntilEndOfTurn) {
|
||||
final Input inp = getInput();
|
||||
if (inp instanceof InputPassPriority) {
|
||||
if (passUntilEndOfTurn) {
|
||||
controller.autoPassUntilEndOfTurn();
|
||||
}
|
||||
inp.selectButtonOK();
|
||||
return true;
|
||||
}
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SOptionPane.showMessageDialog("Cannot pass priority at this time.");
|
||||
SOptionPane.showMessageDialog(getGui(), "Cannot pass priority at this time.");
|
||||
}
|
||||
});
|
||||
return false;
|
||||
@@ -76,8 +84,7 @@ public class InputProxy implements Observer {
|
||||
|
||||
@Override
|
||||
public final void update(final Observable observable, final Object obj) {
|
||||
final Input nextInput = GuiBase.getInterface().getInputQueue().getActualInput(game);
|
||||
|
||||
final Input nextInput = getGui().getInputQueue().getActualInput(game);
|
||||
/* if(DEBUG_INPUT)
|
||||
System.out.printf("%s ... \t%s on %s, \tstack = %s%n",
|
||||
FThreads.debugGetStackTraceItem(6, true), nextInput == null ? "null" : nextInput.getClass().getSimpleName(),
|
||||
@@ -87,13 +94,13 @@ public class InputProxy implements Observer {
|
||||
Runnable showMessage = new Runnable() {
|
||||
@Override public void run() {
|
||||
Input current = getInput();
|
||||
GuiBase.getInterface().getInputQueue().syncPoint();
|
||||
getGui().getInputQueue().syncPoint();
|
||||
//System.out.printf("\t%s > showMessage @ %s/%s during %s%n", FThreads.debugGetCurrThreadId(), nextInput.getClass().getSimpleName(), current.getClass().getSimpleName(), game.getPhaseHandler().debugPrintState());
|
||||
current.showMessageInitial();
|
||||
}
|
||||
};
|
||||
|
||||
FThreads.invokeInEdtLater(showMessage);
|
||||
FThreads.invokeInEdtLater(getGui(), showMessage);
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
@@ -127,10 +134,10 @@ public class InputProxy implements Observer {
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
*/
|
||||
public final void selectPlayer(final Player player, final ITriggerEvent triggerEvent) {
|
||||
Input inp = getInput();
|
||||
public final void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
inp.selectPlayer(player, triggerEvent);
|
||||
inp.selectPlayer(controller.getPlayer(player), triggerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,22 +146,22 @@ public class InputProxy implements Observer {
|
||||
* selectCard.
|
||||
* </p>
|
||||
*
|
||||
* @param card
|
||||
* @param cardView
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @param triggerEvent
|
||||
*/
|
||||
public final boolean selectCard(final Card card, final ITriggerEvent triggerEvent) {
|
||||
Input inp = getInput();
|
||||
public final boolean selectCard(final CardView cardView, final ITriggerEvent triggerEvent) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
return inp.selectCard(card, triggerEvent);
|
||||
return inp.selectCard(controller.getCard(cardView), triggerEvent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final void selectAbility(SpellAbility ab) {
|
||||
Input inp = getInput();
|
||||
public final void selectAbility(final SpellAbilityView ab) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
inp.selectAbility(ab);
|
||||
inp.selectAbility(controller.getSpellAbility(ab));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.game.Game;
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* InputControl class.
|
||||
@@ -34,8 +37,13 @@ public class InputQueue extends Observable {
|
||||
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
|
||||
private final InputLockUI inputLock;
|
||||
|
||||
public InputQueue() {
|
||||
inputLock = new InputLockUI(this);
|
||||
public InputQueue(final Game game) {
|
||||
inputLock = new InputLockUI(game, this);
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (p.getController() instanceof PlayerControllerHuman) {
|
||||
this.addObserver(((PlayerControllerHuman) p.getController()).getInputProxy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void updateObservers() {
|
||||
@@ -63,7 +71,7 @@ public class InputQueue extends Observable {
|
||||
*
|
||||
* @return a {@link forge.gui.input.InputBase} object.
|
||||
*/
|
||||
public final Input getActualInput(Game game) {
|
||||
public final Input getActualInput(final Game game) {
|
||||
Input topMost = inputStack.peek(); // incoming input to Control
|
||||
if (topMost != null && !game.isGameOver()) {
|
||||
return topMost;
|
||||
@@ -76,8 +84,9 @@ public class InputQueue extends Observable {
|
||||
return inputStack.toString();
|
||||
}
|
||||
|
||||
public void setInput(InputSynchronized input) {
|
||||
public void setInput(final InputSynchronized input) {
|
||||
this.inputStack.push(input);
|
||||
inputLock.setGui(input.getGui());
|
||||
syncPoint();
|
||||
this.updateObservers();
|
||||
}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package forge.match.input;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostShard;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
import forge.game.player.Player;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card> {
|
||||
private static final long serialVersionUID = -1779224307654698954L;
|
||||
@@ -24,8 +25,8 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card>
|
||||
private final Player player;
|
||||
private final List<Card> availableCreatures;
|
||||
|
||||
public InputSelectCardsForConvoke(Player p, ManaCost cost, List<Card> untapped) {
|
||||
super(0, Math.min(cost.getCMC(), untapped.size()));
|
||||
public InputSelectCardsForConvoke(final PlayerControllerHuman controller, final Player p, final ManaCost cost, final List<Card> untapped) {
|
||||
super(controller, 0, Math.min(cost.getCMC(), untapped.size()));
|
||||
remainingCost = new ManaCostBeingPaid(cost);
|
||||
player = p;
|
||||
availableCreatures = untapped;
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package forge.match.input;
|
||||
|
||||
import forge.game.card.Card;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
|
||||
public class InputSelectCardsFromList extends InputSelectEntitiesFromList<Card> {
|
||||
private static final long serialVersionUID = 6230360322294805986L;
|
||||
|
||||
public InputSelectCardsFromList(int cnt, Collection<Card> validCards) {
|
||||
super(cnt, cnt, validCards); // to avoid hangs
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final int cnt, final Collection<Card> validCards) {
|
||||
super(controller, cnt, cnt, validCards); // to avoid hangs
|
||||
}
|
||||
|
||||
public InputSelectCardsFromList(int min, int max, Collection<Card> validCards) {
|
||||
super(min, max, validCards); // to avoid hangs
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final int min, final int max, final Collection<Card> validCards) {
|
||||
super(controller, min, max, validCards); // to avoid hangs
|
||||
}
|
||||
|
||||
public InputSelectCardsFromList(Collection<Card> validCards) {
|
||||
super(1, 1, validCards); // to avoid hangs
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final Collection<Card> validCards) {
|
||||
super(controller, 1, 1, validCards); // to avoid hangs
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,23 @@
|
||||
package forge.match.input;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSelectManyBase<T> {
|
||||
private static final long serialVersionUID = -6609493252672573139L;
|
||||
|
||||
private final Collection<T> validChoices;
|
||||
protected final List<T> selected = new ArrayList<T>();
|
||||
|
||||
public InputSelectEntitiesFromList(int min, int max, Collection<T> validChoices) {
|
||||
super(Math.min(min, validChoices.size()), Math.min(max, validChoices.size()));
|
||||
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final Collection<T> validChoices) {
|
||||
super(controller, Math.min(min, validChoices.size()), Math.min(max, validChoices.size()));
|
||||
this.validChoices = validChoices;
|
||||
|
||||
if (min > validChoices.size()) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package forge.match.input;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
|
||||
import java.util.Collection;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
|
||||
public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyncronizedBase {
|
||||
private static final long serialVersionUID = -2305549394512889450L;
|
||||
@@ -18,7 +18,8 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
|
||||
|
||||
protected String message = "Source-Card-Name - Select %d more card(s)";
|
||||
|
||||
protected InputSelectManyBase(int min, int max) {
|
||||
protected InputSelectManyBase(final PlayerControllerHuman controller, final int min, final int max) {
|
||||
super(controller);
|
||||
if (min > max) {
|
||||
throw new IllegalArgumentException("Min must not be greater than Max");
|
||||
}
|
||||
@@ -43,7 +44,7 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
|
||||
@Override
|
||||
public final void showMessage() {
|
||||
showMessage(getMessage());
|
||||
ButtonUtil.update(hasEnoughTargets(), allowCancel, true);
|
||||
ButtonUtil.update(getGui(), hasEnoughTargets(), allowCancel, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,16 +72,16 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
|
||||
this.message = message0;
|
||||
}
|
||||
|
||||
protected void onSelectStateChanged(GameEntity c, boolean newState) {
|
||||
protected void onSelectStateChanged(final GameEntity c, final boolean newState) {
|
||||
if (c instanceof Card) {
|
||||
GuiBase.getInterface().setUsedToPay((Card)c, newState); // UI supports card highlighting though this abstraction-breaking mechanism
|
||||
getGui().setUsedToPay(getController().getCardView((Card) c), newState); // UI supports card highlighting though this abstraction-breaking mechanism
|
||||
}
|
||||
}
|
||||
|
||||
private void resetUsedToPay() {
|
||||
for (GameEntity c : getSelected()) {
|
||||
for (final GameEntity c : getSelected()) {
|
||||
if (c instanceof Card) {
|
||||
GuiBase.getInterface().setUsedToPay((Card)c, false);
|
||||
getGui().setUsedToPay(getController().getCardView((Card) c), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package forge.match.input;
|
||||
|
||||
import forge.GuiBase;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.ApiType;
|
||||
@@ -8,15 +13,10 @@ import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
private final List<Card> choices;
|
||||
@@ -43,7 +43,8 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
* @param sa
|
||||
* @param mandatory
|
||||
*/
|
||||
public InputSelectTargets(List<Card> choices, SpellAbility sa, boolean mandatory) {
|
||||
public InputSelectTargets(final PlayerControllerHuman controller, final List<Card> choices, final SpellAbility sa, final boolean mandatory) {
|
||||
super(controller);
|
||||
this.choices = choices;
|
||||
this.tgt = sa.getTargetRestrictions();
|
||||
this.sa = sa;
|
||||
@@ -77,19 +78,19 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
if (!tgt.isMinTargetsChosen(sa.getHostCard(), sa) || tgt.isDividedAsYouChoose()) {
|
||||
if (mandatory && tgt.hasCandidates(sa, true)) {
|
||||
// Player has to click on a target
|
||||
ButtonUtil.update(false, false, false);
|
||||
ButtonUtil.update(getGui(), false, false, false);
|
||||
}
|
||||
else {
|
||||
ButtonUtil.update(false, true, false);
|
||||
ButtonUtil.update(getGui(), false, true, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mandatory && tgt.hasCandidates(sa, true)) {
|
||||
// Player has to click on a target or ok
|
||||
ButtonUtil.update(true, false, true);
|
||||
ButtonUtil.update(getGui(), true, false, true);
|
||||
}
|
||||
else {
|
||||
ButtonUtil.update(true, true, true);
|
||||
ButtonUtil.update(getGui(), true, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,7 +177,7 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(apiBasedMessage);
|
||||
sb.append(card.toString());
|
||||
Integer chosen = SGuiChoose.oneOrNone(sb.toString(), choices);
|
||||
Integer chosen = SGuiChoose.oneOrNone(getGui(), sb.toString(), choices);
|
||||
if (chosen == null) {
|
||||
return true; //still return true since there was a valid choice
|
||||
}
|
||||
@@ -220,7 +221,7 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(apiBasedMessage);
|
||||
sb.append(player.getName());
|
||||
Integer chosen = SGuiChoose.oneOrNone(sb.toString(), choices);
|
||||
Integer chosen = SGuiChoose.oneOrNone(getGui(), sb.toString(), choices);
|
||||
if (null == chosen) {
|
||||
return;
|
||||
}
|
||||
@@ -234,13 +235,13 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
addTarget(player);
|
||||
}
|
||||
|
||||
private void addTarget(GameEntity ge) {
|
||||
private void addTarget(final GameEntity ge) {
|
||||
sa.getTargets().add(ge);
|
||||
if (ge instanceof Card) {
|
||||
GuiBase.getInterface().setUsedToPay((Card) ge, true);
|
||||
getGui().setUsedToPay(getController().getCardView((Card) ge), true);
|
||||
lastTarget = (Card) ge;
|
||||
}
|
||||
Integer val = targetDepth.get(ge);
|
||||
final Integer val = targetDepth.get(ge);
|
||||
targetDepth.put(ge, val == null ? Integer.valueOf(1) : Integer.valueOf(val.intValue() + 1) );
|
||||
|
||||
if(hasAllTargets()) {
|
||||
@@ -252,9 +253,9 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
}
|
||||
|
||||
private void done() {
|
||||
for (GameEntity c : targetDepth.keySet()) {
|
||||
for (final GameEntity c : targetDepth.keySet()) {
|
||||
if (c instanceof Card) {
|
||||
GuiBase.getInterface().setUsedToPay((Card)c, false);
|
||||
getGui().setUsedToPay(getController().getCardView((Card) c), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package forge.match.input;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
|
||||
public interface InputSynchronized extends Input {
|
||||
void awaitLatchRelease();
|
||||
void relaseLatchWhenGameIsOver();
|
||||
IGuiBase getGui();
|
||||
}
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
package forge.match.input;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.error.BugReporter;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.error.BugReporter;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
|
||||
public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized {
|
||||
private static final long serialVersionUID = 8756177361251703052L;
|
||||
private final CountDownLatch cdlDone;
|
||||
|
||||
public InputSyncronizedBase() {
|
||||
public InputSyncronizedBase(final PlayerControllerHuman controller) {
|
||||
super(controller);
|
||||
cdlDone = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void awaitLatchRelease() {
|
||||
FThreads.assertExecutedByEdt(false);
|
||||
FThreads.assertExecutedByEdt(getGui(), false);
|
||||
try{
|
||||
cdlDone.await();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
BugReporter.reportException(e);
|
||||
BugReporter.reportException(e, getGui());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +31,7 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
||||
|
||||
|
||||
public void showAndWait() {
|
||||
GuiBase.getInterface().getInputQueue().setInput(this);
|
||||
getGui().getInputQueue().setInput(this);
|
||||
awaitLatchRelease();
|
||||
}
|
||||
|
||||
@@ -38,7 +39,7 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
||||
onStop();
|
||||
|
||||
// ensure input won't accept any user actions.
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setFinished();
|
||||
@@ -46,7 +47,7 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
||||
});
|
||||
|
||||
// thread irrelevant
|
||||
GuiBase.getInterface().getInputQueue().removeInput(InputSyncronizedBase.this);
|
||||
getGui().getInputQueue().removeInput(InputSyncronizedBase.this);
|
||||
cdlDone.countDown();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,13 +19,16 @@ package forge.model;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.IUnOpenedProduct;
|
||||
import forge.card.UnOpenedProduct;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.TextUtil;
|
||||
import forge.util.storage.StorageReaderFile;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -292,11 +295,13 @@ public final class CardBlock implements Comparable<CardBlock> {
|
||||
* Tries to create a booster for the selected meta-set code.
|
||||
*
|
||||
* @param code
|
||||
* String, the MetaSet code
|
||||
* String, the MetaSet code
|
||||
* @param gui
|
||||
* the {@link IGuiBase} resolving any choices to be made.
|
||||
* @return UnOpenedProduct, the created booster.
|
||||
*/
|
||||
public IUnOpenedProduct getBooster(final String code) {
|
||||
public IUnOpenedProduct getBooster(final String code, final IGuiBase gui) {
|
||||
MetaSet ms = metaSets.get(code);
|
||||
return ms == null ? new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(code)) : ms.getBooster();
|
||||
return ms == null ? new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(code)) : ms.getBooster(gui);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,11 @@ import forge.deck.DeckGroup;
|
||||
import forge.deck.io.DeckGroupSerializer;
|
||||
import forge.deck.io.DeckStorage;
|
||||
import forge.deck.io.OldDeckParser;
|
||||
import forge.interfaces.IGuiBase;
|
||||
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;
|
||||
@@ -48,7 +50,7 @@ public class CardCollections {
|
||||
*
|
||||
* @param file the file
|
||||
*/
|
||||
public CardCollections() {
|
||||
public CardCollections(final IGuiBase gui) {
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start();
|
||||
this.constructed = new StorageImmediatelySerialized<Deck>("Constructed decks", new DeckStorage(new File(ForgeConstants.DECK_CONSTRUCTED_DIR), true), true);
|
||||
@@ -64,7 +66,7 @@ public class CardCollections {
|
||||
// int sum = constructed.size() + sealed.size() + draft.size() + cube.size() + scheme.size() + plane.size();
|
||||
// FSkin.setProgessBarMessage(String.format("Loaded %d decks in %f sec", sum, sw.getTime() / 1000f ));
|
||||
// remove this after most people have been switched to new layout
|
||||
final OldDeckParser oldParser = new OldDeckParser(this.constructed, this.draft, this.sealed, this.cube);
|
||||
final OldDeckParser oldParser = new OldDeckParser(gui, this.constructed, this.draft, this.sealed, this.cube);
|
||||
oldParser.tryParse();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import forge.game.GameFormat;
|
||||
import forge.game.GameType;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.gauntlet.GauntletData;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.interfaces.IProgressBar;
|
||||
import forge.itemmanager.ItemManagerConfig;
|
||||
import forge.limited.GauntletMini;
|
||||
@@ -84,7 +85,7 @@ public class FModel {
|
||||
private static IStorage<QuestWorld> worlds;
|
||||
private static GameFormat.Collection formats;
|
||||
|
||||
public static void initialize(final IProgressBar progressBar) {
|
||||
public static void initialize(final IGuiBase gui, final IProgressBar progressBar) {
|
||||
|
||||
// Instantiate preferences: quest and regular
|
||||
//Preferences are initialized first so that the splash screen can be translated.
|
||||
@@ -102,7 +103,7 @@ public class FModel {
|
||||
ProgressObserver.emptyObserver : new ProgressObserver() {
|
||||
@Override
|
||||
public void setOperationName(final String name, final boolean usePercents) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
FThreads.invokeInEdtLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressBar.setDescription(name);
|
||||
@@ -113,7 +114,7 @@ public class FModel {
|
||||
|
||||
@Override
|
||||
public void report(final int current, final int total) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
FThreads.invokeInEdtLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressBar.setMaximum(total);
|
||||
@@ -150,7 +151,7 @@ public class FModel {
|
||||
loadDynamicGamedata();
|
||||
|
||||
if (progressBar != null) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
FThreads.invokeInEdtLater(gui, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressBar.setDescription(Localizer.getInstance().getMessage("splash.loading.decks"));
|
||||
@@ -158,8 +159,8 @@ public class FModel {
|
||||
});
|
||||
}
|
||||
|
||||
decks = new CardCollections();
|
||||
quest = new QuestController();
|
||||
decks = new CardCollections(gui);
|
||||
quest = new QuestController(gui);
|
||||
|
||||
CardPreferences.load();
|
||||
DeckPreferences.load();
|
||||
@@ -297,9 +298,9 @@ public class FModel {
|
||||
gauntletData = data0;
|
||||
}
|
||||
|
||||
public static GauntletMini getGauntletMini() {
|
||||
public static GauntletMini getGauntletMini(final IGuiBase gui) {
|
||||
if (gauntlet == null) {
|
||||
gauntlet = new GauntletMini();
|
||||
gauntlet = new GauntletMini(gui);
|
||||
}
|
||||
return gauntlet;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.google.common.base.Predicate;
|
||||
|
||||
import forge.card.IUnOpenedProduct;
|
||||
import forge.card.UnOpenedProduct;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
@@ -162,7 +163,7 @@ public class MetaSet {
|
||||
*
|
||||
* @return UnOpenedProduct, the generated booster.
|
||||
*/
|
||||
public IUnOpenedProduct getBooster() {
|
||||
public IUnOpenedProduct getBooster(final IGuiBase gui) {
|
||||
|
||||
switch(type) {
|
||||
case Full:
|
||||
@@ -181,7 +182,7 @@ public class MetaSet {
|
||||
Predicate<PaperCard> predicate = IPaperCard.Predicates.printedInSets(data.split(" "));
|
||||
return new UnOpenedProduct(SealedProduct.Template.genericBooster, predicate);
|
||||
|
||||
case Choose: return UnOpenedMeta.choose(data);
|
||||
case Choose: return UnOpenedMeta.choose(data, gui);
|
||||
case Random: return UnOpenedMeta.random(data);
|
||||
case Combo: return UnOpenedMeta.selectAll(data);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package forge.model;
|
||||
|
||||
import forge.card.IUnOpenedProduct;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.TextUtil;
|
||||
@@ -44,17 +45,22 @@ public class UnOpenedMeta implements IUnOpenedProduct {
|
||||
private final ArrayList<MetaSet> metaSets;
|
||||
private final JoinOperation operation;
|
||||
private final Random generator = MyRandom.getRandom();
|
||||
private final IGuiBase gui;
|
||||
|
||||
/**
|
||||
* Constructor for UnOpenedMeta.
|
||||
*
|
||||
* @param creationString
|
||||
* String, is parsed for MetaSet info.
|
||||
* String, is parsed for MetaSet info.
|
||||
* @param choose
|
||||
* sets the random/choice status.
|
||||
* sets the random/choice status.
|
||||
* @param gui
|
||||
* the gui.
|
||||
*/
|
||||
private UnOpenedMeta(final String creationString, final JoinOperation op) {
|
||||
private UnOpenedMeta(final String creationString, final JoinOperation op, final IGuiBase gui) {
|
||||
metaSets = new ArrayList<MetaSet>();
|
||||
operation = op;
|
||||
this.gui = gui;
|
||||
|
||||
for (String m : TextUtil.splitWithParenthesis(creationString, ';')) {
|
||||
metaSets.add(new MetaSet(m, true));
|
||||
@@ -88,39 +94,39 @@ public class UnOpenedMeta implements IUnOpenedProduct {
|
||||
if (isHuman) {
|
||||
final MetaSet ms;
|
||||
if (allowCancel) {
|
||||
ms = SGuiChoose.oneOrNone("Choose Booster", metaSets);
|
||||
ms = SGuiChoose.oneOrNone(gui, "Choose Booster", metaSets);
|
||||
if (ms == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ms = SGuiChoose.one("Choose Booster", metaSets);
|
||||
ms = SGuiChoose.one(gui, "Choose Booster", metaSets);
|
||||
}
|
||||
return ms.getBooster().get();
|
||||
return ms.getBooster(gui).get();
|
||||
}
|
||||
|
||||
case RandomOne: // AI should fall though here from the case above
|
||||
int selected = generator.nextInt(metaSets.size());
|
||||
final IUnOpenedProduct newBooster = metaSets.get(selected).getBooster();
|
||||
final IUnOpenedProduct newBooster = metaSets.get(selected).getBooster(gui);
|
||||
return newBooster.get();
|
||||
|
||||
case SelectAll:
|
||||
List<PaperCard> allCards = new ArrayList<PaperCard>();
|
||||
for (MetaSet ms : metaSets) {
|
||||
allCards.addAll(ms.getBooster().get());
|
||||
allCards.addAll(ms.getBooster(gui).get());
|
||||
}
|
||||
return allCards;
|
||||
}
|
||||
throw new IllegalStateException("Got wrong operation type in unopenedMeta - execution should never reach this point");
|
||||
}
|
||||
|
||||
public static UnOpenedMeta choose(String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.ChooseOne);
|
||||
public static UnOpenedMeta choose(final String desc, final IGuiBase gui) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.ChooseOne, gui);
|
||||
}
|
||||
public static UnOpenedMeta random(String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.RandomOne);
|
||||
public static UnOpenedMeta random(final String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.RandomOne, null);
|
||||
}
|
||||
public static UnOpenedMeta selectAll(String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.SelectAll);
|
||||
public static UnOpenedMeta selectAll(final String desc) {
|
||||
return new UnOpenedMeta(desc, JoinOperation.SelectAll, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package forge.player;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
@@ -16,42 +13,42 @@ public final class GamePlayerUtil {
|
||||
|
||||
private final static ForgePreferences prefs = FModel.getPreferences();
|
||||
|
||||
public static void setPlayerName() {
|
||||
public static void setPlayerName(final IGuiBase gui) {
|
||||
String oldPlayerName = prefs.getPref(FPref.PLAYER_NAME);
|
||||
String newPlayerName = null;
|
||||
|
||||
if (StringUtils.isBlank(oldPlayerName)) {
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingFirstTimePrompt(), oldPlayerName);
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingFirstTimePrompt(gui), oldPlayerName);
|
||||
} else {
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingStandardPrompt(oldPlayerName), oldPlayerName);
|
||||
newPlayerName = getVerifiedPlayerName(getPlayerNameUsingStandardPrompt(gui, oldPlayerName), oldPlayerName);
|
||||
}
|
||||
|
||||
prefs.setPref(FPref.PLAYER_NAME, newPlayerName);
|
||||
prefs.save();
|
||||
|
||||
if (StringUtils.isBlank(oldPlayerName) && newPlayerName != "Human") {
|
||||
showThankYouPrompt(newPlayerName);
|
||||
showThankYouPrompt(gui, newPlayerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void showThankYouPrompt(String playerName) {
|
||||
SOptionPane.showMessageDialog("Thank you, " + playerName + ". "
|
||||
private static void showThankYouPrompt(final IGuiBase gui, final String playerName) {
|
||||
SOptionPane.showMessageDialog(gui, "Thank you, " + playerName + ". "
|
||||
+ "You will not be prompted again but you can change\n"
|
||||
+ "your name at any time using the \"Player Name\" setting in Preferences\n"
|
||||
+ "or via the constructed match setup screen\n");
|
||||
}
|
||||
|
||||
private static String getPlayerNameUsingFirstTimePrompt() {
|
||||
return SOptionPane.showInputDialog(
|
||||
private static String getPlayerNameUsingFirstTimePrompt(final IGuiBase gui) {
|
||||
return SOptionPane.showInputDialog(gui,
|
||||
"By default, Forge will refer to you as the \"Human\" during gameplay.\n" +
|
||||
"If you would prefer a different name please enter it now.",
|
||||
"Personalize Forge Gameplay",
|
||||
SOptionPane.QUESTION_ICON);
|
||||
}
|
||||
|
||||
private static String getPlayerNameUsingStandardPrompt(String playerName) {
|
||||
return SOptionPane.showInputDialog(
|
||||
private static String getPlayerNameUsingStandardPrompt(final IGuiBase gui, final String playerName) {
|
||||
return SOptionPane.showInputDialog(gui,
|
||||
"Please enter a new name. (alpha-numeric only)",
|
||||
"Personalize Forge Gameplay",
|
||||
null,
|
||||
@@ -69,13 +66,4 @@ public final class GamePlayerUtil {
|
||||
return newName;
|
||||
}
|
||||
|
||||
public static RegisteredPlayer getGuiRegisteredPlayer(Game game) {
|
||||
LobbyPlayer guiPlayer = GuiBase.getInterface().getGuiPlayer();
|
||||
for (RegisteredPlayer player : game.getMatch().getPlayers()) {
|
||||
if (player.getPlayer() == guiPlayer) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.match.input.InputSelectCardsFromList;
|
||||
import forge.match.input.InputSelectManyBase;
|
||||
import forge.util.Aggregates;
|
||||
@@ -25,21 +26,29 @@ import forge.util.ITriggerEvent;
|
||||
import forge.util.Lang;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SGuiDialog;
|
||||
import forge.view.CardView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
private final PlayerControllerHuman controller;
|
||||
private final SpellAbility ability;
|
||||
private final Card source;
|
||||
|
||||
public HumanCostDecision(Player p, SpellAbility sa, Card source) {
|
||||
|
||||
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final Card source) {
|
||||
super(p);
|
||||
this.controller = controller;
|
||||
ability = sa;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
private IGuiBase getGui() {
|
||||
return this.controller.getGui();
|
||||
}
|
||||
|
||||
protected int chooseXValue(final int maxValue) {
|
||||
/*final String chosen = sa.getSVar("ChosenX");
|
||||
if (chosen.length() > 0) {
|
||||
@@ -51,7 +60,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
source.setSVar("ChosenX", Integer.toString(chosenX));
|
||||
return chosenX;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostAddMana cost) {
|
||||
Integer c = cost.convertAmount();
|
||||
@@ -63,7 +72,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostChooseCreatureType cost) {
|
||||
String choice = player.getController().chooseSomeType("Creature", ability, new ArrayList<String>(CardType.getCreatureTypes()), new ArrayList<String>(), true);
|
||||
String choice = controller.chooseSomeType("Creature", ability, new ArrayList<String>(CardType.getCreatureTypes()), new ArrayList<String>(), true);
|
||||
if( null == choice )
|
||||
return null;
|
||||
return PaymentDecision.type(choice);
|
||||
@@ -122,7 +131,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (c == 0) { return PaymentDecision.card(Lists.<Card>newArrayList()); }
|
||||
List<Card> discarded = new ArrayList<Card>();
|
||||
while (c > 0) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, handList);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, handList);
|
||||
inp.setMessage("Select one of the cards with the same name to discard. Already chosen: " + discarded);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -153,7 +162,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, handList);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, handList);
|
||||
inp.setMessage("Select %d more " + cost.getDescriptiveType() + " to discard.");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -251,7 +260,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
if (cost.from == ZoneType.Battlefield || cost.from == ZoneType.Hand) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, list);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
inp.setMessage("Exile %d card(s) from your" + cost.from);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -290,8 +299,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (nNeeded == 0) {
|
||||
return PaymentDecision.number(0);
|
||||
}
|
||||
|
||||
final Player p = SGuiChoose.oneOrNone(String.format("Exile from whose %s?", cost.getFrom()), payableZone);
|
||||
final PlayerView view = SGuiChoose.oneOrNone(getGui(), String.format("Exile from whose %s?", cost.getFrom()),
|
||||
controller.getPlayerViews(payableZone));
|
||||
final Player p = controller.getPlayer(view);
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -301,7 +311,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if(count < nNeeded)
|
||||
return null;
|
||||
|
||||
List<Card> toExile = SGuiChoose.many("Exile from " + cost.getFrom(), "To be exiled", count - nNeeded, typeList, null);
|
||||
List<Card> toExile = SGuiChoose.many(getGui(), "Exile from " + cost.getFrom(), "To be exiled", count - nNeeded, typeList, null);
|
||||
return PaymentDecision.card(toExile);
|
||||
}
|
||||
|
||||
@@ -348,7 +358,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
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 = SGuiChoose.oneOrNone("Exile from Stack", descList);
|
||||
final String o = SGuiChoose.oneOrNone(getGui(), "Exile from Stack", descList);
|
||||
|
||||
if (o != null) {
|
||||
final SpellAbility toExile = saList.get(descList.indexOf(o));
|
||||
@@ -382,7 +392,8 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
List<Card> exiled = new ArrayList<Card>();
|
||||
for (int i = 0; i < nNeeded; i++) {
|
||||
final Card c = SGuiChoose.oneOrNone("Exile from " + cost.getFrom(), typeList);
|
||||
final CardView view = SGuiChoose.oneOrNone(getGui(), "Exile from " + cost.getFrom(), controller.getCardViews(typeList));
|
||||
final Card c = controller.getCard(view);
|
||||
|
||||
if (c != null) {
|
||||
typeList.remove(c);
|
||||
@@ -416,7 +427,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (list.size() < c)
|
||||
return null;
|
||||
|
||||
return PaymentDecision.card(SGuiChoose.many("Choose an exiled card to put into graveyard", "To graveyard", c, list, source));
|
||||
final List<CardView> choice = SGuiChoose.many(getGui(), "Choose an exiled card to put into graveyard", "To graveyard", c,
|
||||
controller.getCardViews(list), controller.getCardView(source));
|
||||
return PaymentDecision.card(controller.getCards(choice));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -447,7 +460,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
final List<Card> list = player.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> validCards = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, validCards);
|
||||
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();
|
||||
@@ -487,7 +500,8 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(source.getName()).append(" - Choose an opponent to gain ").append(c).append(" life:");
|
||||
|
||||
final Player chosenToGain = SGuiChoose.oneOrNone(sb.toString(), oppsThatCanGainLife);
|
||||
final PlayerView chosenToGainView = SGuiChoose.oneOrNone(getGui(), sb.toString(), controller.getPlayerViews(oppsThatCanGainLife));
|
||||
final Player chosenToGain = controller.getPlayer(chosenToGainView);
|
||||
if (null == chosenToGain)
|
||||
return null;
|
||||
else
|
||||
@@ -568,7 +582,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
list = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
|
||||
|
||||
if (cost.from == ZoneType.Hand) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, list);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
inp.setMessage("Put %d card(s) from your " + cost.from );
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -597,14 +611,16 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if(typeList.size() < nNeeded)
|
||||
return null;
|
||||
|
||||
final List<CardView> viewList = controller.getCardViews(typeList);
|
||||
List<Card> chosen = new ArrayList<>();
|
||||
for (int i = 0; i < nNeeded; i++) {
|
||||
final Card c = SGuiChoose.oneOrNone("Put from " + fromZone + " to library", typeList);
|
||||
final CardView view = SGuiChoose.oneOrNone(getGui(), "Put from " + fromZone + " to library", viewList);
|
||||
final Card c = controller.getCard(view);
|
||||
|
||||
if (c == null)
|
||||
return null;
|
||||
|
||||
typeList.remove(c);
|
||||
|
||||
viewList.remove(view);
|
||||
chosen.add(c);
|
||||
}
|
||||
return PaymentDecision.card(chosen);
|
||||
@@ -615,21 +631,27 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.number(0);
|
||||
}
|
||||
|
||||
final Player p = SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", fromZone), payableZone);
|
||||
final List<PlayerView> players = controller.getPlayerViews(payableZone);
|
||||
final PlayerView pView = SGuiChoose.oneOrNone(getGui(), String.format("Put cards from whose %s?", fromZone), players);
|
||||
final Player p = controller.getPlayer(pView);
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Card> typeList = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
if(typeList.size() < nNeeded)
|
||||
if (typeList.size() < nNeeded)
|
||||
return null;
|
||||
|
||||
|
||||
final List<CardView> viewList = controller.getCardViews(typeList);
|
||||
List<Card> chosen = new ArrayList<>();
|
||||
for (int i = 0; i < nNeeded; i++) {
|
||||
final Card c = SGuiChoose.oneOrNone("Put cards from " + fromZone + " to Library", typeList);
|
||||
final CardView view = SGuiChoose.oneOrNone(getGui(), "Put cards from " + fromZone + " to Library", viewList);
|
||||
final Card c = controller.getCard(view);
|
||||
|
||||
if (c == null)
|
||||
return null;
|
||||
typeList.remove(c);
|
||||
|
||||
viewList.remove(view);
|
||||
chosen.add(c);
|
||||
}
|
||||
return PaymentDecision.card(chosen);
|
||||
@@ -647,8 +669,8 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
// Cards to use this branch: Scarscale Ritual, Wandering Mage - each adds only one counter
|
||||
List<Card> typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, ability.getHostCard());
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, typeList);
|
||||
inp.setMessage("Put " + Lang.nounWithAmount(c, cost.getCounter().getName() + " counter") + " on " +cost.getDescriptiveType());
|
||||
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();
|
||||
|
||||
@@ -676,13 +698,14 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (cost.payCostFromSource()) {
|
||||
final Card card = ability.getHostCard();
|
||||
if (card.getController() == player && card.isInPlay()) {
|
||||
return player.getController().confirmPayment(cost, "Return " + card.getName() + " to hand?") ? PaymentDecision.card(card) : null;
|
||||
final CardView view = controller.getCardView(card);
|
||||
return player.getController().confirmPayment(cost, "Return " + view + " to hand?") ? PaymentDecision.card(card) : null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
List<Card> validCards = CardLists.getValidCards(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ability.getActivatingPlayer(), ability.getHostCard());
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, validCards);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, validCards);
|
||||
inp.setMessage("Return %d " + cost.getType() + " " + cost.getType() + " card(s) to hand");
|
||||
inp.showAndWait();
|
||||
if (inp.hasCancelled())
|
||||
@@ -723,7 +746,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (num == 0)
|
||||
return PaymentDecision.number(0);
|
||||
|
||||
inp = new InputSelectCardsFromList(num, handList) {
|
||||
inp = new InputSelectCardsFromList(controller, num, handList) {
|
||||
private static final long serialVersionUID = 8338626212893374798L;
|
||||
|
||||
@Override
|
||||
@@ -754,7 +777,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if ( num == 0 )
|
||||
return PaymentDecision.number(0);;
|
||||
|
||||
inp = new InputSelectCardsFromList(num, num, handList);
|
||||
inp = new InputSelectCardsFromList(controller, num, num, handList);
|
||||
inp.setMessage("Select %d more " + cost.getDescriptiveType() + " card(s) to reveal.");
|
||||
}
|
||||
inp.setCancelAllowed(true);
|
||||
@@ -784,7 +807,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return card.hasCounters();
|
||||
}
|
||||
});
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, list);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, list);
|
||||
inp.setMessage("Select " + cost.getDescriptiveType() + " to remove a counter");
|
||||
inp.setCancelAllowed(false);
|
||||
inp.showAndWait();
|
||||
@@ -798,7 +821,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
String prompt = "Select type counters to remove";
|
||||
cost.setCounterType(SGuiChoose.one(prompt, typeChoices));
|
||||
cost.setCounterType(SGuiChoose.one(getGui(), prompt, typeChoices));
|
||||
|
||||
return PaymentDecision.card(selected, cost.getCounter());
|
||||
}
|
||||
@@ -810,8 +833,8 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
private final CounterType counterType;
|
||||
private final List<Card> validChoices;
|
||||
|
||||
public InputSelectCardToRemoveCounter(int cntCounters, CounterType cType, List<Card> validCards) {
|
||||
super(cntCounters, cntCounters);
|
||||
public InputSelectCardToRemoveCounter(final PlayerControllerHuman controller, int cntCounters, CounterType cType, List<Card> validCards) {
|
||||
super(controller, cntCounters, cntCounters);
|
||||
this.validChoices = validCards;
|
||||
counterType = cType;
|
||||
cardsChosen = cntCounters > 0 ? new HashMap<Card, Integer>() : null;
|
||||
@@ -888,7 +911,8 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (cost.payCostFromSource()) {
|
||||
int maxCounters = source.getCounters(cost.counter);
|
||||
if (amount.equals("All")) {
|
||||
if (!SGuiDialog.confirm(ability.getHostCard(), "Remove all counters?")) {
|
||||
final CardView view = controller.getCardView(ability.getHostCard());
|
||||
if (!SGuiDialog.confirm(getGui(), view, "Remove all counters?")) {
|
||||
return null;
|
||||
}
|
||||
cntRemoved = maxCounters;
|
||||
@@ -914,7 +938,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
List<Card> validCards = CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source);
|
||||
if (cost.zone.equals(ZoneType.Battlefield)) {
|
||||
final InputSelectCardToRemoveCounter inp = new InputSelectCardToRemoveCounter(cntRemoved, cost.counter, validCards);
|
||||
final InputSelectCardToRemoveCounter inp = new InputSelectCardToRemoveCounter(controller, cntRemoved, cost.counter, validCards);
|
||||
inp.setMessage("Remove %d " + cost.counter.getName() + " counters from " + cost.getDescriptiveType());
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -936,12 +960,13 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
|
||||
// Rift Elemental only - always removes 1 counter, so there will be no code for N counters.
|
||||
List<Card> suspended = new ArrayList<Card>();
|
||||
for(Card crd : validCards)
|
||||
if(crd.getCounters( cost.counter) > 0 )
|
||||
suspended.add(crd);
|
||||
List<CardView> suspended = Lists.newArrayList();
|
||||
for (final Card crd : validCards)
|
||||
if (crd.getCounters( cost.counter) > 0)
|
||||
suspended.add(controller.getCardView(crd));
|
||||
|
||||
final Card card = SGuiChoose.oneOrNone("Remove counter(s) from a card in " + cost.zone, suspended);
|
||||
final CardView view = SGuiChoose.oneOrNone(getGui(), "Remove counter(s) from a card in " + cost.zone, suspended);
|
||||
final Card card = controller.getCard(view);
|
||||
return null == card ? null : PaymentDecision.card(card, c);
|
||||
}
|
||||
|
||||
@@ -982,7 +1007,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (list.size() < c) {
|
||||
return null;
|
||||
}
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, list);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list);
|
||||
inp.setMessage("Select a " + cost.getDescriptiveType() + " to sacrifice (%d left)");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -1050,7 +1075,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (c == 0) return PaymentDecision.number(0);
|
||||
List<Card> tapped = new ArrayList<Card>();
|
||||
while (c > 0) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, typeList);
|
||||
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();
|
||||
@@ -1072,7 +1097,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
if (totalPower) {
|
||||
int i = Integer.parseInt(totalP);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(0, typeList.size(), typeList);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 0, typeList.size(), typeList);
|
||||
inp.setMessage("Select a card to tap.");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -1084,7 +1109,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
}
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, typeList);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, typeList);
|
||||
inp.setMessage("Select a " + cost.getDescriptiveType() + " to tap (%d left)");
|
||||
inp.showAndWait();
|
||||
if ( inp.hasCancelled() )
|
||||
@@ -1112,7 +1137,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
}
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, typeList);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, typeList);
|
||||
inp.setMessage("Select a " + cost.getDescriptiveType() + " to untap (%d left)");
|
||||
inp.showAndWait();
|
||||
if( inp.hasCancelled() || inp.getSelected().size() != c )
|
||||
|
||||
@@ -38,7 +38,7 @@ import java.util.Map;
|
||||
|
||||
public class HumanPlay {
|
||||
|
||||
public HumanPlay() {
|
||||
private HumanPlay() {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,8 +49,8 @@ public class HumanPlay {
|
||||
* @param sa
|
||||
* a {@link forge.game.spellability.SpellAbility} object.
|
||||
*/
|
||||
public final static void playSpellAbility(Player p, SpellAbility sa) {
|
||||
FThreads.assertExecutedByEdt(false);
|
||||
public final static void playSpellAbility(final PlayerControllerHuman controller, final Player p, SpellAbility sa) {
|
||||
FThreads.assertExecutedByEdt(controller.getGui(), false);
|
||||
|
||||
if (sa == Ability.PLAY_LAND_SURROGATE) {
|
||||
p.playLand(sa.getHostCard(), false);
|
||||
@@ -89,10 +89,10 @@ public class HumanPlay {
|
||||
Cost abCost = sa.getPayCosts() == null ? new Cost("0", sa.isAbility()) : sa.getPayCosts();
|
||||
CostPayment payment = new CostPayment(abCost, sa);
|
||||
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(sa, payment);
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa, payment);
|
||||
req.playAbility(true, false, false);
|
||||
}
|
||||
else if (payManaCostIfNeeded(p, sa)) {
|
||||
else if (payManaCostIfNeeded(controller, p, sa)) {
|
||||
if (sa.isSpell() && !source.isCopiedSpell()) {
|
||||
sa.setHostCard(p.getGame().getAction().moveToStack(source));
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public class HumanPlay {
|
||||
return p.getController().getAbilityToPlay(abilities);
|
||||
}
|
||||
|
||||
private static boolean payManaCostIfNeeded(final Player p, final SpellAbility sa) {
|
||||
private static boolean payManaCostIfNeeded(final PlayerControllerHuman controller, final Player p, final SpellAbility sa) {
|
||||
final ManaCostBeingPaid manaCost;
|
||||
if (sa.getHostCard().isCopiedSpell() && sa.isSpell()) {
|
||||
manaCost = new ManaCostBeingPaid(ManaCost.ZERO);
|
||||
@@ -129,7 +129,7 @@ public class HumanPlay {
|
||||
boolean isPaid = manaCost.isPaid();
|
||||
|
||||
if (!isPaid) {
|
||||
InputPayManaSimple inputPay = new InputPayManaSimple(p.getGame(), sa, manaCost);
|
||||
InputPayManaSimple inputPay = new InputPayManaSimple(controller, p.getGame(), sa, manaCost);
|
||||
inputPay.showAndWait();
|
||||
isPaid = inputPay.isPaid();
|
||||
}
|
||||
@@ -144,8 +144,8 @@ public class HumanPlay {
|
||||
* @param sa
|
||||
* a {@link forge.game.spellability.SpellAbility} object.
|
||||
*/
|
||||
public static final void playSaWithoutPayingManaCost(final Game game, final SpellAbility sa, boolean mayChooseNewTargets) {
|
||||
FThreads.assertExecutedByEdt(false);
|
||||
public static final void playSaWithoutPayingManaCost(final PlayerControllerHuman controller, final Game game, final SpellAbility sa, boolean mayChooseNewTargets) {
|
||||
FThreads.assertExecutedByEdt(controller.getGui(), false);
|
||||
final Card source = sa.getHostCard();
|
||||
|
||||
source.setSplitStateToPlayAbility(sa);
|
||||
@@ -156,7 +156,7 @@ public class HumanPlay {
|
||||
}
|
||||
final CostPayment payment = new CostPayment(sa.getPayCosts(), sa);
|
||||
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(sa, payment);
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa, payment);
|
||||
req.playAbility(mayChooseNewTargets, true, false);
|
||||
}
|
||||
else {
|
||||
@@ -180,19 +180,19 @@ public class HumanPlay {
|
||||
* @param skipTargeting
|
||||
* a boolean.
|
||||
*/
|
||||
public final static void playSpellAbilityNoStack(final Player player, final SpellAbility sa) {
|
||||
playSpellAbilityNoStack(player, sa, false);
|
||||
public final static void playSpellAbilityNoStack(final PlayerControllerHuman controller, final Player player, final SpellAbility sa) {
|
||||
playSpellAbilityNoStack(controller, player, sa, false);
|
||||
}
|
||||
|
||||
public final static void playSpellAbilityNoStack(final Player player, final SpellAbility sa, boolean useOldTargets) {
|
||||
public final static void playSpellAbilityNoStack(final PlayerControllerHuman controller, final Player player, final SpellAbility sa, boolean useOldTargets) {
|
||||
sa.setActivatingPlayer(player);
|
||||
|
||||
if (sa.getPayCosts() != null) {
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(sa, new CostPayment(sa.getPayCosts(), sa));
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa, new CostPayment(sa.getPayCosts(), sa));
|
||||
|
||||
req.playAbility(!useOldTargets, false, true);
|
||||
}
|
||||
else if (payManaCostIfNeeded(player, sa)) {
|
||||
else if (payManaCostIfNeeded(controller, player, sa)) {
|
||||
AbilityUtils.resolve(sa);
|
||||
}
|
||||
}
|
||||
@@ -231,7 +231,7 @@ public class HumanPlay {
|
||||
* a {@link forge.UiCommand} object.
|
||||
* @param sourceAbility TODO
|
||||
*/
|
||||
public static boolean payCostDuringAbilityResolve(final Player p, final Card source, final Cost cost, SpellAbility sourceAbility, String prompt) {
|
||||
public static boolean payCostDuringAbilityResolve(final PlayerControllerHuman controller, final Player p, final Card source, final Cost cost, SpellAbility sourceAbility, String prompt) {
|
||||
// Only human player pays this way
|
||||
Card current = null; // Used in spells with RepeatEach effect to distinguish cards, Cut the Tethers
|
||||
if (sourceAbility.hasParam("ShowCurrentCard")) {
|
||||
@@ -259,7 +259,7 @@ public class HumanPlay {
|
||||
}
|
||||
}
|
||||
|
||||
HumanCostDecision hcd = new HumanCostDecision(p, sourceAbility, source);
|
||||
final HumanCostDecision hcd = new HumanCostDecision(controller, p, sourceAbility, source);
|
||||
|
||||
//the following costs do not need inputs
|
||||
for (CostPart part : parts) {
|
||||
@@ -378,7 +378,7 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
while (amount > 0) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, list);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, list);
|
||||
inp.setMessage("Select a card to add a counter to");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -430,7 +430,7 @@ public class HumanPlay {
|
||||
}
|
||||
});
|
||||
if (list.isEmpty()) { return false; }
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, list);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, list);
|
||||
inp.setMessage("Select a card to remove a counter");
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -447,7 +447,7 @@ public class HumanPlay {
|
||||
}
|
||||
if (typeChoices.size() > 1) {
|
||||
String cprompt = "Select type counters to remove";
|
||||
counterType = SGuiChoose.one(cprompt, typeChoices);
|
||||
counterType = SGuiChoose.one(controller.getGui(), cprompt, typeChoices);
|
||||
}
|
||||
else {
|
||||
counterType = typeChoices.get(0);
|
||||
@@ -488,7 +488,7 @@ public class HumanPlay {
|
||||
}
|
||||
// replace this with input
|
||||
for (int i = 0; i < nNeeded; i++) {
|
||||
final Card c = SGuiChoose.oneOrNone("Exile from " + from, list);
|
||||
final Card c = SGuiChoose.oneOrNone(controller.getGui(), "Exile from " + from, list);
|
||||
if (c == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -522,7 +522,7 @@ public class HumanPlay {
|
||||
payableZone.add(player);
|
||||
}
|
||||
}
|
||||
Player chosen = SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", from), payableZone);
|
||||
Player chosen = SGuiChoose.oneOrNone(controller.getGui(), String.format("Put cards from whose %s?", from), payableZone);
|
||||
if (chosen == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -534,7 +534,7 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Card c = SGuiChoose.oneOrNone("Put cards to Library", typeList);
|
||||
final Card c = SGuiChoose.oneOrNone(controller.getGui(), "Put cards to Library", typeList);
|
||||
|
||||
if (c != null) {
|
||||
typeList.remove(c);
|
||||
@@ -546,7 +546,7 @@ public class HumanPlay {
|
||||
}
|
||||
}
|
||||
else if (from == ZoneType.Hand) { // Tainted Specter
|
||||
boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "put into library." + orString);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, "put into library." + orString);
|
||||
if (!hasPaid) {
|
||||
return false;
|
||||
}
|
||||
@@ -556,19 +556,19 @@ public class HumanPlay {
|
||||
else if (part instanceof CostSacrifice) {
|
||||
int amount = Integer.parseInt(((CostSacrifice)part).getAmount());
|
||||
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||
boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "sacrifice." + orString);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, "sacrifice." + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostGainControl) {
|
||||
int amount = Integer.parseInt(((CostGainControl)part).getAmount());
|
||||
List<Card> list = CardLists.getValidCards(p.getGame().getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||
boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "gain control." + orString);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, "gain control." + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostReturn) {
|
||||
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "return to hand." + orString);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, "return to hand." + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostDiscard) {
|
||||
@@ -584,21 +584,21 @@ public class HumanPlay {
|
||||
} else {
|
||||
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), part.getType(), p, source);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "discard." + orString);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, "discard." + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
}
|
||||
else if (part instanceof CostReveal) {
|
||||
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), part.getType(), p, source);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "reveal." + orString);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, "reveal." + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostTapType) {
|
||||
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||
list = CardLists.filter(list, Presets.UNTAPPED);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "tap." + orString);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, "tap." + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostPartMana) {
|
||||
@@ -642,10 +642,10 @@ public class HumanPlay {
|
||||
return paid;
|
||||
}
|
||||
|
||||
private static boolean payCostPart(SpellAbility sourceAbility, CostPartWithList cpl, int amount, List<Card> list, String actionName) {
|
||||
private static boolean payCostPart(final PlayerControllerHuman controller, SpellAbility sourceAbility, CostPartWithList cpl, int amount, List<Card> list, String actionName) {
|
||||
if (list.size() < amount) { return false; } // unable to pay (not enough cards)
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(amount, amount, list);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, amount, amount, list);
|
||||
inp.setMessage("Select %d " + cpl.getDescriptiveType() + " card(s) to " + actionName);
|
||||
inp.setCancelAllowed(true);
|
||||
|
||||
@@ -686,7 +686,7 @@ public class HumanPlay {
|
||||
return done;
|
||||
}
|
||||
|
||||
public static boolean payManaCost(final ManaCost realCost, final CostPartMana mc, final SpellAbility ability, final Player activator, String prompt, boolean isActivatedSa) {
|
||||
public static boolean payManaCost(final PlayerControllerHuman controller, final ManaCost realCost, final CostPartMana mc, final SpellAbility ability, final Player activator, String prompt, boolean isActivatedSa) {
|
||||
final Card source = ability.getHostCard();
|
||||
ManaCostBeingPaid toPay = new ManaCostBeingPaid(realCost, mc.getRestiction());
|
||||
|
||||
@@ -726,7 +726,7 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
if (!toPay.isPaid()) {
|
||||
inpPayment = new InputPayManaOfCostPayment(toPay, ability, activator);
|
||||
inpPayment = new InputPayManaOfCostPayment(controller, toPay, ability, activator);
|
||||
inpPayment.setMessagePrefix(prompt);
|
||||
inpPayment.showAndWait();
|
||||
if (!inpPayment.isPaid()) {
|
||||
@@ -736,7 +736,7 @@ public class HumanPlay {
|
||||
source.setXManaCostPaidByColor(toPay.getXManaCostPaidByColor());
|
||||
source.setColorsPaid(toPay.getColorsPaid());
|
||||
source.setSunburstValue(toPay.getSunburst());
|
||||
}
|
||||
}
|
||||
|
||||
// Handle convoke and offerings
|
||||
if (ability.isOffering() && ability.getSacrificedAsOffering() != null) {
|
||||
|
||||
@@ -50,10 +50,12 @@ import java.util.List;
|
||||
* @version $Id: HumanPlaySpellAbility.java 24317 2014-01-17 08:32:39Z Max mtg $
|
||||
*/
|
||||
public class HumanPlaySpellAbility {
|
||||
private final PlayerControllerHuman controller;
|
||||
private final SpellAbility ability;
|
||||
private final CostPayment payment;
|
||||
|
||||
public HumanPlaySpellAbility(final SpellAbility sa, final CostPayment cp) {
|
||||
public HumanPlaySpellAbility(final PlayerControllerHuman controller, final SpellAbility sa, final CostPayment cp) {
|
||||
this.controller = controller;
|
||||
this.ability = sa;
|
||||
this.payment = cp;
|
||||
}
|
||||
@@ -94,7 +96,7 @@ public class HumanPlaySpellAbility {
|
||||
boolean prerequisitesMet = this.announceValuesLikeX()
|
||||
&& this.announceType()
|
||||
&& (!mayChooseTargets || setupTargets()) // if you can choose targets, then do choose them.
|
||||
&& (isFree || this.payment.payCost(new HumanCostDecision(human, ability, ability.getHostCard())));
|
||||
&& (isFree || this.payment.payCost(new HumanCostDecision(controller, human, ability, ability.getHostCard())));
|
||||
|
||||
if (!prerequisitesMet) {
|
||||
if (!ability.isTrigger()) {
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
package forge.player;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.IGameEntitiesFactory;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.GuiDisplayUtil;
|
||||
|
||||
public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactory {
|
||||
public LobbyPlayerHuman(String name) {
|
||||
final IGuiBase gui;
|
||||
|
||||
public LobbyPlayerHuman(final String name, final IGuiBase gui) {
|
||||
super(name);
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerController createControllerFor(Player human) {
|
||||
return new PlayerControllerHuman(human.getGame(), human, this);
|
||||
return new PlayerControllerHuman(human.getGame(), human, this, gui);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Player createIngamePlayer(Game game) {
|
||||
Player player = new Player(GuiDisplayUtil.personalizeHuman(getName()), game);
|
||||
player.setFirstController(new PlayerControllerHuman(game, player, this));
|
||||
public Player createIngamePlayer(Game game, final int id) {
|
||||
Player player = new Player(GuiDisplayUtil.personalizeHuman(getName()), game, id);
|
||||
player.setFirstController(new PlayerControllerHuman(game, player, this, gui));
|
||||
|
||||
if (ForgePreferences.DEV_MODE && FModel.getPreferences().getPrefBoolean(FPref.DEV_UNLIMITED_LAND)) {
|
||||
player.canCheatPlayUnlimitedLands = true;
|
||||
@@ -33,6 +36,10 @@ public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactor
|
||||
}
|
||||
|
||||
public void hear(LobbyPlayer player, String message) {
|
||||
GuiBase.getInterface().hear(player, message);
|
||||
gui.hear(player, message);
|
||||
}
|
||||
|
||||
public IGuiBase getGui() {
|
||||
return this.gui;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,15 +17,19 @@
|
||||
*/
|
||||
package forge.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
@@ -34,11 +38,9 @@ import forge.game.zone.ZoneType;
|
||||
import forge.match.input.InputSelectTargets;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import forge.view.CardView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.StackItemView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -49,11 +51,12 @@ import java.util.Map;
|
||||
* @version $Id: TargetSelection.java 25148 2014-03-12 08:28:52Z swordshine $
|
||||
*/
|
||||
public class TargetSelection {
|
||||
private final PlayerControllerHuman controller;
|
||||
private final SpellAbility ability;
|
||||
|
||||
|
||||
public TargetSelection(final SpellAbility sa) {
|
||||
this.ability = sa;
|
||||
public TargetSelection(final PlayerControllerHuman controller, final SpellAbility currentAbility) {
|
||||
this.controller = controller;
|
||||
this.ability = currentAbility;
|
||||
}
|
||||
|
||||
private final TargetRestrictions getTgt() {
|
||||
@@ -70,7 +73,7 @@ public class TargetSelection {
|
||||
*/
|
||||
|
||||
public final boolean chooseTargets(Integer numTargets) {
|
||||
TargetRestrictions tgt = getTgt();
|
||||
final TargetRestrictions tgt = getTgt();
|
||||
final boolean canTarget = tgt != null && tgt.doesTarget();
|
||||
if (!canTarget) {
|
||||
throw new RuntimeException("TargetSelection.chooseTargets called for ability that does not target - " + ability);
|
||||
@@ -81,8 +84,8 @@ public class TargetSelection {
|
||||
final int maxTargets = numTargets != null ? numTargets.intValue() : tgt.getMaxTargets(ability.getHostCard(), ability);
|
||||
final int numTargeted = ability.getTargets().getNumTargeted();
|
||||
|
||||
boolean hasEnoughTargets = minTargets == 0 || numTargeted >= minTargets;
|
||||
boolean hasAllTargets = numTargeted == maxTargets && maxTargets > 0;
|
||||
final boolean hasEnoughTargets = minTargets == 0 || numTargeted >= minTargets;
|
||||
final boolean hasAllTargets = numTargeted == maxTargets && maxTargets > 0;
|
||||
if (maxTargets == 0) { return true; }
|
||||
|
||||
// if not enough targets chosen, cancel Ability
|
||||
@@ -105,8 +108,8 @@ public class TargetSelection {
|
||||
final boolean choiceResult;
|
||||
final boolean random = tgt.isRandomTarget();
|
||||
if (random) {
|
||||
List<GameObject> candidates = tgt.getAllCandidates(this.ability, true);
|
||||
GameObject choice = Aggregates.random(candidates);
|
||||
final List<GameEntity> candidates = tgt.getAllCandidates(this.ability, true);
|
||||
final GameObject choice = Aggregates.random(candidates);
|
||||
return ability.getTargets().add(choice);
|
||||
}
|
||||
else if (zone.size() == 1 && zone.get(0) == ZoneType.Stack) {
|
||||
@@ -120,7 +123,7 @@ public class TargetSelection {
|
||||
//if no valid cards to target and only one valid non-card, auto-target the non-card
|
||||
//this handles "target opponent" cards, along with any other cards that can only target a single non-card game entity
|
||||
//note that we don't handle auto-targeting cards this way since it's possible that the result will be undesirable
|
||||
List<GameObject> nonCardTargets = tgt.getAllCandidates(this.ability, true);
|
||||
List<GameEntity> nonCardTargets = tgt.getAllCandidates(this.ability, true);
|
||||
if (nonCardTargets.size() == 1) {
|
||||
return ability.getTargets().add(nonCardTargets.get(0));
|
||||
}
|
||||
@@ -131,16 +134,16 @@ public class TargetSelection {
|
||||
//to play a spell or activat an ability
|
||||
return ability.getTargets().add(validTargets.get(0));
|
||||
}
|
||||
final Map<Player, Object> playersWithValidTargets = new HashMap<Player, Object>();
|
||||
final Map<PlayerView, Object> playersWithValidTargets = Maps.newHashMap();
|
||||
for (Card card : validTargets) {
|
||||
playersWithValidTargets.put(card.getController(), null);
|
||||
playersWithValidTargets.put(controller.getPlayerView(card.getController()), null);
|
||||
}
|
||||
if (GuiBase.getInterface().openZones(zone, playersWithValidTargets)) {
|
||||
InputSelectTargets inp = new InputSelectTargets(validTargets, ability, mandatory);
|
||||
if (controller.getGui().openZones(zone, playersWithValidTargets)) {
|
||||
InputSelectTargets inp = new InputSelectTargets(controller, validTargets, ability, mandatory);
|
||||
inp.showAndWait();
|
||||
choiceResult = !inp.hasCancelled();
|
||||
bTargetingDone = inp.hasPressedOk();
|
||||
GuiBase.getInterface().restoreOldZones(playersWithValidTargets);
|
||||
controller.getGui().restoreOldZones(playersWithValidTargets);
|
||||
}
|
||||
else {
|
||||
// for every other case an all-purpose GuiChoose
|
||||
@@ -226,20 +229,21 @@ public class TargetSelection {
|
||||
// Send in a list of valid cards, and popup a choice box to target
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
final List<Card> crdsBattle = new ArrayList<Card>();
|
||||
final List<Card> crdsExile = new ArrayList<Card>();
|
||||
final List<Card> crdsGrave = new ArrayList<Card>();
|
||||
final List<Card> crdsLibrary = new ArrayList<Card>();
|
||||
final List<Card> crdsStack = new ArrayList<Card>();
|
||||
final List<Card> crdsAnte = new ArrayList<Card>();
|
||||
final List<CardView> crdsBattle = Lists.newArrayList();
|
||||
final List<CardView> crdsExile = Lists.newArrayList();
|
||||
final List<CardView> crdsGrave = Lists.newArrayList();
|
||||
final List<CardView> crdsLibrary = Lists.newArrayList();
|
||||
final List<CardView> crdsStack = Lists.newArrayList();
|
||||
final List<CardView> crdsAnte = Lists.newArrayList();
|
||||
for (final Card inZone : choices) {
|
||||
final CardView view = controller.getCardView(inZone);
|
||||
Zone zz = game.getZoneOf(inZone);
|
||||
if (zz.is(ZoneType.Battlefield)) crdsBattle.add(inZone);
|
||||
else if (zz.is(ZoneType.Exile)) crdsExile.add(inZone);
|
||||
else if (zz.is(ZoneType.Graveyard)) crdsGrave.add(inZone);
|
||||
else if (zz.is(ZoneType.Library)) crdsLibrary.add(inZone);
|
||||
else if (zz.is(ZoneType.Stack)) crdsStack.add(inZone);
|
||||
else if (zz.is(ZoneType.Ante)) crdsAnte.add(inZone);
|
||||
if (zz.is(ZoneType.Battlefield)) crdsBattle.add(view);
|
||||
else if (zz.is(ZoneType.Exile)) crdsExile.add(view);
|
||||
else if (zz.is(ZoneType.Graveyard)) crdsGrave.add(view);
|
||||
else if (zz.is(ZoneType.Library)) crdsLibrary.add(view);
|
||||
else if (zz.is(ZoneType.Stack)) crdsStack.add(view);
|
||||
else if (zz.is(ZoneType.Ante)) crdsAnte.add(view);
|
||||
}
|
||||
List<Object> choicesFiltered = new ArrayList<Object>();
|
||||
if (!crdsBattle.isEmpty()) {
|
||||
@@ -275,9 +279,9 @@ public class TargetSelection {
|
||||
|
||||
Object chosen = null;
|
||||
if (!choices.isEmpty() && mandatory) {
|
||||
chosen = SGuiChoose.one(getTgt().getVTSelection(), choicesFiltered);
|
||||
chosen = SGuiChoose.one(controller.getGui(), getTgt().getVTSelection(), choicesFiltered);
|
||||
} else {
|
||||
chosen = SGuiChoose.oneOrNone(getTgt().getVTSelection(), choicesFiltered);
|
||||
chosen = SGuiChoose.oneOrNone(controller.getGui(), getTgt().getVTSelection(), choicesFiltered);
|
||||
}
|
||||
if (chosen == null) {
|
||||
return false;
|
||||
@@ -286,9 +290,11 @@ public class TargetSelection {
|
||||
bTargetingDone = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (chosen instanceof Card )
|
||||
ability.getTargets().add((Card)chosen);
|
||||
|
||||
if (chosen instanceof CardView) {
|
||||
final Card chosenCard = controller.getCard((CardView) chosen);
|
||||
ability.getTargets().add(chosenCard);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -307,14 +313,13 @@ public class TargetSelection {
|
||||
final List<Object> selectOptions = new ArrayList<Object>();
|
||||
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
for (final SpellAbilityStackInstance si : game.getStack()) {
|
||||
SpellAbility abilityOnStack = si.getSpellAbility();
|
||||
if (ability.equals(abilityOnStack)) {
|
||||
// By peeking at stack item, target is set to its SI state. So set it back before adding targets
|
||||
ability.resetTargets();
|
||||
}
|
||||
else if (ability.canTargetSpellAbility(abilityOnStack)) {
|
||||
selectOptions.add(abilityOnStack);
|
||||
} else if (ability.canTargetSpellAbility(abilityOnStack)) {
|
||||
selectOptions.add(controller.getStackItemView(si));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,12 +337,12 @@ public class TargetSelection {
|
||||
// Not enough targets, cancel targeting
|
||||
return false;
|
||||
} else {
|
||||
final Object madeChoice = SGuiChoose.oneOrNone(message, selectOptions);
|
||||
final Object madeChoice = SGuiChoose.oneOrNone(controller.getGui(), message, selectOptions);
|
||||
if (madeChoice == null) {
|
||||
return false;
|
||||
}
|
||||
if (madeChoice instanceof SpellAbility) {
|
||||
ability.getTargets().add((SpellAbility)madeChoice);
|
||||
if (madeChoice instanceof StackItemView) {
|
||||
ability.getTargets().add(controller.getStackItem((StackItemView)madeChoice).getSpellAbility());
|
||||
} else // 'FINISH TARGETING' chosen
|
||||
bTargetingDone = true;
|
||||
}
|
||||
|
||||
@@ -17,133 +17,113 @@
|
||||
*/
|
||||
package forge.properties;
|
||||
|
||||
import forge.GuiBase;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ForgeConstants {
|
||||
public static final String ASSETS_DIR = GuiBase.getInterface().getAssetsDir();
|
||||
public static final String PROFILE_FILE = ASSETS_DIR + "forge.profile.properties";
|
||||
public static final String PROFILE_TEMPLATE_FILE = PROFILE_FILE + ".example";
|
||||
|
||||
public static final String RES_DIR = ASSETS_DIR + "res/";
|
||||
public static final String LISTS_DIR = RES_DIR + "lists/";
|
||||
public static final String KEYWORD_LIST_FILE = LISTS_DIR + "NonStackingKWList.txt";
|
||||
public static final String TYPE_LIST_FILE = LISTS_DIR + "TypeLists.txt";
|
||||
public static final String IMAGE_LIST_TOKENS_FILE = LISTS_DIR + "token-images.txt";
|
||||
public static final String IMAGE_LIST_QUEST_OPPONENT_ICONS_FILE = LISTS_DIR + "quest-opponent-icons.txt";
|
||||
public static final String IMAGE_LIST_QUEST_PET_SHOP_ICONS_FILE = LISTS_DIR + "quest-pet-shop-icons.txt";
|
||||
public static final String IMAGE_LIST_QUEST_TOKENS_FILE = LISTS_DIR + "quest-pet-token-images.txt";
|
||||
public static final String IMAGE_LIST_QUEST_BOOSTERS_FILE = LISTS_DIR + "booster-images.txt";
|
||||
public static final String IMAGE_LIST_QUEST_FATPACKS_FILE = LISTS_DIR + "fatpack-images.txt";
|
||||
public static final String IMAGE_LIST_QUEST_BOOSTERBOXES_FILE = LISTS_DIR + "boosterbox-images.txt";
|
||||
public static final String IMAGE_LIST_QUEST_PRECONS_FILE = LISTS_DIR + "precon-images.txt";
|
||||
public static final String IMAGE_LIST_QUEST_TOURNAMENTPACKS_FILE = LISTS_DIR + "tournamentpack-images.txt";
|
||||
public static void init(final String assetsDir) {
|
||||
ASSETS_DIR = assetsDir;
|
||||
PROFILE_FILE = ASSETS_DIR + "forge.profile.properties";
|
||||
PROFILE_TEMPLATE_FILE = PROFILE_FILE + ".example";
|
||||
|
||||
public static final String CHANGES_FILE = ASSETS_DIR + "CHANGES.txt";
|
||||
public static final String LICENSE_FILE = ASSETS_DIR + "LICENSE.txt";
|
||||
public static final String README_FILE = ASSETS_DIR + "README.txt";
|
||||
public static final String HOWTO_FILE = RES_DIR + "howto.txt";
|
||||
RES_DIR = ASSETS_DIR + "res/";
|
||||
LISTS_DIR = RES_DIR + "lists/";
|
||||
|
||||
public static final String DRAFT_DIR = RES_DIR + "draft/";
|
||||
public static final String DRAFT_RANKINGS_FILE = DRAFT_DIR + "rankings.txt";
|
||||
public static final String SEALED_DIR = RES_DIR + "sealed/";
|
||||
public static final String CARD_DATA_DIR = RES_DIR + "cardsfolder/";
|
||||
public static final String EDITIONS_DIR = RES_DIR + "editions/";
|
||||
public static final String BLOCK_DATA_DIR = RES_DIR + "blockdata/";
|
||||
public static final String DECK_CUBE_DIR = RES_DIR + "cube/";
|
||||
public static final String AI_PROFILE_DIR = RES_DIR + "ai/";
|
||||
public static final String SOUND_DIR = RES_DIR + "sound/";
|
||||
public static final String MUSIC_DIR = RES_DIR + "music/";
|
||||
public static final String LANG_DIR = RES_DIR + "languages/";
|
||||
public static final String EFFECTS_DIR = RES_DIR + "effects/";
|
||||
KEYWORD_LIST_FILE = LISTS_DIR + "NonStackingKWList.txt";
|
||||
TYPE_LIST_FILE = LISTS_DIR + "TypeLists.txt";
|
||||
IMAGE_LIST_TOKENS_FILE = LISTS_DIR + "token-images.txt";
|
||||
IMAGE_LIST_QUEST_OPPONENT_ICONS_FILE = LISTS_DIR + "quest-opponent-icons.txt";
|
||||
IMAGE_LIST_QUEST_PET_SHOP_ICONS_FILE = LISTS_DIR + "quest-pet-shop-icons.txt";
|
||||
IMAGE_LIST_QUEST_TOKENS_FILE = LISTS_DIR + "quest-pet-token-images.txt";
|
||||
IMAGE_LIST_QUEST_BOOSTERS_FILE = LISTS_DIR + "booster-images.txt";
|
||||
IMAGE_LIST_QUEST_FATPACKS_FILE = LISTS_DIR + "fatpack-images.txt";
|
||||
IMAGE_LIST_QUEST_BOOSTERBOXES_FILE = LISTS_DIR + "boosterbox-images.txt";
|
||||
IMAGE_LIST_QUEST_PRECONS_FILE = LISTS_DIR + "precon-images.txt";
|
||||
IMAGE_LIST_QUEST_TOURNAMENTPACKS_FILE = LISTS_DIR + "tournamentpack-images.txt";
|
||||
|
||||
private static final String QUEST_DIR = RES_DIR + "quest/";
|
||||
public static final String QUEST_WORLD_DIR = QUEST_DIR + "world/";
|
||||
public static final String QUEST_PRECON_DIR = QUEST_DIR + "precons/";
|
||||
public static final String PRICES_BOOSTER_FILE = QUEST_DIR + "booster-prices.txt";
|
||||
public static final String BAZAAR_DIR = QUEST_DIR + "bazaar/";
|
||||
public static final String BAZAAR_INDEX_FILE = BAZAAR_DIR + "index.xml";
|
||||
public static final String DEFAULT_DUELS_DIR = QUEST_DIR + "duels";
|
||||
public static final String DEFAULT_CHALLENGES_DIR = QUEST_DIR + "challenges";
|
||||
public static final String THEMES_DIR = QUEST_DIR + "themes";
|
||||
CHANGES_FILE = ASSETS_DIR + "CHANGES.txt";
|
||||
LICENSE_FILE = ASSETS_DIR + "LICENSE.txt";
|
||||
README_FILE = ASSETS_DIR + "README.txt";
|
||||
HOWTO_FILE = RES_DIR + "howto.txt";
|
||||
|
||||
public static final String SKINS_DIR = RES_DIR + "skins/";
|
||||
public static final String DEFAULT_SKINS_DIR = SKINS_DIR + "default/";
|
||||
//don't associate these skin files with a directory since skin directory will be determined later
|
||||
public static final String SPRITE_ICONS_FILE = "sprite_icons.png";
|
||||
public static final String SPRITE_FOILS_FILE = "sprite_foils.png";
|
||||
public static final String SPRITE_OLD_FOILS_FILE = "sprite_old_foils.png";
|
||||
public static final String SPRITE_AVATARS_FILE = "sprite_avatars.png";
|
||||
public static final String FONT_FILE = "font1.ttf";
|
||||
public static final String SPLASH_BG_FILE = "bg_splash.png";
|
||||
public static final String MATCH_BG_FILE = "bg_match.jpg";
|
||||
public static final String TEXTURE_BG_FILE = "bg_texture.jpg";
|
||||
public static final String DRAFT_DECK_IMG_FILE = "bg_draft_deck.png";
|
||||
public static final String TROPHY_CASE_TOP_FILE = "bg_trophy_case_top.png";
|
||||
public static final String TROPHY_CASE_SHELF_FILE = "bg_trophy_case_shelf.png";
|
||||
DRAFT_DIR = RES_DIR + "draft/";
|
||||
DRAFT_RANKINGS_FILE = DRAFT_DIR + "rankings.txt";
|
||||
SEALED_DIR = RES_DIR + "sealed/";
|
||||
CARD_DATA_DIR = RES_DIR + "cardsfolder/";
|
||||
EDITIONS_DIR = RES_DIR + "editions/";
|
||||
BLOCK_DATA_DIR = RES_DIR + "blockdata/";
|
||||
DECK_CUBE_DIR = RES_DIR + "cube/";
|
||||
AI_PROFILE_DIR = RES_DIR + "ai/";
|
||||
SOUND_DIR = RES_DIR + "sound/";
|
||||
MUSIC_DIR = RES_DIR + "music/";
|
||||
LANG_DIR = RES_DIR + "languages/";
|
||||
EFFECTS_DIR = RES_DIR + "effects/";
|
||||
|
||||
QUEST_DIR = RES_DIR + "quest/";
|
||||
QUEST_WORLD_DIR = QUEST_DIR + "world/";
|
||||
QUEST_PRECON_DIR = QUEST_DIR + "precons/";
|
||||
PRICES_BOOSTER_FILE = QUEST_DIR + "booster-prices.txt";
|
||||
BAZAAR_DIR = QUEST_DIR + "bazaar/";
|
||||
BAZAAR_INDEX_FILE = BAZAAR_DIR + "index.xml";
|
||||
DEFAULT_DUELS_DIR = QUEST_DIR + "duels";
|
||||
DEFAULT_CHALLENGES_DIR = QUEST_DIR + "challenges";
|
||||
THEMES_DIR = QUEST_DIR + "themes";
|
||||
|
||||
SKINS_DIR = RES_DIR + "skins/";
|
||||
DEFAULT_SKINS_DIR = SKINS_DIR + "default/";
|
||||
|
||||
// data tree roots
|
||||
public static final String USER_DIR;
|
||||
public static final String CACHE_DIR;
|
||||
public static final String CACHE_CARD_PICS_DIR;
|
||||
public static final Map<String, String> CACHE_CARD_PICS_SUBDIR;
|
||||
public static final int SERVER_PORT_NUMBER;
|
||||
static {
|
||||
ForgeProfileProperties.load();
|
||||
USER_DIR = ForgeProfileProperties.getUserDir();
|
||||
CACHE_DIR = ForgeProfileProperties.getCacheDir();
|
||||
CACHE_CARD_PICS_DIR = ForgeProfileProperties.getCardPicsDir();
|
||||
CACHE_CARD_PICS_SUBDIR = Collections.unmodifiableMap(ForgeProfileProperties.getCardPicsSubDirs());
|
||||
SERVER_PORT_NUMBER = ForgeProfileProperties.getServerPort();
|
||||
}
|
||||
|
||||
// data that is only in the profile dirs
|
||||
public static final String USER_QUEST_DIR = USER_DIR + "quest/";
|
||||
public static final String USER_PREFS_DIR = USER_DIR + "preferences/";
|
||||
public static final String USER_GAMES_DIR = USER_DIR + "games/";
|
||||
public static final String LOG_FILE = USER_DIR + "forge.log";
|
||||
public static final String DECK_BASE_DIR = USER_DIR + "decks/";
|
||||
public static final String ACHIEVEMENTS_DIR = USER_DIR + "achievements/";
|
||||
public static final String DECK_CONSTRUCTED_DIR = DECK_BASE_DIR + "constructed/";
|
||||
public static final String DECK_DRAFT_DIR = DECK_BASE_DIR + "draft/";
|
||||
public static final String DECK_WINSTON_DIR = DECK_BASE_DIR + "winston/";
|
||||
public static final String DECK_SEALED_DIR = DECK_BASE_DIR + "sealed/";
|
||||
public static final String DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme/";
|
||||
public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar/";
|
||||
public static final String DECK_COMMANDER_DIR = DECK_BASE_DIR + "commander/";
|
||||
public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves/";
|
||||
public static final String MAIN_PREFS_FILE = USER_PREFS_DIR + "forge.preferences";
|
||||
public static final String CARD_PREFS_FILE = USER_PREFS_DIR + "card.preferences";
|
||||
public static final String DECK_PREFS_FILE = USER_PREFS_DIR + "deck.preferences";
|
||||
public static final String QUEST_PREFS_FILE = USER_PREFS_DIR + "quest.preferences";
|
||||
public static final String ITEM_VIEW_PREFS_FILE = USER_PREFS_DIR + "item_view.preferences";
|
||||
USER_QUEST_DIR = USER_DIR + "quest/";
|
||||
USER_PREFS_DIR = USER_DIR + "preferences/";
|
||||
USER_GAMES_DIR = USER_DIR + "games/";
|
||||
LOG_FILE = USER_DIR + "forge.log";
|
||||
DECK_BASE_DIR = USER_DIR + "decks/";
|
||||
ACHIEVEMENTS_DIR = USER_DIR + "achievements/";
|
||||
DECK_CONSTRUCTED_DIR = DECK_BASE_DIR + "constructed/";
|
||||
DECK_DRAFT_DIR = DECK_BASE_DIR + "draft/";
|
||||
DECK_WINSTON_DIR = DECK_BASE_DIR + "winston/";
|
||||
DECK_SEALED_DIR = DECK_BASE_DIR + "sealed/";
|
||||
DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme/";
|
||||
DECK_PLANE_DIR = DECK_BASE_DIR + "planar/";
|
||||
DECK_COMMANDER_DIR = DECK_BASE_DIR + "commander/";
|
||||
QUEST_SAVE_DIR = USER_QUEST_DIR + "saves/";
|
||||
MAIN_PREFS_FILE = USER_PREFS_DIR + "forge.preferences";
|
||||
CARD_PREFS_FILE = USER_PREFS_DIR + "card.preferences";
|
||||
DECK_PREFS_FILE = USER_PREFS_DIR + "deck.preferences";
|
||||
QUEST_PREFS_FILE = USER_PREFS_DIR + "quest.preferences";
|
||||
ITEM_VIEW_PREFS_FILE = USER_PREFS_DIR + "item_view.preferences";
|
||||
ACHIEVEMENTS_FILE = USER_PREFS_DIR + "achievements.xml";
|
||||
|
||||
// data that has defaults in the program dir but overrides/additions in the user dir
|
||||
private static final String _DEFAULTS_DIR = RES_DIR + "defaults/";
|
||||
public static final String NO_CARD_FILE = _DEFAULTS_DIR + "no_card.jpg";
|
||||
public static final FileLocation WINDOW_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "window.xml");
|
||||
public static final FileLocation MATCH_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "match.xml");
|
||||
public static final FileLocation WORKSHOP_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "workshop.xml");
|
||||
public static final FileLocation EDITOR_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.xml");
|
||||
public static final FileLocation GAUNTLET_DIR = new FileLocation(_DEFAULTS_DIR, USER_DIR, "gauntlet/");
|
||||
_DEFAULTS_DIR = RES_DIR + "defaults/";
|
||||
NO_CARD_FILE = _DEFAULTS_DIR + "no_card.jpg";
|
||||
|
||||
// data that is only in the cached dir
|
||||
private static final String PICS_DIR = CACHE_DIR + "pics/";
|
||||
public static final String DB_DIR = CACHE_DIR + "db/";
|
||||
public static final String FONTS_DIR = CACHE_DIR + "fonts/";
|
||||
public static final String CACHE_TOKEN_PICS_DIR = PICS_DIR + "tokens/";
|
||||
public static final String CACHE_ICON_PICS_DIR = PICS_DIR + "icons/";
|
||||
public static final String CACHE_SYMBOLS_DIR = PICS_DIR + "symbols/";
|
||||
public static final String CACHE_BOOSTER_PICS_DIR = PICS_DIR + "boosters/";
|
||||
public static final String CACHE_FATPACK_PICS_DIR = PICS_DIR + "fatpacks/";
|
||||
public static final String CACHE_BOOSTERBOX_PICS_DIR = PICS_DIR + "boosterboxes/";
|
||||
public static final String CACHE_PRECON_PICS_DIR = PICS_DIR + "precons/";
|
||||
public static final String CACHE_TOURNAMENTPACK_PICS_DIR = PICS_DIR + "tournamentpacks/";
|
||||
public static final String QUEST_CARD_PRICE_FILE = DB_DIR + "all-prices.txt";
|
||||
WINDOW_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "window.xml");
|
||||
MATCH_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "match.xml");
|
||||
WORKSHOP_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "workshop.xml");
|
||||
EDITOR_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.xml");
|
||||
GAUNTLET_DIR = new FileLocation(_DEFAULTS_DIR, USER_DIR, "gauntlet/");
|
||||
|
||||
public static final String[] PROFILE_DIRS = {
|
||||
PICS_DIR = CACHE_DIR + "pics/";
|
||||
DB_DIR = CACHE_DIR + "db/";
|
||||
FONTS_DIR = CACHE_DIR + "fonts/";
|
||||
CACHE_TOKEN_PICS_DIR = PICS_DIR + "tokens/";
|
||||
CACHE_ICON_PICS_DIR = PICS_DIR + "icons/";
|
||||
CACHE_SYMBOLS_DIR = PICS_DIR + "symbols/";
|
||||
CACHE_BOOSTER_PICS_DIR = PICS_DIR + "boosters/";
|
||||
CACHE_FATPACK_PICS_DIR = PICS_DIR + "fatpacks/";
|
||||
CACHE_BOOSTERBOX_PICS_DIR = PICS_DIR + "boosterboxes/";
|
||||
CACHE_PRECON_PICS_DIR = PICS_DIR + "precons/";
|
||||
CACHE_TOURNAMENTPACK_PICS_DIR = PICS_DIR + "tournamentpacks/";
|
||||
QUEST_CARD_PRICE_FILE = DB_DIR + "all-prices.txt";;
|
||||
|
||||
PROFILE_DIRS = new String[] {
|
||||
USER_DIR,
|
||||
CACHE_DIR,
|
||||
CACHE_CARD_PICS_DIR,
|
||||
@@ -163,7 +143,123 @@ public final class ForgeConstants {
|
||||
CACHE_BOOSTERBOX_PICS_DIR,
|
||||
CACHE_PRECON_PICS_DIR,
|
||||
CACHE_TOURNAMENTPACK_PICS_DIR };
|
||||
}
|
||||
|
||||
public static String ASSETS_DIR;
|
||||
public static String PROFILE_FILE;
|
||||
public static String PROFILE_TEMPLATE_FILE;
|
||||
|
||||
public static String RES_DIR;
|
||||
public static String LISTS_DIR;
|
||||
public static String KEYWORD_LIST_FILE;
|
||||
public static String TYPE_LIST_FILE;
|
||||
public static String IMAGE_LIST_TOKENS_FILE;
|
||||
public static String IMAGE_LIST_QUEST_OPPONENT_ICONS_FILE;
|
||||
public static String IMAGE_LIST_QUEST_PET_SHOP_ICONS_FILE;
|
||||
public static String IMAGE_LIST_QUEST_TOKENS_FILE;
|
||||
public static String IMAGE_LIST_QUEST_BOOSTERS_FILE;
|
||||
public static String IMAGE_LIST_QUEST_FATPACKS_FILE;
|
||||
public static String IMAGE_LIST_QUEST_BOOSTERBOXES_FILE;
|
||||
public static String IMAGE_LIST_QUEST_PRECONS_FILE;
|
||||
public static String IMAGE_LIST_QUEST_TOURNAMENTPACKS_FILE;
|
||||
|
||||
public static String CHANGES_FILE;
|
||||
public static String LICENSE_FILE;
|
||||
public static String README_FILE;
|
||||
public static String HOWTO_FILE;
|
||||
|
||||
public static String DRAFT_DIR;
|
||||
public static String DRAFT_RANKINGS_FILE;
|
||||
public static String SEALED_DIR;
|
||||
public static String CARD_DATA_DIR;
|
||||
public static String EDITIONS_DIR;
|
||||
public static String BLOCK_DATA_DIR;
|
||||
public static String DECK_CUBE_DIR;
|
||||
public static String AI_PROFILE_DIR;
|
||||
public static String SOUND_DIR;
|
||||
public static String MUSIC_DIR;
|
||||
public static String LANG_DIR;
|
||||
public static String EFFECTS_DIR;
|
||||
|
||||
private static String QUEST_DIR;
|
||||
public static String QUEST_WORLD_DIR;
|
||||
public static String QUEST_PRECON_DIR;
|
||||
public static String PRICES_BOOSTER_FILE;
|
||||
public static String BAZAAR_DIR;
|
||||
public static String BAZAAR_INDEX_FILE;
|
||||
public static String DEFAULT_DUELS_DIR;
|
||||
public static String DEFAULT_CHALLENGES_DIR;
|
||||
public static String THEMES_DIR;
|
||||
|
||||
public static String SKINS_DIR;
|
||||
public static String DEFAULT_SKINS_DIR;
|
||||
//don't associate these skin files with a directory since skin directory will be determined later
|
||||
public static final String SPRITE_ICONS_FILE = "sprite_icons.png";
|
||||
public static final String SPRITE_FOILS_FILE = "sprite_foils.png";
|
||||
public static final String SPRITE_OLD_FOILS_FILE = "sprite_old_foils.png";
|
||||
public static final String SPRITE_AVATARS_FILE = "sprite_avatars.png";
|
||||
public static final String FONT_FILE = "font1.ttf";
|
||||
public static final String SPLASH_BG_FILE = "bg_splash.png";
|
||||
public static final String MATCH_BG_FILE = "bg_match.jpg";
|
||||
public static final String TEXTURE_BG_FILE = "bg_texture.jpg";
|
||||
public static final String DRAFT_DECK_IMG_FILE = "bg_draft_deck.png";
|
||||
public static final String TROPHY_CASE_TOP_FILE = "bg_trophy_case_top.png";
|
||||
public static final String TROPHY_CASE_SHELF_FILE = "bg_trophy_case_shelf.png";
|
||||
|
||||
// data tree roots
|
||||
public static String USER_DIR;
|
||||
public static String CACHE_DIR;
|
||||
public static String CACHE_CARD_PICS_DIR;
|
||||
public static Map<String, String> CACHE_CARD_PICS_SUBDIR;
|
||||
public static int SERVER_PORT_NUMBER;
|
||||
|
||||
// data that is only in the profile dirs
|
||||
public static String USER_QUEST_DIR;
|
||||
public static String USER_PREFS_DIR;
|
||||
public static String USER_GAMES_DIR;
|
||||
public static String LOG_FILE;
|
||||
public static String DECK_BASE_DIR;
|
||||
public static String ACHIEVEMENTS_DIR;
|
||||
public static String DECK_CONSTRUCTED_DIR;
|
||||
public static String DECK_DRAFT_DIR;
|
||||
public static String DECK_WINSTON_DIR;
|
||||
public static String DECK_SEALED_DIR;
|
||||
public static String DECK_SCHEME_DIR;
|
||||
public static String DECK_PLANE_DIR;
|
||||
public static String DECK_COMMANDER_DIR;
|
||||
public static String QUEST_SAVE_DIR;
|
||||
public static String MAIN_PREFS_FILE;
|
||||
public static String CARD_PREFS_FILE;
|
||||
public static String DECK_PREFS_FILE;
|
||||
public static String QUEST_PREFS_FILE;
|
||||
public static String ITEM_VIEW_PREFS_FILE;
|
||||
public static String ACHIEVEMENTS_FILE;
|
||||
|
||||
// data that has defaults in the program dir but overrides/additions in the user dir
|
||||
private static String _DEFAULTS_DIR;
|
||||
public static String NO_CARD_FILE;
|
||||
public static FileLocation WINDOW_LAYOUT_FILE;
|
||||
public static FileLocation MATCH_LAYOUT_FILE;
|
||||
public static FileLocation WORKSHOP_LAYOUT_FILE;
|
||||
public static FileLocation EDITOR_LAYOUT_FILE;
|
||||
public static FileLocation GAUNTLET_DIR;
|
||||
|
||||
// data that is only in the cached dir
|
||||
private static String PICS_DIR;
|
||||
public static String DB_DIR;
|
||||
public static String FONTS_DIR;
|
||||
public static String CACHE_TOKEN_PICS_DIR;
|
||||
public static String CACHE_ICON_PICS_DIR;
|
||||
public static String CACHE_SYMBOLS_DIR;
|
||||
public static String CACHE_BOOSTER_PICS_DIR;
|
||||
public static String CACHE_FATPACK_PICS_DIR;
|
||||
public static String CACHE_BOOSTERBOX_PICS_DIR;
|
||||
public static String CACHE_PRECON_PICS_DIR;
|
||||
public static String CACHE_TOURNAMENTPACK_PICS_DIR;
|
||||
public static String QUEST_CARD_PRICE_FILE;
|
||||
|
||||
public static String[] PROFILE_DIRS;
|
||||
|
||||
// URLs
|
||||
private static final String URL_CARDFORGE = "http://cardforge.org";
|
||||
public static final String URL_DRAFT_UPLOAD = URL_CARDFORGE + "/draftAI/submitDraftData.php";
|
||||
|
||||
@@ -17,25 +17,26 @@
|
||||
*/
|
||||
package forge.properties;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
|
||||
/**
|
||||
* Determines the user data and cache dirs, first looking at the specified file for overrides
|
||||
* then falling back to platform-specific defaults. Resulting dir strings are guaranteed to end in a slash
|
||||
* so they can be easily appended with further path elements.
|
||||
*/
|
||||
public class ForgeProfileProperties {
|
||||
private static boolean isRunningOnDesktop;
|
||||
private static String userDir;
|
||||
private static String cacheDir;
|
||||
private static String cardPicsDir;
|
||||
@@ -52,6 +53,10 @@ public class ForgeProfileProperties {
|
||||
//prevent initializing static class
|
||||
}
|
||||
|
||||
public static void init(final IGuiBase gui) {
|
||||
isRunningOnDesktop = gui.isRunningOnDesktop();
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Properties props = new Properties();
|
||||
File propFile = new File(ForgeConstants.PROFILE_FILE);
|
||||
@@ -144,7 +149,7 @@ public class ForgeProfileProperties {
|
||||
|
||||
// returns a pair <userDir, cacheDir>
|
||||
private static Pair<String, String> getDefaultDirs() {
|
||||
if (!GuiBase.getInterface().isRunningOnDesktop()) { //special case for mobile devices
|
||||
if (isRunningOnDesktop) { //special case for mobile devices
|
||||
String assetsDir = ForgeConstants.ASSETS_DIR;
|
||||
return Pair.of(assetsDir + "data" + File.separator, assetsDir + "cache" + File.separator);
|
||||
}
|
||||
|
||||
@@ -24,16 +24,17 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.game.GameFormat;
|
||||
import forge.game.event.GameEvent;
|
||||
import forge.game.event.GameEventMulligan;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.model.FModel;
|
||||
@@ -57,6 +58,7 @@ import forge.util.storage.StorageBase;
|
||||
*/
|
||||
public class QuestController {
|
||||
|
||||
private final IGuiBase gui;
|
||||
private QuestData model;
|
||||
// gadgets
|
||||
|
||||
@@ -99,7 +101,15 @@ public class QuestController {
|
||||
|
||||
/** */
|
||||
public static final int MAX_PET_SLOTS = 2;
|
||||
|
||||
|
||||
public QuestController(final IGuiBase gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
public final IGuiBase getGui() {
|
||||
return this.gui;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO: Write javadoc for this method.
|
||||
@@ -471,7 +481,7 @@ public class QuestController {
|
||||
if (ev instanceof GameEventMulligan) {
|
||||
GameEventMulligan mev = (GameEventMulligan) ev;
|
||||
// First mulligan is free
|
||||
if (mev.player.getLobbyPlayer() == GuiBase.getInterface().getQuestPlayer()
|
||||
if (mev.player.getLobbyPlayer() == gui.getGuiPlayer()
|
||||
&& getAssets().hasItem(QuestItemType.SLEIGHT) && mev.player.getStats().getMulliganCount() < 7) {
|
||||
mev.player.drawCard();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package forge.quest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.deck.DeckSection;
|
||||
@@ -10,13 +12,11 @@ import forge.game.GameRules;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QuestDraftUtils {
|
||||
private static List<DraftMatchup> matchups = new ArrayList<DraftMatchup>();
|
||||
|
||||
@@ -24,11 +24,11 @@ public class QuestDraftUtils {
|
||||
public static boolean aiMatchInProgress = false;
|
||||
private static boolean waitForUserInput = false;
|
||||
|
||||
public static void continueMatch(Game lastGame) {
|
||||
public static void continueMatch(final Game lastGame, final IGuiBase gui) {
|
||||
if (lastGame.getMatch().isMatchOver()) {
|
||||
matchInProgress = false;
|
||||
}
|
||||
GuiBase.getInterface().continueMatch(matchInProgress ? lastGame.getMatch() : null);
|
||||
gui.continueMatch(matchInProgress ? lastGame.getMatch() : null);
|
||||
}
|
||||
|
||||
public static void completeDraft(DeckGroup finishedDraft) {
|
||||
@@ -59,7 +59,7 @@ public class QuestDraftUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void startNextMatch() {
|
||||
public static void startNextMatch(final IGuiBase gui) {
|
||||
|
||||
if (matchups.size() > 0) {
|
||||
return;
|
||||
@@ -82,38 +82,38 @@ public class QuestDraftUtils {
|
||||
switch (currentSet) {
|
||||
|
||||
case 7:
|
||||
addMatchup(0, 1, draft);
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
addMatchup(0, 1, draft, gui);
|
||||
addMatchup(2, 3, draft, gui);
|
||||
addMatchup(4, 5, draft, gui);
|
||||
addMatchup(6, 7, draft, gui);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
addMatchup(2, 3, draft, gui);
|
||||
addMatchup(4, 5, draft, gui);
|
||||
addMatchup(6, 7, draft, gui);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
addMatchup(4, 5, draft, gui);
|
||||
addMatchup(6, 7, draft, gui);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
addMatchup(6, 7, draft);
|
||||
addMatchup(6, 7, draft, gui);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
addMatchup(8, 9, draft);
|
||||
addMatchup(10, 11, draft);
|
||||
addMatchup(8, 9, draft, gui);
|
||||
addMatchup(10, 11, draft, gui);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
addMatchup(10, 11, draft);
|
||||
addMatchup(10, 11, draft, gui);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
addMatchup(12, 13, draft);
|
||||
addMatchup(12, 13, draft, gui);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
@@ -122,11 +122,11 @@ public class QuestDraftUtils {
|
||||
|
||||
}
|
||||
|
||||
update();
|
||||
update(gui);
|
||||
|
||||
}
|
||||
|
||||
private static void addMatchup(final int player1, final int player2, final QuestEventDraft draft) {
|
||||
private static void addMatchup(final int player1, final int player2, final QuestEventDraft draft, final IGuiBase gui) {
|
||||
|
||||
DraftMatchup matchup = new DraftMatchup();
|
||||
DeckGroup decks = FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME);
|
||||
@@ -145,12 +145,12 @@ public class QuestDraftUtils {
|
||||
if (humanIndex > -1) {
|
||||
|
||||
matchup.hasHumanPlayer = true;
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getHumanDeck()).setPlayer(GuiBase.getInterface().getGuiPlayer()));
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getHumanDeck()).setPlayer(gui.getGuiPlayer()));
|
||||
|
||||
int aiName = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
|
||||
|
||||
int aiDeckIndex = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GuiBase.getInterface().createAiPlayer(draft.getAINames()[aiName], draft.getAIIcons()[aiName])));
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(gui.createAiPlayer(draft.getAINames()[aiName], draft.getAIIcons()[aiName])));
|
||||
|
||||
} else {
|
||||
|
||||
@@ -158,17 +158,17 @@ public class QuestDraftUtils {
|
||||
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(GuiBase.getInterface().createAiPlayer(draft.getAINames()[aiName1], draft.getAIIcons()[aiName1])));
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(gui.createAiPlayer(draft.getAINames()[aiName1], draft.getAIIcons()[aiName1])));
|
||||
|
||||
aiDeckIndex = Integer.parseInt(draft.getStandings()[player2]) - 1;
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GuiBase.getInterface().createAiPlayer(draft.getAINames()[aiName2], draft.getAIIcons()[aiName2])));
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(gui.createAiPlayer(draft.getAINames()[aiName2], draft.getAIIcons()[aiName2])));
|
||||
|
||||
}
|
||||
|
||||
matchups.add(matchup);
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
public static void update(final IGuiBase gui) {
|
||||
if (matchups.isEmpty()) {
|
||||
if (!matchInProgress) {
|
||||
aiMatchInProgress = false;
|
||||
@@ -184,14 +184,14 @@ public class QuestDraftUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
GuiBase.getInterface().enableOverlay();
|
||||
gui.enableOverlay();
|
||||
|
||||
DraftMatchup nextMatch = matchups.remove(0);
|
||||
|
||||
matchInProgress = true;
|
||||
|
||||
if (!nextMatch.hasHumanPlayer) {
|
||||
GuiBase.getInterface().disableOverlay();
|
||||
gui.disableOverlay();
|
||||
waitForUserInput = false;
|
||||
aiMatchInProgress = true;
|
||||
}
|
||||
@@ -208,17 +208,17 @@ public class QuestDraftUtils {
|
||||
rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE);
|
||||
|
||||
final Match match = new Match(rules, nextMatch.matchStarter);
|
||||
FThreads.invokeInEdtLater(new Runnable(){
|
||||
FThreads.invokeInEdtLater(gui, new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
GuiBase.getInterface().startGame(match);
|
||||
gui.startGame(match);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void continueMatches() {
|
||||
public static void continueMatches(final IGuiBase gui) {
|
||||
waitForUserInput = false;
|
||||
update();
|
||||
update(gui);
|
||||
}
|
||||
|
||||
private static class DraftMatchup {
|
||||
|
||||
@@ -7,22 +7,28 @@ import org.apache.commons.lang3.StringUtils;
|
||||
*
|
||||
*/
|
||||
public enum QuestEventDifficulty {
|
||||
EASY("easy"),
|
||||
MEDIUM("medium"),
|
||||
HARD("hard"),
|
||||
EXPERT("very hard");
|
||||
|
||||
String inFile;
|
||||
|
||||
private QuestEventDifficulty(String storedInFile) {
|
||||
EASY ("easy", 1. ),
|
||||
MEDIUM("medium", 1.5),
|
||||
HARD ("hard", 2. ),
|
||||
EXPERT("very hard", 3. );
|
||||
|
||||
private final String inFile;
|
||||
private final double multiplier;
|
||||
|
||||
private QuestEventDifficulty(final String storedInFile, final double multiplier) {
|
||||
inFile = storedInFile;
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
|
||||
public final String getTitle() {
|
||||
return inFile;
|
||||
}
|
||||
|
||||
public static QuestEventDifficulty fromString(String src) {
|
||||
|
||||
public final double getMultiplier() {
|
||||
return this.multiplier;
|
||||
}
|
||||
|
||||
public static QuestEventDifficulty fromString(final String src) {
|
||||
if ( StringUtils.isBlank(src) )
|
||||
return MEDIUM; // player have custom files, that didn't specify a valid difficulty
|
||||
|
||||
|
||||
@@ -17,7 +17,15 @@
|
||||
*/
|
||||
package forge.quest;
|
||||
|
||||
import forge.GuiBase;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardEdition.CardInSet;
|
||||
import forge.card.CardRarity;
|
||||
@@ -25,6 +33,7 @@ import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.PaperCard;
|
||||
import forge.limited.BoosterDraft;
|
||||
@@ -36,9 +45,6 @@ import forge.quest.io.ReadPriceList;
|
||||
import forge.util.NameGenerator;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* QuestEvent.
|
||||
@@ -656,18 +662,18 @@ public class QuestEventDraft {
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
public boolean canEnter() {
|
||||
long creditsAvailable = FModel.getQuest().getAssets().getCredits();
|
||||
return creditsAvailable < getEntryFee();
|
||||
}
|
||||
|
||||
public BoosterDraft enter() {
|
||||
FModel.getQuest().getAchievements().setCurrentDraft(this);
|
||||
FModel.getQuest().getAssets().subtractCredits(getEntryFee());
|
||||
return BoosterDraft.createDraft(LimitedPoolType.Block, FModel.getBlocks().get(getBlock()), getBoosterConfiguration());
|
||||
}
|
||||
|
||||
|
||||
public boolean canEnter() {
|
||||
long creditsAvailable = FModel.getQuest().getAssets().getCredits();
|
||||
return creditsAvailable < getEntryFee();
|
||||
}
|
||||
|
||||
public BoosterDraft enter(final IGuiBase gui) {
|
||||
FModel.getQuest().getAchievements().setCurrentDraft(this);
|
||||
FModel.getQuest().getAssets().subtractCredits(getEntryFee());
|
||||
return BoosterDraft.createDraft(gui, LimitedPoolType.Block, FModel.getBlocks().get(getBlock()), getBoosterConfiguration());
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
@@ -745,14 +751,14 @@ public class QuestEventDraft {
|
||||
public static QuestEventDraft getRandomDraftOrNull(final QuestController quest) {
|
||||
List<CardBlock> possibleBlocks = getAvailableBlocks(quest);
|
||||
Collections.shuffle(possibleBlocks);
|
||||
return getDraftOrNull(possibleBlocks.get(0));
|
||||
return getDraftOrNull(quest, possibleBlocks.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a draft event based on the provided block.
|
||||
* @return The created draft or null in the event no draft could be created.
|
||||
*/
|
||||
public static QuestEventDraft getDraftOrNull(final CardBlock block) {
|
||||
public static QuestEventDraft getDraftOrNull(final QuestController quest, final CardBlock block) {
|
||||
|
||||
QuestEventDraft event = new QuestEventDraft(block.getName());
|
||||
|
||||
@@ -795,14 +801,14 @@ public class QuestEventDraft {
|
||||
}
|
||||
|
||||
List<String> usedNames = new ArrayList<>();
|
||||
usedNames.add(GuiBase.getInterface().getGuiPlayer().getName());
|
||||
usedNames.add(quest.getGui().getGuiPlayer().getName());
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
event.aiNames[i] = NameGenerator.getRandomName("Any", "Any", usedNames);
|
||||
usedNames.add(event.aiNames[i]);
|
||||
}
|
||||
|
||||
int numberOfIcons = GuiBase.getInterface().getAvatarCount();
|
||||
int numberOfIcons = quest.getGui().getAvatarCount();
|
||||
List<Integer> usedIcons = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
|
||||
@@ -10,10 +10,10 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.BoosterBox;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.BoxedProduct;
|
||||
@@ -151,7 +151,7 @@ public class QuestSpellShop {
|
||||
}
|
||||
};
|
||||
|
||||
public static void buy(Iterable<Entry<InventoryItem, Integer>> items, IItemManager<InventoryItem> shopManager, IItemManager<InventoryItem> inventoryManager, boolean confirmPurchase) {
|
||||
public static void buy(IGuiBase gui, Iterable<Entry<InventoryItem, Integer>> items, IItemManager<InventoryItem> shopManager, IItemManager<InventoryItem> inventoryManager, boolean confirmPurchase) {
|
||||
long totalCost = 0;
|
||||
ItemPool<InventoryItem> itemsToBuy = new ItemPool<InventoryItem>(InventoryItem.class);
|
||||
for (Entry<InventoryItem, Integer> itemEntry : items) {
|
||||
@@ -171,11 +171,11 @@ public class QuestSpellShop {
|
||||
|
||||
long creditsShort = totalCost - FModel.getQuest().getAssets().getCredits();
|
||||
if (creditsShort > 0) {
|
||||
SOptionPane.showMessageDialog("You need " + creditsShort + " more credits to purchase the following " + suffix.toLowerCase() + ".\n" + displayList, title);
|
||||
SOptionPane.showMessageDialog(gui, "You need " + creditsShort + " more credits to purchase the following " + suffix.toLowerCase() + ".\n" + displayList, title);
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirmPurchase && !SOptionPane.showConfirmDialog("Pay " + totalCost + " credits to purchase the following " +
|
||||
if (confirmPurchase && !SOptionPane.showConfirmDialog(gui, "Pay " + totalCost + " credits to purchase the following " +
|
||||
suffix.toLowerCase() + "?\n" + displayList, title, "Buy", "Cancel")) {
|
||||
return;
|
||||
}
|
||||
@@ -219,7 +219,7 @@ public class QuestSpellShop {
|
||||
final List<PaperCard> remainingCards = new ArrayList<>();
|
||||
|
||||
while (((BoxedProduct) booster).boosterPacksRemaining() > 0 && !skipTheRest) {
|
||||
skipTheRest = GuiBase.getInterface().showBoxedProduct(booster.getName(), "You have found the following cards inside (Booster Pack " + (totalPacks - ((BoxedProduct) booster).boosterPacksRemaining() + 1) + " of " + totalPacks + "):", ((BoxedProduct) booster).getNextBoosterPack());
|
||||
skipTheRest = gui.showBoxedProduct(booster.getName(), "You have found the following cards inside (Booster Pack " + (totalPacks - ((BoxedProduct) booster).boosterPacksRemaining() + 1) + " of " + totalPacks + "):", ((BoxedProduct) booster).getNextBoosterPack());
|
||||
}
|
||||
|
||||
if (skipTheRest) {
|
||||
@@ -231,12 +231,12 @@ public class QuestSpellShop {
|
||||
remainingCards.addAll(((BoxedProduct) booster).getExtraCards());
|
||||
|
||||
if (remainingCards.size() > 0) {
|
||||
GuiBase.getInterface().showCardList(booster.getName(), "You have found the following cards inside:", remainingCards);
|
||||
gui.showCardList(booster.getName(), "You have found the following cards inside:", remainingCards);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
GuiBase.getInterface().showCardList(booster.getName(), "You have found the following cards inside:", newCards);
|
||||
gui.showCardList(booster.getName(), "You have found the following cards inside:", newCards);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public class QuestSpellShop {
|
||||
}
|
||||
|
||||
boolean one = (qty == 1);
|
||||
SOptionPane.showMessageDialog(String.format(
|
||||
SOptionPane.showMessageDialog(gui, String.format(
|
||||
"%s '%s' %s added to your decklist.%n%n%s cards were also added to your pool.",
|
||||
one ? "Deck" : String.format("%d copies of deck", qty),
|
||||
deck.getName(), one ? "was" : "were", one ? "Its" : "Their"),
|
||||
@@ -261,7 +261,7 @@ public class QuestSpellShop {
|
||||
inventoryManager.addItems(itemsToAdd);
|
||||
}
|
||||
|
||||
public static void sell(Iterable<Entry<InventoryItem, Integer>> items, IItemManager<InventoryItem> shopManager, IItemManager<InventoryItem> inventoryManager, boolean confirmSale) {
|
||||
public static void sell(final IGuiBase gui, Iterable<Entry<InventoryItem, Integer>> items, IItemManager<InventoryItem> shopManager, IItemManager<InventoryItem> inventoryManager, boolean confirmSale) {
|
||||
long totalReceived = 0;
|
||||
ItemPool<InventoryItem> itemsToSell = new ItemPool<InventoryItem>(InventoryItem.class);
|
||||
for (Entry<InventoryItem, Integer> itemEntry : items) {
|
||||
@@ -280,7 +280,7 @@ public class QuestSpellShop {
|
||||
String displayList = SItemManagerUtil.buildDisplayList(itemsToSell);
|
||||
String title = "Sell " + suffix;
|
||||
|
||||
if (!SOptionPane.showConfirmDialog("Sell the following " + suffix.toLowerCase() + " for " + totalReceived +
|
||||
if (!SOptionPane.showConfirmDialog(gui, "Sell the following " + suffix.toLowerCase() + " for " + totalReceived +
|
||||
" credit" + (totalReceived != 1 ? "s" : "") + "?\n" + displayList, title, "Sell", "Cancel")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,12 @@
|
||||
*/
|
||||
package forge.quest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.card.CardDb.SetPreference;
|
||||
@@ -31,6 +35,7 @@ import forge.game.Match;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperToken;
|
||||
import forge.model.FModel;
|
||||
@@ -44,11 +49,6 @@ import forge.quest.data.QuestPreferences.QPref;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* QuestUtil class.
|
||||
@@ -191,8 +191,8 @@ public class QuestUtil {
|
||||
return FModel.getMagicDb().getCommonCards().getCardFromEdition(name, SetPreference.Latest);
|
||||
}
|
||||
|
||||
public static void travelWorld() {
|
||||
if (!checkActiveQuest("Travel between worlds.")) {
|
||||
public static void travelWorld(final IGuiBase gui) {
|
||||
if (!checkActiveQuest(gui, "Travel between worlds.")) {
|
||||
return;
|
||||
}
|
||||
List<QuestWorld> worlds = new ArrayList<QuestWorld>();
|
||||
@@ -205,12 +205,12 @@ public class QuestUtil {
|
||||
}
|
||||
|
||||
if (worlds.size() < 1) {
|
||||
SOptionPane.showErrorDialog("There are currently no worlds you can travel to\nin this version of Forge.", "No Worlds");
|
||||
SOptionPane.showErrorDialog(gui, "There are currently no worlds you can travel to\nin this version of Forge.", "No Worlds");
|
||||
return;
|
||||
}
|
||||
|
||||
final String setPrompt = "Where do you wish to travel?";
|
||||
final QuestWorld newWorld = SGuiChoose.oneOrNone(setPrompt, worlds);
|
||||
final QuestWorld newWorld = SGuiChoose.oneOrNone(gui, setPrompt, worlds);
|
||||
|
||||
if (worlds.indexOf(newWorld) < 0) {
|
||||
return;
|
||||
@@ -221,7 +221,7 @@ public class QuestUtil {
|
||||
if (nextChallengeInWins() < 1 && qCtrl.getAchievements().getCurrentChallenges().size() > 0) {
|
||||
needRemove = true;
|
||||
|
||||
if (!SOptionPane.showConfirmDialog(
|
||||
if (!SOptionPane.showConfirmDialog(gui,
|
||||
"You have uncompleted challenges in your current world. If you travel now, they will be LOST!"
|
||||
+ "\nAre you sure you wish to travel anyway?\n"
|
||||
+ "(Click \"No\" to go back and complete your current challenges first.)",
|
||||
@@ -466,11 +466,11 @@ public class QuestUtil {
|
||||
return draftEvent;
|
||||
}
|
||||
|
||||
public static boolean checkActiveQuest(String location) {
|
||||
public static boolean checkActiveQuest(final IGuiBase gui, final String location) {
|
||||
QuestController qc = FModel.getQuest();
|
||||
if (qc == null || qc.getAssets() == null) {
|
||||
String msg = "Please create a Quest before attempting to " + location;
|
||||
SOptionPane.showErrorDialog(msg, "No Quest");
|
||||
SOptionPane.showErrorDialog(gui, msg, "No Quest");
|
||||
System.out.println(msg);
|
||||
return false;
|
||||
}
|
||||
@@ -478,24 +478,24 @@ public class QuestUtil {
|
||||
}
|
||||
|
||||
/** */
|
||||
public static void showSpellShop() {
|
||||
if (!checkActiveQuest("Visit the Spell Shop.")) {
|
||||
public static void showSpellShop(final IGuiBase gui) {
|
||||
if (!checkActiveQuest(gui, "Visit the Spell Shop.")) {
|
||||
return;
|
||||
}
|
||||
GuiBase.getInterface().showSpellShop();
|
||||
gui.showSpellShop();
|
||||
}
|
||||
|
||||
/** */
|
||||
public static void showBazaar() {
|
||||
if (!checkActiveQuest("Visit the Bazaar.")) {
|
||||
public static void showBazaar(final IGuiBase gui) {
|
||||
if (!checkActiveQuest(gui, "Visit the Bazaar.")) {
|
||||
return;
|
||||
}
|
||||
GuiBase.getInterface().showBazaar();
|
||||
gui.showBazaar();
|
||||
}
|
||||
|
||||
/** */
|
||||
public static void chooseAndUnlockEdition() {
|
||||
if (!checkActiveQuest("Unlock Editions.")) {
|
||||
public static void chooseAndUnlockEdition(final IGuiBase gui) {
|
||||
if (!checkActiveQuest(gui, "Unlock Editions.")) {
|
||||
return;
|
||||
}
|
||||
final QuestController qData = FModel.getQuest();
|
||||
@@ -506,19 +506,19 @@ public class QuestUtil {
|
||||
|
||||
CardEdition unlocked = toUnlock.left;
|
||||
qData.getAssets().subtractCredits(toUnlock.right);
|
||||
SOptionPane.showMessageDialog("You have successfully unlocked " + unlocked.getName() + "!",
|
||||
SOptionPane.showMessageDialog(gui, "You have successfully unlocked " + unlocked.getName() + "!",
|
||||
unlocked.getName() + " unlocked!", null);
|
||||
|
||||
QuestUtilUnlockSets.doUnlock(qData, unlocked);
|
||||
QuestUtilUnlockSets.doUnlock(gui, qData, unlocked);
|
||||
}
|
||||
|
||||
public static void startGame() {
|
||||
if (canStartGame()) {
|
||||
finishStartingGame();
|
||||
public static void startGame(final IGuiBase gui) {
|
||||
if (canStartGame(gui)) {
|
||||
finishStartingGame(gui);
|
||||
}
|
||||
}
|
||||
|
||||
public static void finishStartingGame() {
|
||||
public static void finishStartingGame(final IGuiBase gui) {
|
||||
final QuestController qData = FModel.getQuest();
|
||||
|
||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||
@@ -564,10 +564,10 @@ public class QuestUtil {
|
||||
}
|
||||
|
||||
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
|
||||
starter.add(humanStart.setPlayer(GuiBase.getInterface().getQuestPlayer()));
|
||||
starter.add(humanStart.setPlayer(gui.getQuestPlayer()));
|
||||
|
||||
LobbyPlayer aiPlayer = GuiBase.getInterface().getAiPlayer(event.getOpponent() == null ? event.getTitle() : event.getOpponent());
|
||||
GuiBase.getInterface().setPlayerAvatar(aiPlayer, event);
|
||||
LobbyPlayer aiPlayer = gui.getAiPlayer(event.getOpponent() == null ? event.getTitle() : event.getOpponent());
|
||||
gui.setPlayerAvatar(aiPlayer, event);
|
||||
starter.add(aiStart.setPlayer(aiPlayer));
|
||||
|
||||
boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL);
|
||||
@@ -585,10 +585,10 @@ public class QuestUtil {
|
||||
rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN));
|
||||
rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE);
|
||||
final Match mc = new Match(rules, starter);
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable(){
|
||||
FThreads.invokeInEdtNowOrLater(gui, new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
GuiBase.getInterface().startGame(mc);
|
||||
gui.startGame(mc);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -610,15 +610,15 @@ public class QuestUtil {
|
||||
* Checks to see if a game can be started and displays relevant dialogues.
|
||||
* @return
|
||||
*/
|
||||
public static boolean canStartGame() {
|
||||
if (!checkActiveQuest("Start a duel.") || null == event) {
|
||||
public static boolean canStartGame(final IGuiBase gui) {
|
||||
if (!checkActiveQuest(gui, "Start a duel.") || null == event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Deck deck = getDeckForNewGame();
|
||||
if (deck == null) {
|
||||
String msg = "Please select a Quest Deck.";
|
||||
SOptionPane.showErrorDialog(msg, "No Deck");
|
||||
SOptionPane.showErrorDialog(gui, msg, "No Deck");
|
||||
System.out.println(msg);
|
||||
return false;
|
||||
}
|
||||
@@ -626,7 +626,7 @@ public class QuestUtil {
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
String errorMessage = GameType.Quest.getDeckFormat().getDeckConformanceProblem(deck);
|
||||
if (null != errorMessage) {
|
||||
SOptionPane.showErrorDialog("Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck");
|
||||
SOptionPane.showErrorDialog(gui, "Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,22 @@
|
||||
*/
|
||||
package forge.quest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.UnOpenedProduct;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.model.FModel;
|
||||
@@ -32,10 +41,6 @@ import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This is a helper class for unlocking new sets during a format-limited
|
||||
* quest.
|
||||
@@ -77,7 +82,7 @@ public class QuestUtilUnlockSets {
|
||||
options.add(String.format("%s [PRICE: %d credits]", ee.left.getName(), ee.right));
|
||||
}
|
||||
|
||||
int index = options.indexOf(SGuiChoose.oneOrNone(setPrompt, options));
|
||||
int index = options.indexOf(SGuiChoose.oneOrNone(qData.getGui(), setPrompt, options));
|
||||
if (index < 0 || index >= options.size()) {
|
||||
return null;
|
||||
}
|
||||
@@ -88,7 +93,8 @@ public class QuestUtilUnlockSets {
|
||||
CardEdition choosenEdition = toBuy.left;
|
||||
|
||||
if (qData.getAssets().getCredits() < price) {
|
||||
SOptionPane.showMessageDialog("Unfortunately, you cannot afford that set yet.\n"
|
||||
SOptionPane.showMessageDialog(qData.getGui(),
|
||||
"Unfortunately, you cannot afford that set yet.\n"
|
||||
+ "To unlock " + choosenEdition.getName() + ", you need " + price + " credits.\n"
|
||||
+ "You have only " + qData.getAssets().getCredits() + " credits.",
|
||||
"Failed to unlock " + choosenEdition.getName(),
|
||||
@@ -96,7 +102,7 @@ public class QuestUtilUnlockSets {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!SOptionPane.showConfirmDialog(
|
||||
if (!SOptionPane.showConfirmDialog(qData.getGui(),
|
||||
"Unlocking " + choosenEdition.getName() + " will cost you " + price + " credits.\n"
|
||||
+ "You have " + qData.getAssets().getCredits() + " credits.\n\n"
|
||||
+ "Are you sure you want to unlock " + choosenEdition.getName() + "?",
|
||||
@@ -173,7 +179,7 @@ public class QuestUtilUnlockSets {
|
||||
* @param qData the quest controller
|
||||
* @param unlockedSet the edition to unlock
|
||||
*/
|
||||
public static void doUnlock(QuestController qData, final CardEdition unlockedSet) {
|
||||
public static void doUnlock(final IGuiBase gui, final QuestController qData, final CardEdition unlockedSet) {
|
||||
IStorage<SealedProduct.Template> starters = FModel.getMagicDb().getTournamentPacks();
|
||||
IStorage<SealedProduct.Template> boosters = FModel.getMagicDb().getBoosters();
|
||||
qData.getFormat().unlockSet(unlockedSet.getCode());
|
||||
@@ -192,7 +198,7 @@ public class QuestUtilUnlockSets {
|
||||
}
|
||||
|
||||
qData.getCards().addAllCards(cardsWon);
|
||||
GuiBase.getInterface().showCardList(unlockedSet.getName(), "You get the following bonus cards:", cardsWon);
|
||||
gui.showCardList(unlockedSet.getName(), "You get the following bonus cards:", cardsWon);
|
||||
qData.save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
package forge.quest;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.IUnOpenedProduct;
|
||||
import forge.card.UnOpenedProduct;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEndReason;
|
||||
import forge.game.GameFormat;
|
||||
import forge.game.GameOutcome;
|
||||
import forge.game.player.GameLossReason;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerOutcome;
|
||||
import forge.game.player.PlayerStatistics;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.interfaces.IWinLoseView;
|
||||
import forge.item.*;
|
||||
import forge.model.FModel;
|
||||
@@ -25,26 +23,31 @@ import forge.quest.data.QuestPreferences.DifficultyPrefs;
|
||||
import forge.quest.data.QuestPreferences.QPref;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public abstract class QuestWinLoseController {
|
||||
private final Game lastGame;
|
||||
private final IGameView lastGame;
|
||||
protected final IGuiBase gui;
|
||||
private final transient boolean wonMatch;
|
||||
private final transient boolean isAnte;
|
||||
private final transient QuestController qData;
|
||||
private final transient QuestEvent qEvent;
|
||||
|
||||
public QuestWinLoseController(Game lastGame0) {
|
||||
lastGame = lastGame0;
|
||||
public QuestWinLoseController(final IGameView game0, final IGuiBase gui) {
|
||||
lastGame = game0;
|
||||
this.gui = gui;
|
||||
qData = FModel.getQuest();
|
||||
qEvent = qData.getCurrentEvent();
|
||||
wonMatch = lastGame.getMatch().isWonBy(GuiBase.getInterface().getQuestPlayer());
|
||||
wonMatch = lastGame.isMatchWonBy(gui.getQuestPlayer());
|
||||
isAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE);
|
||||
}
|
||||
|
||||
@@ -53,21 +56,21 @@ public abstract class QuestWinLoseController {
|
||||
final QuestController qc = FModel.getQuest();
|
||||
|
||||
// After the first game, reset the card shop pool to be able to buy back anted cards
|
||||
if (lastGame.getMatch().getPlayedGames().size() == 1) {
|
||||
if (lastGame.getNumPlayedGamesInMatch() == 1) {
|
||||
qc.getCards().clearShopList();
|
||||
qc.getCards().getShopList();
|
||||
}
|
||||
|
||||
final LobbyPlayer questLobbyPlayer = GuiBase.getInterface().getQuestPlayer();
|
||||
Player player = null;
|
||||
for (Player p : lastGame.getRegisteredPlayers()) {
|
||||
final LobbyPlayer questLobbyPlayer = gui.getQuestPlayer();
|
||||
PlayerView player = null;
|
||||
for (final PlayerView p : lastGame.getPlayers()) {
|
||||
if (p.getLobbyPlayer().equals(questLobbyPlayer)) {
|
||||
player = p;
|
||||
}
|
||||
}
|
||||
final Player questPlayer = player;
|
||||
final PlayerView questPlayer = player;
|
||||
|
||||
final boolean matchIsNotOver = !lastGame.getMatch().isMatchOver();
|
||||
final boolean matchIsNotOver = !lastGame.isMatchOver();
|
||||
if (matchIsNotOver) {
|
||||
view.getBtnQuit().setText("Quit (-15 Credits)");
|
||||
}
|
||||
@@ -86,11 +89,8 @@ public abstract class QuestWinLoseController {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isAnte) {
|
||||
//do per-game actions
|
||||
GameOutcome outcome = lastGame.getOutcome();
|
||||
|
||||
// Won/lost cards should already be calculated (even in a draw)
|
||||
GameOutcome.AnteResult anteResult = outcome.anteResult.get(questPlayer);
|
||||
GameOutcome.AnteResult anteResult = lastGame.getAnteResult();
|
||||
if (anteResult != null) {
|
||||
if (anteResult.wonCards != null) {
|
||||
qc.getCards().addAllCards(anteResult.wonCards);
|
||||
@@ -98,7 +98,7 @@ public abstract class QuestWinLoseController {
|
||||
if (anteResult.lostCards != null) {
|
||||
qc.getCards().loseCards(anteResult.lostCards);
|
||||
}
|
||||
anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.equals(outcome.getWinningPlayer()));
|
||||
anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.getLobbyPlayer().equals(lastGame.getWinningPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,21 +218,14 @@ public abstract class QuestWinLoseController {
|
||||
|
||||
// Basic win bonus
|
||||
final int base = FModel.getQuestPreferences().getPrefInt(QPref.REWARDS_BASE);
|
||||
double multiplier = 1;
|
||||
|
||||
switch (qEvent.getDifficulty()) {
|
||||
case EASY: multiplier = 1; break;
|
||||
case MEDIUM: multiplier = 1.5; break;
|
||||
case HARD: multiplier = 2; break;
|
||||
case EXPERT: multiplier = 3; break;
|
||||
}
|
||||
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");
|
||||
|
||||
int creditsForPreviousWins = (int) ((Double.parseDouble(FModel.getQuestPreferences()
|
||||
final int creditsForPreviousWins = (int) ((Double.parseDouble(FModel.getQuestPreferences()
|
||||
.getPref(QPref.REWARDS_WINS_MULTIPLIER)) * qData.getAchievements().getWin()));
|
||||
credBase += creditsForPreviousWins;
|
||||
|
||||
@@ -242,9 +235,9 @@ public abstract class QuestWinLoseController {
|
||||
// Gameplay bonuses (for each game win)
|
||||
boolean hasNeverLost = true;
|
||||
int lifeDifferenceCredits = 0;
|
||||
|
||||
LobbyPlayer localHuman = GuiBase.getInterface().getQuestPlayer();
|
||||
for (final GameOutcome game : lastGame.getMatch().getPlayedGames()) {
|
||||
|
||||
final LobbyPlayer localHuman = gui.getQuestPlayer();
|
||||
for (final GameOutcome game : lastGame.getOutcomesOfMatch()) {
|
||||
if (!game.isWinner(localHuman)) {
|
||||
hasNeverLost = false;
|
||||
continue; // no rewards for losing a game
|
||||
@@ -513,7 +506,7 @@ public abstract class QuestWinLoseController {
|
||||
|
||||
Collections.sort(formats);
|
||||
|
||||
final GameFormat selected = SGuiChoose.getChoices("Choose bonus booster format", 1, 1, formats, pref, null).get(0);
|
||||
final GameFormat selected = SGuiChoose.getChoices(gui, "Choose bonus booster format", 1, 1, formats, pref, null).get(0);
|
||||
FModel.getQuestPreferences().setPref(QPref.BOOSTER_FORMAT, selected.toString());
|
||||
|
||||
cardsWon = qData.getCards().generateQuestBooster(selected.getFilterPrinted());
|
||||
@@ -550,7 +543,7 @@ public abstract class QuestWinLoseController {
|
||||
maxChoices--;
|
||||
}
|
||||
|
||||
final CardEdition chooseEd = SGuiChoose.one("Choose bonus booster set", options);
|
||||
final CardEdition chooseEd = SGuiChoose.one(gui, "Choose bonus booster set", options);
|
||||
|
||||
IUnOpenedProduct product = new UnOpenedProduct(FModel.getMagicDb().getBoosters().get(chooseEd.getCode()));
|
||||
cardsWon = product.get();
|
||||
@@ -641,7 +634,7 @@ public abstract class QuestWinLoseController {
|
||||
}
|
||||
else if (ii instanceof IQuestRewardCard) {
|
||||
final List<PaperCard> cardChoices = ((IQuestRewardCard) ii).getChoices();
|
||||
final PaperCard chosenCard = (null == cardChoices ? null : SGuiChoose.one("Choose " + ((IQuestRewardCard) ii).getName(), cardChoices));
|
||||
final PaperCard chosenCard = (null == cardChoices ? null : SGuiChoose.one(gui, "Choose " + ((IQuestRewardCard) ii).getName(), cardChoices));
|
||||
if (null != chosenCard) {
|
||||
cardsWon.add(chosenCard);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package forge.quest.bazaar;
|
||||
|
||||
import forge.assets.ISkinImage;
|
||||
import forge.quest.data.QuestAssets;
|
||||
|
||||
/**
|
||||
@@ -50,9 +49,9 @@ public interface IQuestBazaarItem extends Comparable<Object> {
|
||||
* getIcon.
|
||||
* </p>
|
||||
*
|
||||
* @return the image that is displayed in the bazaar
|
||||
* @return the image that is dispslayed in the bazaar
|
||||
*/
|
||||
ISkinImage getIcon(QuestAssets qA);
|
||||
String getIcon(QuestAssets qA);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
||||
@@ -17,15 +17,13 @@
|
||||
*/
|
||||
package forge.quest.bazaar;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.assets.ISkinImage;
|
||||
import forge.quest.data.QuestAssets;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Abstract QuestItemAbstract class.
|
||||
@@ -170,8 +168,8 @@ public class QuestItemBasic implements IQuestBazaarItem {
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public ISkinImage getIcon(QuestAssets qA) {
|
||||
return GuiBase.getInterface().getSkinIcon(icon);
|
||||
public String getIcon(final QuestAssets qA) {
|
||||
return icon.name();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,19 +17,16 @@
|
||||
*/
|
||||
package forge.quest.bazaar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.assets.ISkinImage;
|
||||
import forge.item.PaperToken;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.quest.data.QuestAssets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Abstract QuestPetAbstract class.
|
||||
@@ -120,22 +117,10 @@ public class QuestPetController implements IQuestBazaarItem {
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
@Override
|
||||
public final ISkinImage getIcon(final QuestAssets qA) {
|
||||
public final String getIcon(final QuestAssets qA) {
|
||||
final String path = ForgeConstants.CACHE_TOKEN_PICS_DIR;
|
||||
final int level = this.getPetLevel(qA);
|
||||
try {
|
||||
return GuiBase.getInterface().getUnskinnedIcon(path + this.levels.get(level < this.maxLevel ? level + 1 : level).getPicture() + ".jpg");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
return GuiBase.getInterface().getUnskinnedIcon(ForgeConstants.NO_CARD_FILE);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return GuiBase.getInterface().getSkinIcon(FSkinProp.ICO_UNKNOWN);
|
||||
return path + this.levels.get(level < this.maxLevel ? level + 1 : level).getPicture() + ".jpg";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,15 +17,13 @@
|
||||
*/
|
||||
package forge.quest.bazaar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.assets.ISkinImage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -89,8 +87,8 @@ public class QuestStallDefinition {
|
||||
*
|
||||
* @return the icon
|
||||
*/
|
||||
public ISkinImage getIcon() {
|
||||
return GuiBase.getInterface().getSkinIcon(icon);
|
||||
public FSkinProp getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,7 +43,7 @@ public class QuestAchievements {
|
||||
private int difficulty;
|
||||
|
||||
private transient CardBlock nextDraftBlock;
|
||||
|
||||
|
||||
public QuestAchievements() { //needed for XML serialization
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ public class QuestAchievements {
|
||||
for (int i = 0; i < draftsToGenerate; i++) {
|
||||
QuestEventDraft draft;
|
||||
if (nextDraftBlock != null) {
|
||||
draft = QuestEventDraft.getDraftOrNull(nextDraftBlock);
|
||||
draft = QuestEventDraft.getDraftOrNull(FModel.getQuest(), nextDraftBlock);
|
||||
nextDraftBlock = null;
|
||||
} else {
|
||||
draft = QuestEventDraft.getRandomDraftOrNull(FModel.getQuest());
|
||||
|
||||
@@ -17,6 +17,35 @@
|
||||
*/
|
||||
package forge.quest.io;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.converters.Converter;
|
||||
import com.thoughtworks.xstream.converters.MarshallingContext;
|
||||
@@ -29,39 +58,30 @@ import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.error.BugReporter;
|
||||
import forge.item.*;
|
||||
import forge.item.BoosterBox;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.FatPack;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.item.TournamentPack;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.quest.QuestController;
|
||||
import forge.quest.QuestEventDraft;
|
||||
import forge.quest.QuestMode;
|
||||
import forge.quest.bazaar.QuestItemType;
|
||||
import forge.quest.data.*;
|
||||
import forge.quest.data.GameFormatQuest;
|
||||
import forge.quest.data.QuestAchievements;
|
||||
import forge.quest.data.QuestAssets;
|
||||
import forge.quest.data.QuestData;
|
||||
import forge.quest.data.QuestEventDraftContainer;
|
||||
import forge.quest.data.QuestItemCondition;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.IgnoringXStream;
|
||||
import forge.util.ItemPool;
|
||||
import forge.util.XmlUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* QuestDataIO class.
|
||||
@@ -130,14 +150,15 @@ public class QuestDataIO {
|
||||
QuestDataIO.updateSaveFile(data, bigXML, xmlSaveFile.getName().replace(".dat", ""));
|
||||
}
|
||||
catch (final Exception e) {
|
||||
BugReporter.reportException(e);
|
||||
//BugReporter.reportException(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
BugReporter.reportException(ex, "Error loading Quest Data");
|
||||
//BugReporter.reportException(ex, "Error loading Quest Data");
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
@@ -371,7 +392,7 @@ public class QuestDataIO {
|
||||
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
BugReporter.reportException(ex, "Error saving Quest Data.");
|
||||
//BugReporter.reportException(ex, "Error saving Quest Data.");
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,48 @@
|
||||
package forge.sound;
|
||||
|
||||
import forge.GuiBase;
|
||||
import java.util.Collection;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.events.IUiEventVisitor;
|
||||
import forge.events.UiEventAttackerDeclared;
|
||||
import forge.events.UiEventBlockerAssigned;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.event.*;
|
||||
import forge.game.event.GameEvent;
|
||||
import forge.game.event.GameEventBlockersDeclared;
|
||||
import forge.game.event.GameEventCardAttachment;
|
||||
import forge.game.event.GameEventCardChangeZone;
|
||||
import forge.game.event.GameEventCardCounters;
|
||||
import forge.game.event.GameEventCardDamaged;
|
||||
import forge.game.event.GameEventCardDestroyed;
|
||||
import forge.game.event.GameEventCardPhased;
|
||||
import forge.game.event.GameEventCardRegenerated;
|
||||
import forge.game.event.GameEventCardSacrificed;
|
||||
import forge.game.event.GameEventCardTapped;
|
||||
import forge.game.event.GameEventFlipCoin;
|
||||
import forge.game.event.GameEventGameOutcome;
|
||||
import forge.game.event.GameEventLandPlayed;
|
||||
import forge.game.event.GameEventPlayerLivesChanged;
|
||||
import forge.game.event.GameEventPlayerPoisoned;
|
||||
import forge.game.event.GameEventShuffle;
|
||||
import forge.game.event.GameEventSpellResolved;
|
||||
import forge.game.event.GameEventTokenCreated;
|
||||
import forge.game.event.GameEventTurnEnded;
|
||||
import forge.game.event.IGameEventVisitor;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.maps.MapOfLists;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* This class is in charge of converting any forge.game.event.Event to a SoundEffectType.
|
||||
*
|
||||
*/
|
||||
public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> implements IUiEventVisitor<SoundEffectType> {
|
||||
|
||||
final LobbyPlayer player;
|
||||
public EventVisualizer(final LobbyPlayer lobbyPlayer) {
|
||||
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; }
|
||||
@@ -41,7 +66,7 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
public SoundEffectType visit(GameEventShuffle event) { return SoundEffectType.Shuffle; }
|
||||
public SoundEffectType visit(GameEventTokenCreated event) { return SoundEffectType.Token; }
|
||||
public SoundEffectType visit(GameEventBlockersDeclared event) {
|
||||
boolean isLocalHuman = event.defendingPlayer.getLobbyPlayer() == GuiBase.getInterface().getGuiPlayer();
|
||||
final boolean isLocalHuman = event.defendingPlayer.getLobbyPlayer() == player;
|
||||
if (isLocalHuman)
|
||||
return null; // already played sounds in interactive mode
|
||||
|
||||
@@ -60,7 +85,7 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
* Plays the sound corresponding to the outcome of the duel.
|
||||
*/
|
||||
public SoundEffectType visit(GameEventGameOutcome event) {
|
||||
boolean humanWonTheDuel = event.result.getWinningLobbyPlayer() == GuiBase.getInterface().getGuiPlayer();
|
||||
boolean humanWonTheDuel = event.result.getWinningLobbyPlayer() == player;
|
||||
return humanWonTheDuel ? SoundEffectType.WinDuel : SoundEffectType.LoseDuel;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package forge.sound;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.events.UiEvent;
|
||||
import forge.game.event.GameEvent;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.events.UiEvent;
|
||||
import forge.game.event.GameEvent;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
|
||||
/**
|
||||
* Manages playback of all sounds for the client.
|
||||
*
|
||||
@@ -24,8 +24,13 @@ public class SoundSystem {
|
||||
private static final Map<SoundEffectType, IAudioClip> loadedClips = new EnumMap<SoundEffectType, IAudioClip>(SoundEffectType.class);
|
||||
private static final Map<String, IAudioClip> loadedScriptClips = new HashMap<String, IAudioClip>();
|
||||
|
||||
private final EventVisualizer visualizer = new EventVisualizer();
|
||||
private final IGuiBase gui;
|
||||
private final EventVisualizer visualizer;
|
||||
|
||||
public SoundSystem(final IGuiBase gui) {
|
||||
this.gui = gui;
|
||||
this.visualizer = new EventVisualizer(gui.getGuiPlayer());
|
||||
}
|
||||
private boolean isUsingAltSystem() {
|
||||
return FModel.getPreferences().getPrefBoolean(FPref.UI_ALT_SOUND_SYSTEM);
|
||||
}
|
||||
@@ -45,7 +50,7 @@ public class SoundSystem {
|
||||
IAudioClip clip = loadedClips.get(type);
|
||||
if (clip == null) { // cache miss
|
||||
String resource = type.getResourceFileName();
|
||||
clip = GuiBase.getInterface().createAudioClip(resource);
|
||||
clip = gui.createAudioClip(resource);
|
||||
if (clip == null) {
|
||||
clip = emptySound;
|
||||
}
|
||||
@@ -67,7 +72,7 @@ public class SoundSystem {
|
||||
|
||||
IAudioClip clip = loadedScriptClips.get(fileName);
|
||||
if (null == clip) { // cache miss
|
||||
clip = GuiBase.getInterface().createAudioClip(fileName);
|
||||
clip = gui.createAudioClip(fileName);
|
||||
if (clip == null) {
|
||||
clip = emptySound;
|
||||
}
|
||||
@@ -82,7 +87,7 @@ public class SoundSystem {
|
||||
*/
|
||||
public void play(String resourceFileName, boolean isSynchronized) {
|
||||
if (isUsingAltSystem()) {
|
||||
GuiBase.getInterface().startAltSoundSystem(ForgeConstants.SOUND_DIR + resourceFileName, isSynchronized);
|
||||
gui.startAltSoundSystem(ForgeConstants.SOUND_DIR + resourceFileName, isSynchronized);
|
||||
}
|
||||
else {
|
||||
IAudioClip snd = fetchResource(resourceFileName);
|
||||
@@ -97,7 +102,7 @@ public class SoundSystem {
|
||||
*/
|
||||
public void play(SoundEffectType type, boolean isSynchronized) {
|
||||
if (isUsingAltSystem()) {
|
||||
GuiBase.getInterface().startAltSoundSystem(ForgeConstants.SOUND_DIR + type.getResourceFileName(), isSynchronized);
|
||||
gui.startAltSoundSystem(ForgeConstants.SOUND_DIR + type.getResourceFileName(), isSynchronized);
|
||||
}
|
||||
else {
|
||||
IAudioClip snd = fetchResource(type);
|
||||
@@ -183,7 +188,7 @@ public class SoundSystem {
|
||||
if (filename == null) { return; }
|
||||
|
||||
try {
|
||||
currentTrack = GuiBase.getInterface().createAudioMusic(filename);
|
||||
currentTrack = gui.createAudioMusic(filename);
|
||||
currentTrack.play(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
498
forge-gui/src/main/java/forge/util/DevModeUtil.java
Normal file
498
forge-gui/src/main/java/forge/util/DevModeUtil.java
Normal file
@@ -0,0 +1,498 @@
|
||||
package forge.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameType;
|
||||
import forge.game.PlanarDice;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.AbilityManaPart;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.match.input.Input;
|
||||
import forge.match.input.InputPassPriority;
|
||||
import forge.match.input.InputSelectCardsFromList;
|
||||
import forge.model.FModel;
|
||||
import forge.player.HumanPlay;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SGuiDialog;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.view.CardView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
public final class DevModeUtil {
|
||||
|
||||
private DevModeUtil() {
|
||||
}
|
||||
|
||||
public static void devModeGenerateMana(final Game game, final PlayerControllerHuman controller) {
|
||||
Player pPriority = game.getPhaseHandler().getPriorityPlayer();
|
||||
if (pPriority == null) {
|
||||
SGuiDialog.message(controller.getGui(), "No player has priority at the moment, so mana cannot be added to their pool.");
|
||||
return;
|
||||
}
|
||||
|
||||
final Card dummy = new Card(-777777);
|
||||
dummy.setOwner(pPriority);
|
||||
Map<String, String> produced = new HashMap<String, String>();
|
||||
produced.put("Produced", "W W W W W W W U U U U U U U B B B B B B B G G G G G G G R R R R R R R 7");
|
||||
final AbilityManaPart abMana = new AbilityManaPart(dummy, produced);
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override public void run() { abMana.produceMana(null); }
|
||||
});
|
||||
}
|
||||
|
||||
public static void devSetupGameState(final Game game, final PlayerControllerHuman controller) {
|
||||
int humanLife = -1;
|
||||
int computerLife = -1;
|
||||
|
||||
final Map<ZoneType, String> humanCardTexts = new EnumMap<ZoneType, String>(ZoneType.class);
|
||||
final Map<ZoneType, String> aiCardTexts = new EnumMap<ZoneType, String>(ZoneType.class);
|
||||
|
||||
String tChangePlayer = "NONE";
|
||||
String tChangePhase = "NONE";
|
||||
|
||||
File gamesDir = new File(ForgeConstants.USER_GAMES_DIR);
|
||||
if (!gamesDir.exists()) { // if the directory does not exist, try to create it
|
||||
gamesDir.mkdir();
|
||||
}
|
||||
|
||||
String filename = controller.getGui().showFileDialog("Select Game State File", ForgeConstants.USER_GAMES_DIR);
|
||||
if (filename == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final FileInputStream fstream = new FileInputStream(filename);
|
||||
final DataInputStream in = new DataInputStream(fstream);
|
||||
final BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
String temp = "";
|
||||
|
||||
while ((temp = br.readLine()) != null) {
|
||||
|
||||
final String[] tempData = temp.split("=");
|
||||
if (tempData.length < 2 || temp.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String categoryName = tempData[0].toLowerCase();
|
||||
final String categoryValue = tempData[1];
|
||||
|
||||
if (categoryName.equals("humanlife")) humanLife = Integer.parseInt(categoryValue);
|
||||
else if (categoryName.equals("ailife")) computerLife = Integer.parseInt(categoryValue);
|
||||
|
||||
else if (categoryName.equals("activeplayer")) tChangePlayer = categoryValue.trim().toLowerCase();
|
||||
else if (categoryName.equals("activephase")) tChangePhase = categoryValue;
|
||||
|
||||
else if (categoryName.equals("humancardsinplay")) humanCardTexts.put(ZoneType.Battlefield, categoryValue);
|
||||
else if (categoryName.equals("aicardsinplay")) aiCardTexts.put(ZoneType.Battlefield, categoryValue);
|
||||
else if (categoryName.equals("humancardsinhand")) humanCardTexts.put(ZoneType.Hand, categoryValue);
|
||||
else if (categoryName.equals("aicardsinhand")) aiCardTexts.put(ZoneType.Hand, categoryValue);
|
||||
else if (categoryName.equals("humancardsingraveyard")) humanCardTexts.put(ZoneType.Graveyard, categoryValue);
|
||||
else if (categoryName.equals("aicardsingraveyard")) aiCardTexts.put(ZoneType.Graveyard, categoryValue);
|
||||
else if (categoryName.equals("humancardsinlibrary")) humanCardTexts.put(ZoneType.Library, categoryValue);
|
||||
else if (categoryName.equals("aicardsinlibrary")) aiCardTexts.put(ZoneType.Library, categoryValue);
|
||||
else if (categoryName.equals("humancardsinexile")) humanCardTexts.put(ZoneType.Exile, categoryValue);
|
||||
else if (categoryName.equals("aicardsinexile")) aiCardTexts.put(ZoneType.Exile, categoryValue);
|
||||
}
|
||||
|
||||
in.close();
|
||||
}
|
||||
catch (final FileNotFoundException fnfe) {
|
||||
SOptionPane.showErrorDialog(controller.getGui(), "File not found: " + filename);
|
||||
}
|
||||
catch (final Exception e) {
|
||||
SOptionPane.showErrorDialog(controller.getGui(), "Error loading battle setup file!");
|
||||
return;
|
||||
}
|
||||
|
||||
setupGameState(game, humanLife, computerLife, humanCardTexts, aiCardTexts, tChangePlayer, tChangePhase, controller);
|
||||
}
|
||||
|
||||
private static void setupGameState(final Game game, final int humanLife, final int computerLife, final Map<ZoneType, String> humanCardTexts,
|
||||
final Map<ZoneType, String> aiCardTexts, final String tChangePlayer, final String tChangePhase, final PlayerControllerHuman controller) {
|
||||
|
||||
Player pPriority = game.getPhaseHandler().getPriorityPlayer();
|
||||
if (pPriority == null) {
|
||||
SGuiDialog.message(controller.getGui(), "No player has priority at the moment, so game state cannot be setup.");
|
||||
return;
|
||||
}
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Player human = game.getPlayers().get(0);
|
||||
final Player ai = game.getPlayers().get(1);
|
||||
|
||||
Player newPlayerTurn = tChangePlayer.equals("human") ? newPlayerTurn = human : tChangePlayer.equals("ai") ? newPlayerTurn = ai : null;
|
||||
PhaseType newPhase = tChangePhase.trim().equalsIgnoreCase("none") ? null : PhaseType.smartValueOf(tChangePhase);
|
||||
|
||||
game.getPhaseHandler().devModeSet(newPhase, newPlayerTurn);
|
||||
|
||||
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
||||
|
||||
devSetupPlayerState(humanLife, humanCardTexts, human);
|
||||
devSetupPlayerState(computerLife, aiCardTexts, ai);
|
||||
|
||||
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
||||
|
||||
game.getAction().checkStaticAbilities();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void devSetupPlayerState(int life, Map<ZoneType, String> cardTexts, final Player p) {
|
||||
Map<ZoneType, List<Card>> humanCards = new EnumMap<ZoneType, List<Card>>(ZoneType.class);
|
||||
for(Entry<ZoneType, String> kv : cardTexts.entrySet()) {
|
||||
humanCards.put(kv.getKey(), devProcessCardsForZone(kv.getValue().split(";"), p));
|
||||
}
|
||||
|
||||
if (life > 0) p.setLife(life, null);
|
||||
for (Entry<ZoneType, List<Card>> kv : humanCards.entrySet()) {
|
||||
if (kv.getKey() == ZoneType.Battlefield) {
|
||||
for (final Card c : kv.getValue()) {
|
||||
p.getZone(ZoneType.Hand).add(c);
|
||||
p.getGame().getAction().moveToPlay(c);
|
||||
c.setSickness(false);
|
||||
}
|
||||
} else {
|
||||
p.getZone(kv.getKey()).setCards(kv.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devProcessCardsForZone.
|
||||
* </p>
|
||||
*
|
||||
* @param data
|
||||
* an array of {@link java.lang.String} objects.
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
private static List<Card> devProcessCardsForZone(final String[] data, final Player player) {
|
||||
final List<Card> cl = new ArrayList<Card>();
|
||||
for (final String element : data) {
|
||||
final String[] cardinfo = element.trim().split("\\|");
|
||||
|
||||
final Card c = Card.fromPaperCard(FModel.getMagicDb().getCommonCards().getCard(cardinfo[0]), player);
|
||||
|
||||
boolean hasSetCurSet = false;
|
||||
for (final String info : cardinfo) {
|
||||
if (info.startsWith("Set:")) {
|
||||
c.setCurSetCode(info.substring(info.indexOf(':') + 1));
|
||||
hasSetCurSet = true;
|
||||
} else if (info.equalsIgnoreCase("Tapped:True")) {
|
||||
c.tap();
|
||||
} else if (info.startsWith("Counters:")) {
|
||||
final String[] counterStrings = info.substring(info.indexOf(':') + 1).split(",");
|
||||
for (final String counter : counterStrings) {
|
||||
c.addCounter(CounterType.valueOf(counter), 1, true);
|
||||
}
|
||||
} else if (info.equalsIgnoreCase("SummonSick:True")) {
|
||||
c.setSickness(true);
|
||||
} else if (info.equalsIgnoreCase("FaceDown:True")) {
|
||||
c.setState(CardCharacteristicName.FaceDown);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasSetCurSet) {
|
||||
c.setCurSetCode(c.getMostRecentSet());
|
||||
}
|
||||
|
||||
cl.add(c);
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeTutor.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeTutor(final Game game, final PlayerControllerHuman controller) {
|
||||
Player pPriority = game.getPhaseHandler().getPriorityPlayer();
|
||||
if (pPriority == null) {
|
||||
SGuiDialog.message(controller.getGui(), "No player has priority at the moment, so their deck can't be tutored from.");
|
||||
return;
|
||||
}
|
||||
|
||||
final List<Card> lib = pPriority.getCardsIn(ZoneType.Library);
|
||||
final CardView cardView = SGuiChoose.oneOrNone(controller.getGui(), "Choose a card", controller.getCardViews(lib));
|
||||
final Card card = controller.getCard(cardView);
|
||||
if (card == null) { return; }
|
||||
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
game.getAction().moveToHand(card);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeAddCounter.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeAddCounter(final Game game, final PlayerControllerHuman controller) {
|
||||
final List<Card> cards = game.getCardsIn(ZoneType.Battlefield);
|
||||
final CardView cardView = SGuiChoose.oneOrNone(controller.getGui(), "Add counters to which card?", controller.getCardViews(cards));
|
||||
final Card card = controller.getCard(cardView);
|
||||
if (card == null) { return; }
|
||||
|
||||
final CounterType counter = SGuiChoose.oneOrNone(controller.getGui(), "Which type of counter?", CounterType.values());
|
||||
if (counter == null) { return; }
|
||||
|
||||
final Integer count = SGuiChoose.getInteger(controller.getGui(), "How many counters?", 1, Integer.MAX_VALUE, 10);
|
||||
if (count == null) { return; }
|
||||
|
||||
card.addCounter(counter, count, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeTapPerm.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeTapPerm(final Game game, final PlayerControllerHuman controller) {
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<Card> untapped = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Predicates.not(CardPredicates.Presets.TAPPED));
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 0, Integer.MAX_VALUE, untapped);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.setMessage("Choose permanents to tap");
|
||||
inp.showAndWait();
|
||||
if (!inp.hasCancelled()) {
|
||||
for (Card c : inp.getSelected()) {
|
||||
c.tap();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeUntapPerm.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeUntapPerm(final Game game, final PlayerControllerHuman controller) {
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<Card> tapped = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.TAPPED);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 0, Integer.MAX_VALUE, tapped);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.setMessage("Choose permanents to untap");
|
||||
inp.showAndWait();
|
||||
if( !inp.hasCancelled() )
|
||||
for(Card c : inp.getSelected())
|
||||
c.untap();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeSetLife.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.1.3
|
||||
*/
|
||||
public static void devModeSetLife(final Game game, final PlayerControllerHuman controller) {
|
||||
final List<Player> players = game.getPlayers();
|
||||
final PlayerView playerView = SGuiChoose.oneOrNone(controller.getGui(), "Set life for which player?", controller.getPlayerViews(players));
|
||||
final Player player = controller.getPlayer(playerView);
|
||||
if (player == null) { return; }
|
||||
|
||||
final Integer life = SGuiChoose.getInteger(controller.getGui(), "Set life to what?", 0);
|
||||
if (life == null) { return; }
|
||||
|
||||
player.setLife(life, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeWinGame.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.5.23
|
||||
*/
|
||||
public static void devModeWinGame(final Game game, final PlayerControllerHuman controller) {
|
||||
Input input = controller.getGui().getInputQueue().getInput();
|
||||
if (!(input instanceof InputPassPriority)) {
|
||||
SOptionPane.showMessageDialog(controller.getGui(), "You must have priority to use this feature.", "Win Game", SOptionPane.INFORMATION_ICON);
|
||||
return;
|
||||
}
|
||||
|
||||
//set life of all other players to 0
|
||||
final LobbyPlayer guiPlayer = controller.getLobbyPlayer();
|
||||
final List<Player> players = game.getPlayers();
|
||||
for (Player player : players) {
|
||||
if (player.getLobbyPlayer() != guiPlayer) {
|
||||
player.setLife(0, null);
|
||||
}
|
||||
}
|
||||
|
||||
//pass priority so that causes gui player to win
|
||||
input.selectButtonOK();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeTutorAnyCard.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.2.7
|
||||
*/
|
||||
public static void devModeCardToHand(final Game game, final PlayerControllerHuman controller) {
|
||||
final List<Player> players = game.getPlayers();
|
||||
final PlayerView pView = SGuiChoose.oneOrNone(controller.getGui(), "Put card in hand for which player?", controller.getPlayerViews(players));
|
||||
final Player p = controller.getPlayer(pView);
|
||||
if (null == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<PaperCard> cards = Lists.newArrayList(FModel.getMagicDb().getCommonCards().getUniqueCards());
|
||||
Collections.sort(cards);
|
||||
|
||||
// use standard forge's list selection dialog
|
||||
final IPaperCard c = SGuiChoose.oneOrNone(controller.getGui(), "Name the card", cards);
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
game.getAction().invoke(new Runnable() { @Override public void run() {
|
||||
game.getAction().moveToHand(Card.fromPaperCard(c, p));
|
||||
}});
|
||||
}
|
||||
|
||||
public static void devModeCardToBattlefield(final Game game, final PlayerControllerHuman controller) {
|
||||
final List<Player> players = game.getPlayers();
|
||||
final PlayerView pView = SGuiChoose.oneOrNone(controller.getGui(), "Put card in play for which player?", controller.getPlayerViews(players));
|
||||
final Player p = controller.getPlayer(pView);
|
||||
if (null == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<PaperCard> cards = Lists.newArrayList(FModel.getMagicDb().getCommonCards().getUniqueCards());
|
||||
Collections.sort(cards);
|
||||
|
||||
// use standard forge's list selection dialog
|
||||
final IPaperCard c = SGuiChoose.oneOrNone(controller.getGui(), "Name the card", cards);
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override public void run() {
|
||||
final Card forgeCard = Card.fromPaperCard(c, p);
|
||||
|
||||
if (c.getRules().getType().isLand()) {
|
||||
game.getAction().moveToPlay(forgeCard);
|
||||
} else {
|
||||
final List<SpellAbility> choices = forgeCard.getBasicSpells();
|
||||
if (choices.isEmpty()) {
|
||||
return; // when would it happen?
|
||||
}
|
||||
|
||||
final SpellAbility sa = choices.size() == 1 ? choices.get(0) : SGuiChoose.oneOrNone(controller.getGui(), "Choose", choices);
|
||||
if (sa == null) {
|
||||
return; // happens if cancelled
|
||||
}
|
||||
|
||||
game.getAction().moveToHand(forgeCard); // this is really needed (for rollbacks at least)
|
||||
// Human player is choosing targets for an ability controlled by chosen player.
|
||||
sa.setActivatingPlayer(p);
|
||||
HumanPlay.playSaWithoutPayingManaCost(controller, game, sa, true);
|
||||
}
|
||||
game.getStack().addAllTriggeredAbilitiesToStack(); // playSa could fire some triggers
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void devModeRiggedPlanarRoll(final Game game, final PlayerControllerHuman controller) {
|
||||
final List<Player> players = game.getPlayers();
|
||||
final PlayerView playerView = SGuiChoose.oneOrNone(controller.getGui(), "Which player should roll?", controller.getPlayerViews(players));
|
||||
final Player player = controller.getPlayer(playerView);
|
||||
if (player == null) { return; }
|
||||
|
||||
final PlanarDice res = SGuiChoose.oneOrNone(controller.getGui(), "Choose result", PlanarDice.values());
|
||||
if (res == null) { return; }
|
||||
|
||||
System.out.println("Rigging planar dice roll: " + res.toString());
|
||||
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PlanarDice.roll(player, res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void devModePlaneswalkTo(final Game game, final PlayerControllerHuman controller) {
|
||||
if (!game.getRules().hasAppliedVariant(GameType.Planechase)) { return; }
|
||||
final Player p = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
final List<PaperCard> allPlanars = new ArrayList<PaperCard>();
|
||||
for (PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
|
||||
if (c.getRules().getType().isPlane() || c.getRules().getType().isPhenomenon()) {
|
||||
allPlanars.add(c);
|
||||
}
|
||||
}
|
||||
Collections.sort(allPlanars);
|
||||
|
||||
// use standard forge's list selection dialog
|
||||
final IPaperCard c = SGuiChoose.oneOrNone(controller.getGui(), "Name the card", allPlanars);
|
||||
if (c == null) { return; }
|
||||
final Card forgeCard = Card.fromPaperCard(c, p);
|
||||
|
||||
forgeCard.setOwner(p);
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
game.getAction().changeZone(null, p.getZone(ZoneType.PlanarDeck), forgeCard, 0);
|
||||
PlanarDice.roll(p, PlanarDice.Planeswalk);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -17,506 +17,21 @@
|
||||
*/
|
||||
package forge.util;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameType;
|
||||
import forge.game.PlanarDice;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.AbilityManaPart;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.match.input.Input;
|
||||
import forge.match.input.InputPassPriority;
|
||||
import forge.match.input.InputSelectCardsFromList;
|
||||
import forge.model.FModel;
|
||||
import forge.player.HumanPlay;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SGuiDialog;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public final class GuiDisplayUtil {
|
||||
|
||||
private GuiDisplayUtil() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static void devModeGenerateMana() {
|
||||
Player pPriority = getGame().getPhaseHandler().getPriorityPlayer();
|
||||
if (pPriority == null) {
|
||||
SGuiDialog.message("No player has priority at the moment, so mana cannot be added to their pool.");
|
||||
return;
|
||||
}
|
||||
|
||||
final Card dummy = new Card(-777777);
|
||||
dummy.setOwner(pPriority);
|
||||
Map<String, String> produced = new HashMap<String, String>();
|
||||
produced.put("Produced", "W W W W W W W U U U U U U U B B B B B B B G G G G G G G R R R R R R R 7");
|
||||
final AbilityManaPart abMana = new AbilityManaPart(dummy, produced);
|
||||
getGame().getAction().invoke(new Runnable() {
|
||||
@Override public void run() { abMana.produceMana(null); }
|
||||
});
|
||||
}
|
||||
|
||||
public static void devSetupGameState() {
|
||||
int humanLife = -1;
|
||||
int computerLife = -1;
|
||||
|
||||
final Map<ZoneType, String> humanCardTexts = new EnumMap<ZoneType, String>(ZoneType.class);
|
||||
final Map<ZoneType, String> aiCardTexts = new EnumMap<ZoneType, String>(ZoneType.class);
|
||||
|
||||
String tChangePlayer = "NONE";
|
||||
String tChangePhase = "NONE";
|
||||
|
||||
File gamesDir = new File(ForgeConstants.USER_GAMES_DIR);
|
||||
if (!gamesDir.exists()) { // if the directory does not exist, try to create it
|
||||
gamesDir.mkdir();
|
||||
}
|
||||
|
||||
String filename = GuiBase.getInterface().showFileDialog("Select Game State File", ForgeConstants.USER_GAMES_DIR);
|
||||
if (filename == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final FileInputStream fstream = new FileInputStream(filename);
|
||||
final DataInputStream in = new DataInputStream(fstream);
|
||||
final BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
String temp = "";
|
||||
|
||||
while ((temp = br.readLine()) != null) {
|
||||
|
||||
final String[] tempData = temp.split("=");
|
||||
if (tempData.length < 2 || temp.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String categoryName = tempData[0].toLowerCase();
|
||||
final String categoryValue = tempData[1];
|
||||
|
||||
if (categoryName.equals("humanlife")) humanLife = Integer.parseInt(categoryValue);
|
||||
else if (categoryName.equals("ailife")) computerLife = Integer.parseInt(categoryValue);
|
||||
|
||||
else if (categoryName.equals("activeplayer")) tChangePlayer = categoryValue.trim().toLowerCase();
|
||||
else if (categoryName.equals("activephase")) tChangePhase = categoryValue;
|
||||
|
||||
else if (categoryName.equals("humancardsinplay")) humanCardTexts.put(ZoneType.Battlefield, categoryValue);
|
||||
else if (categoryName.equals("aicardsinplay")) aiCardTexts.put(ZoneType.Battlefield, categoryValue);
|
||||
else if (categoryName.equals("humancardsinhand")) humanCardTexts.put(ZoneType.Hand, categoryValue);
|
||||
else if (categoryName.equals("aicardsinhand")) aiCardTexts.put(ZoneType.Hand, categoryValue);
|
||||
else if (categoryName.equals("humancardsingraveyard")) humanCardTexts.put(ZoneType.Graveyard, categoryValue);
|
||||
else if (categoryName.equals("aicardsingraveyard")) aiCardTexts.put(ZoneType.Graveyard, categoryValue);
|
||||
else if (categoryName.equals("humancardsinlibrary")) humanCardTexts.put(ZoneType.Library, categoryValue);
|
||||
else if (categoryName.equals("aicardsinlibrary")) aiCardTexts.put(ZoneType.Library, categoryValue);
|
||||
else if (categoryName.equals("humancardsinexile")) humanCardTexts.put(ZoneType.Exile, categoryValue);
|
||||
else if (categoryName.equals("aicardsinexile")) aiCardTexts.put(ZoneType.Exile, categoryValue);
|
||||
|
||||
}
|
||||
|
||||
in.close();
|
||||
}
|
||||
catch (final FileNotFoundException fnfe) {
|
||||
SOptionPane.showErrorDialog("File not found: " + filename);
|
||||
}
|
||||
catch (final Exception e) {
|
||||
SOptionPane.showErrorDialog("Error loading battle setup file!");
|
||||
return;
|
||||
}
|
||||
|
||||
setupGameState(humanLife, computerLife, humanCardTexts, aiCardTexts, tChangePlayer, tChangePhase);
|
||||
}
|
||||
|
||||
private static void setupGameState(final int humanLife, final int computerLife, final Map<ZoneType, String> humanCardTexts,
|
||||
final Map<ZoneType, String> aiCardTexts, final String tChangePlayer, final String tChangePhase) {
|
||||
|
||||
final Game game = getGame();
|
||||
Player pPriority = game.getPhaseHandler().getPriorityPlayer();
|
||||
if (pPriority == null) {
|
||||
SGuiDialog.message("No player has priority at the moment, so game state cannot be setup.");
|
||||
return;
|
||||
}
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Player human = game.getPlayers().get(0);
|
||||
final Player ai = game.getPlayers().get(1);
|
||||
|
||||
Player newPlayerTurn = tChangePlayer.equals("human") ? newPlayerTurn = human : tChangePlayer.equals("ai") ? newPlayerTurn = ai : null;
|
||||
PhaseType newPhase = tChangePhase.trim().equalsIgnoreCase("none") ? null : PhaseType.smartValueOf(tChangePhase);
|
||||
|
||||
game.getPhaseHandler().devModeSet(newPhase, newPlayerTurn);
|
||||
|
||||
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
||||
|
||||
devSetupPlayerState(humanLife, humanCardTexts, human);
|
||||
devSetupPlayerState(computerLife, aiCardTexts, ai);
|
||||
|
||||
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
||||
|
||||
game.getAction().checkStaticAbilities();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void devSetupPlayerState(int life, Map<ZoneType, String> cardTexts, final Player p) {
|
||||
Map<ZoneType, List<Card>> humanCards = new EnumMap<ZoneType, List<Card>>(ZoneType.class);
|
||||
for(Entry<ZoneType, String> kv : cardTexts.entrySet()) {
|
||||
humanCards.put(kv.getKey(), GuiDisplayUtil.devProcessCardsForZone(kv.getValue().split(";"), p));
|
||||
}
|
||||
|
||||
if (life > 0) p.setLife(life, null);
|
||||
for (Entry<ZoneType, List<Card>> kv : humanCards.entrySet()) {
|
||||
if (kv.getKey() == ZoneType.Battlefield) {
|
||||
for (final Card c : kv.getValue()) {
|
||||
p.getZone(ZoneType.Hand).add(c);
|
||||
p.getGame().getAction().moveToPlay(c);
|
||||
c.setSickness(false);
|
||||
}
|
||||
} else {
|
||||
p.getZone(kv.getKey()).setCards(kv.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devProcessCardsForZone.
|
||||
* </p>
|
||||
*
|
||||
* @param data
|
||||
* an array of {@link java.lang.String} objects.
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
private static List<Card> devProcessCardsForZone(final String[] data, final Player player) {
|
||||
final List<Card> cl = new ArrayList<Card>();
|
||||
for (final String element : data) {
|
||||
final String[] cardinfo = element.trim().split("\\|");
|
||||
|
||||
final Card c = Card.fromPaperCard(FModel.getMagicDb().getCommonCards().getCard(cardinfo[0]), player);
|
||||
|
||||
boolean hasSetCurSet = false;
|
||||
for (final String info : cardinfo) {
|
||||
if (info.startsWith("Set:")) {
|
||||
c.setCurSetCode(info.substring(info.indexOf(':') + 1));
|
||||
hasSetCurSet = true;
|
||||
} else if (info.equalsIgnoreCase("Tapped:True")) {
|
||||
c.tap();
|
||||
} else if (info.startsWith("Counters:")) {
|
||||
final String[] counterStrings = info.substring(info.indexOf(':') + 1).split(",");
|
||||
for (final String counter : counterStrings) {
|
||||
c.addCounter(CounterType.valueOf(counter), 1, true);
|
||||
}
|
||||
} else if (info.equalsIgnoreCase("SummonSick:True")) {
|
||||
c.setSickness(true);
|
||||
} else if (info.equalsIgnoreCase("FaceDown:True")) {
|
||||
c.setState(CardCharacteristicName.FaceDown);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasSetCurSet) {
|
||||
c.setCurSetCode(c.getMostRecentSet());
|
||||
}
|
||||
|
||||
cl.add(c);
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeTutor.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeTutor() {
|
||||
Player pPriority = getGame().getPhaseHandler().getPriorityPlayer();
|
||||
if (pPriority == null) {
|
||||
SGuiDialog.message("No player has priority at the moment, so their deck can't be tutored from.");
|
||||
return;
|
||||
}
|
||||
|
||||
final List<Card> lib = pPriority.getCardsIn(ZoneType.Library);
|
||||
final Card card = SGuiChoose.oneOrNone("Choose a card", lib);
|
||||
if (card == null) { return; }
|
||||
|
||||
getGame().getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getGame().getAction().moveToHand(card);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeAddCounter.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeAddCounter() {
|
||||
final Card card = SGuiChoose.oneOrNone("Add counters to which card?", getGame().getCardsIn(ZoneType.Battlefield));
|
||||
if (card == null) { return; }
|
||||
|
||||
final CounterType counter = SGuiChoose.oneOrNone("Which type of counter?", CounterType.values());
|
||||
if (counter == null) { return; }
|
||||
|
||||
final Integer count = SGuiChoose.getInteger("How many counters?", 1, Integer.MAX_VALUE, 10);
|
||||
if (count == null) { return; }
|
||||
|
||||
card.addCounter(counter, count, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeTapPerm.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeTapPerm() {
|
||||
final Game game = getGame();
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<Card> untapped = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Predicates.not(CardPredicates.Presets.TAPPED));
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(0, Integer.MAX_VALUE, untapped);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.setMessage("Choose permanents to tap");
|
||||
inp.showAndWait();
|
||||
if (!inp.hasCancelled()) {
|
||||
for (Card c : inp.getSelected()) {
|
||||
c.tap();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeUntapPerm.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void devModeUntapPerm() {
|
||||
final Game game = getGame();
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<Card> tapped = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.TAPPED);
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(0, Integer.MAX_VALUE, tapped);
|
||||
inp.setCancelAllowed(true);
|
||||
inp.setMessage("Choose permanents to untap");
|
||||
inp.showAndWait();
|
||||
if( !inp.hasCancelled() )
|
||||
for(Card c : inp.getSelected())
|
||||
c.untap();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeSetLife.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.1.3
|
||||
*/
|
||||
public static void devModeSetLife() {
|
||||
final List<Player> players = getGame().getPlayers();
|
||||
final Player player = SGuiChoose.oneOrNone("Set life for which player?", players);
|
||||
if (player == null) { return; }
|
||||
|
||||
final Integer life = SGuiChoose.getInteger("Set life to what?", 0);
|
||||
if (life == null) { return; }
|
||||
|
||||
player.setLife(life, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeWinGame.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.5.23
|
||||
*/
|
||||
public static void devModeWinGame() {
|
||||
Input input = GuiBase.getInterface().getInputQueue().getInput();
|
||||
if (!(input instanceof InputPassPriority)) {
|
||||
SOptionPane.showMessageDialog("You must have priority to use this feature.", "Win Game", SOptionPane.INFORMATION_ICON);
|
||||
return;
|
||||
}
|
||||
|
||||
//set life of all other players to 0
|
||||
LobbyPlayer guiPlayer = GuiBase.getInterface().getGuiPlayer();
|
||||
final List<Player> players = getGame().getPlayers();
|
||||
for (Player player : players) {
|
||||
if (player.getLobbyPlayer() != guiPlayer) {
|
||||
player.setLife(0, null);
|
||||
}
|
||||
}
|
||||
|
||||
//pass priority so that causes gui player to win
|
||||
input.selectButtonOK();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* devModeTutorAnyCard.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.2.7
|
||||
*/
|
||||
public static void devModeCardToHand() {
|
||||
final List<Player> players = getGame().getPlayers();
|
||||
final Player p = SGuiChoose.oneOrNone("Put card in hand for which player?", players);
|
||||
if (null == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<PaperCard> cards = Lists.newArrayList(FModel.getMagicDb().getCommonCards().getUniqueCards());
|
||||
Collections.sort(cards);
|
||||
|
||||
// use standard forge's list selection dialog
|
||||
final IPaperCard c = SGuiChoose.oneOrNone("Name the card", cards);
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
getGame().getAction().invoke(new Runnable() { @Override public void run() {
|
||||
getGame().getAction().moveToHand(Card.fromPaperCard(c, p));
|
||||
}});
|
||||
}
|
||||
|
||||
public static void devModeCardToBattlefield() {
|
||||
final List<Player> players = getGame().getPlayers();
|
||||
final Player p = SGuiChoose.oneOrNone("Put card in play for which player?", players);
|
||||
if (null == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<PaperCard> cards = Lists.newArrayList(FModel.getMagicDb().getCommonCards().getUniqueCards());
|
||||
Collections.sort(cards);
|
||||
|
||||
// use standard forge's list selection dialog
|
||||
final IPaperCard c = SGuiChoose.oneOrNone("Name the card", cards);
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Game game = getGame();
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override public void run() {
|
||||
final Card forgeCard = Card.fromPaperCard(c, p);
|
||||
|
||||
if (c.getRules().getType().isLand()) {
|
||||
game.getAction().moveToPlay(forgeCard);
|
||||
} else {
|
||||
final List<SpellAbility> choices = forgeCard.getBasicSpells();
|
||||
if (choices.isEmpty()) {
|
||||
return; // when would it happen?
|
||||
}
|
||||
|
||||
final SpellAbility sa = choices.size() == 1 ? choices.get(0) : SGuiChoose.oneOrNone("Choose", choices);
|
||||
if (sa == null) {
|
||||
return; // happens if cancelled
|
||||
}
|
||||
|
||||
game.getAction().moveToHand(forgeCard); // this is really needed (for rollbacks at least)
|
||||
// Human player is choosing targets for an ability controlled by chosen player.
|
||||
sa.setActivatingPlayer(p);
|
||||
HumanPlay.playSaWithoutPayingManaCost(game, sa, true);
|
||||
}
|
||||
game.getStack().addAllTriggeredAbilitiesToStack(); // playSa could fire some triggers
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void devModeRiggedPlanarRoll() {
|
||||
final List<Player> players = getGame().getPlayers();
|
||||
final Player player = SGuiChoose.oneOrNone("Which player should roll?", players);
|
||||
if (player == null) { return; }
|
||||
|
||||
final PlanarDice res = SGuiChoose.oneOrNone("Choose result", PlanarDice.values());
|
||||
if (res == null) { return; }
|
||||
|
||||
System.out.println("Rigging planar dice roll: " + res.toString());
|
||||
|
||||
//DBG
|
||||
//System.out.println("ActivePlanes: " + getGame().getActivePlanes());
|
||||
//System.out.println("CommandPlanes: " + getGame().getCardsIn(ZoneType.Command));
|
||||
|
||||
|
||||
|
||||
getGame().getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PlanarDice.roll(player, res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void devModePlaneswalkTo() {
|
||||
final Game game = getGame();
|
||||
if (!game.getRules().hasAppliedVariant(GameType.Planechase)) { return; }
|
||||
final Player p = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
final List<PaperCard> allPlanars = new ArrayList<PaperCard>();
|
||||
for (PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
|
||||
if (c.getRules().getType().isPlane() || c.getRules().getType().isPhenomenon()) {
|
||||
allPlanars.add(c);
|
||||
}
|
||||
}
|
||||
Collections.sort(allPlanars);
|
||||
|
||||
// use standard forge's list selection dialog
|
||||
final IPaperCard c = SGuiChoose.oneOrNone("Name the card", allPlanars);
|
||||
if (c == null) { return; }
|
||||
final Card forgeCard = Card.fromPaperCard(c, p);
|
||||
|
||||
forgeCard.setOwner(p);
|
||||
getGame().getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getGame().getAction().changeZone(null, p.getZone(ZoneType.PlanarDeck), forgeCard, 0);
|
||||
PlanarDice.roll(p, PlanarDice.Planeswalk);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Game getGame() {
|
||||
return GuiBase.getInterface().getGame();
|
||||
}
|
||||
|
||||
public static String getPlayerName() {
|
||||
return FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
}
|
||||
|
||||
public static String personalizeHuman(String text) {
|
||||
String playerName = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
public static String personalizeHuman(final String text) {
|
||||
final String playerName = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
return text.replaceAll("(?i)human", playerName);
|
||||
}
|
||||
|
||||
} // end class GuiDisplayUtil
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package forge.util;
|
||||
|
||||
import forge.FThreads;
|
||||
|
||||
public abstract class WaitCallback<T> extends Callback<T> implements Runnable {
|
||||
public class Lock {
|
||||
}
|
||||
|
||||
private final Lock lock = new Lock();
|
||||
|
||||
private T result;
|
||||
|
||||
@Override
|
||||
public final void run(T result0) {
|
||||
result = result0;
|
||||
synchronized(lock) {
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public final T invokeAndWait() {
|
||||
FThreads.assertExecutedByEdt(false); //not supported if on UI thread
|
||||
FThreads.invokeInEdtLater(this);
|
||||
try {
|
||||
synchronized(lock) {
|
||||
lock.wait();
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,8 @@ import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.card.Card;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.view.CardView;
|
||||
|
||||
public class SGuiChoose {
|
||||
/**
|
||||
@@ -31,19 +31,19 @@ public class SGuiChoose {
|
||||
* getChoices.
|
||||
* @see #getChoices(String, int, int, Object...)
|
||||
*/
|
||||
public static <T> T oneOrNone(final String message, final T[] choices) {
|
||||
public static <T> T oneOrNone(final IGuiBase gui, final String message, final T[] choices) {
|
||||
if ((choices == null) || (choices.length == 0)) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = SGuiChoose.getChoices(message, 0, 1, choices);
|
||||
final List<T> choice = SGuiChoose.getChoices(gui, message, 0, 1, choices);
|
||||
return choice.isEmpty() ? null : choice.get(0);
|
||||
}
|
||||
|
||||
public static <T> T oneOrNone(final String message, final Collection<T> choices) {
|
||||
public static <T> T oneOrNone(final IGuiBase gui, final String message, final Collection<T> choices) {
|
||||
if ((choices == null) || choices.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final List<T> choice = SGuiChoose.getChoices(message, 0, 1, choices);
|
||||
final List<T> choice = SGuiChoose.getChoices(gui, message, 0, 1, choices);
|
||||
return choice.isEmpty() ? null : choice.get(0);
|
||||
}
|
||||
|
||||
@@ -61,13 +61,13 @@ public class SGuiChoose {
|
||||
* 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);
|
||||
public static <T> T one(final IGuiBase gui, final String message, final T[] choices) {
|
||||
final List<T> choice = SGuiChoose.getChoices(gui, message, 1, 1, choices);
|
||||
assert choice.size() == 1;
|
||||
return choice.get(0);
|
||||
}
|
||||
|
||||
public static <T> T one(final String message, final Collection<T> choices) {
|
||||
public static <T> T one(final IGuiBase gui, final String message, final Collection<T> choices) {
|
||||
if (choices == null || choices.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
@@ -75,48 +75,48 @@ public class SGuiChoose {
|
||||
return Iterables.getFirst(choices, null);
|
||||
}
|
||||
|
||||
final List<T> choice = SGuiChoose.getChoices(message, 1, 1, choices);
|
||||
final List<T> choice = SGuiChoose.getChoices(gui, message, 1, 1, choices);
|
||||
assert choice.size() == 1;
|
||||
return choice.get(0);
|
||||
}
|
||||
|
||||
public static <T> List<T> noneOrMany(final String message, final Collection<T> choices) {
|
||||
return SGuiChoose.getChoices(message, 0, choices.size(), choices, null, null);
|
||||
public static <T> List<T> noneOrMany(final IGuiBase gui, final String message, final Collection<T> choices) {
|
||||
return SGuiChoose.getChoices(gui, 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) {
|
||||
public static <T> void reveal(final IGuiBase gui, final String message, final T item) {
|
||||
List<T> items = new ArrayList<T>();
|
||||
items.add(item);
|
||||
reveal(message, items);
|
||||
reveal(gui, 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 IGuiBase gui, final String message, final T[] items) {
|
||||
SGuiChoose.getChoices(gui, message, -1, -1, items);
|
||||
}
|
||||
public static <T> void reveal(final String message, final Collection<T> items) {
|
||||
SGuiChoose.getChoices(message, -1, -1, items);
|
||||
public static <T> void reveal(final IGuiBase gui, final String message, final Collection<T> items) {
|
||||
SGuiChoose.getChoices(gui, 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 IGuiBase gui, final String message) {
|
||||
return getInteger(gui, 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 IGuiBase gui, final String message, int min) {
|
||||
return getInteger(gui, message, min, Integer.MAX_VALUE, false);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max) {
|
||||
return getInteger(message, min, max, false);
|
||||
public static Integer getInteger(final IGuiBase gui, final String message, int min, int max) {
|
||||
return getInteger(gui, message, min, max, false);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max, boolean sortDesc) {
|
||||
public static Integer getInteger(final IGuiBase gui, final String message, int min, int max, 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);
|
||||
return getInteger(gui, message, min, max, min + 99);
|
||||
}
|
||||
int count = max - min + 1;
|
||||
if (count > 100) {
|
||||
return getInteger(message, min, max, min + 99);
|
||||
return getInteger(gui, message, min, max, min + 99);
|
||||
}
|
||||
|
||||
final Integer[] choices = new Integer[count];
|
||||
@@ -130,13 +130,13 @@ public class SGuiChoose {
|
||||
choices[i] = Integer.valueOf(i + min);
|
||||
}
|
||||
}
|
||||
return SGuiChoose.oneOrNone(message, choices);
|
||||
return SGuiChoose.oneOrNone(gui, message, choices);
|
||||
}
|
||||
public static Integer getInteger(final String message, int min, int max, int cutoff) {
|
||||
public static Integer getInteger(final IGuiBase gui, final String message, int min, int max, int cutoff) {
|
||||
if (max <= min || cutoff < min) { return min; } //just return min if max <= min or cutoff < min
|
||||
|
||||
if (cutoff >= max) { //fallback to regular integer prompt if cutoff at or after max
|
||||
return getInteger(message, min, max);
|
||||
return getInteger(gui, message, min, max);
|
||||
}
|
||||
|
||||
List<Object> choices = new ArrayList<Object>();
|
||||
@@ -145,7 +145,7 @@ public class SGuiChoose {
|
||||
}
|
||||
choices.add("Other...");
|
||||
|
||||
Object choice = SGuiChoose.oneOrNone(message, choices);
|
||||
Object choice = SGuiChoose.oneOrNone(gui, message, choices);
|
||||
if (choice instanceof Integer || choice == null) {
|
||||
return (Integer)choice;
|
||||
}
|
||||
@@ -166,7 +166,7 @@ public class SGuiChoose {
|
||||
prompt += ":";
|
||||
|
||||
while (true) {
|
||||
String str = SOptionPane.showInputDialog(prompt, message);
|
||||
String str = SOptionPane.showInputDialog(gui, prompt, message);
|
||||
if (str == null) { return null; } // that is 'cancel'
|
||||
|
||||
if (StringUtils.isNumeric(str)) {
|
||||
@@ -179,30 +179,30 @@ public class SGuiChoose {
|
||||
}
|
||||
|
||||
// returned Object will never be null
|
||||
public static <T> List<T> getChoices(final String message, final int min, final int max, final T[] choices) {
|
||||
return getChoices(message, min, max, Arrays.asList(choices), null, null);
|
||||
public static <T> List<T> getChoices(final IGuiBase gui, final String message, final int min, final int max, final T[] choices) {
|
||||
return getChoices(gui, message, min, max, Arrays.asList(choices), null, null);
|
||||
}
|
||||
|
||||
public static <T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices) {
|
||||
return getChoices(message, min, max, choices, null, null);
|
||||
public static <T> List<T> getChoices(final IGuiBase gui, final String message, final int min, final int max, final Collection<T> choices) {
|
||||
return getChoices(gui, message, min, max, choices, null, null);
|
||||
}
|
||||
|
||||
public static <T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display) {
|
||||
return GuiBase.getInterface().getChoices(message, min, max, choices, selected, display);
|
||||
public static <T> List<T> getChoices(final IGuiBase gui, final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display) {
|
||||
return gui.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, Card referenceCard) {
|
||||
return order(title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false);
|
||||
public static <T> List<T> many(final IGuiBase gui, final String title, final String topCaption, int cnt, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
return order(gui, title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, Card referenceCard) {
|
||||
public static <T> List<T> many(final IGuiBase gui, final String title, final String topCaption, int min, int max, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
int m2 = min >= 0 ? sourceChoices.size() - min : -1;
|
||||
int m1 = max >= 0 ? sourceChoices.size() - max : -1;
|
||||
return order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, false);
|
||||
return order(gui, title, topCaption, m1, m2, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> order(final String title, final String top, final List<T> sourceChoices, Card referenceCard) {
|
||||
return order(title, top, 0, 0, sourceChoices, null, referenceCard, false);
|
||||
public static <T> List<T> order(final IGuiBase gui, final String title, final String top, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
return order(gui, title, top, 0, 0, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,8 +215,8 @@ public class SGuiChoose {
|
||||
* @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);
|
||||
public static <T> List<T> insertInList(final IGuiBase gui, final String title, final T newItem, final List<T> oldItems) {
|
||||
final T placeAfter = oneOrNone(gui, title, oldItems);
|
||||
final int indexAfter = (placeAfter == null ? 0 : oldItems.indexOf(placeAfter) + 1);
|
||||
final List<T> result = Lists.newArrayListWithCapacity(oldItems.size() + 1);
|
||||
result.addAll(oldItems);
|
||||
@@ -224,63 +224,62 @@ public class SGuiChoose {
|
||||
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, final Card referenceCard, final boolean sideboardingMode) {
|
||||
return GuiBase.getInterface().order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode);
|
||||
private static <T> List<T> order(final IGuiBase gui, final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode) {
|
||||
return gui.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode);
|
||||
}
|
||||
|
||||
|
||||
// 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) {
|
||||
public static <T> T sortedOneOrNone(final IGuiBase gui, 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);
|
||||
final List<T> choice = SGuiChoose.sortedGetChoices(gui, 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) {
|
||||
public static <T> T sortedOneOrNone(final IGuiBase gui, 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);
|
||||
final List<T> choice = SGuiChoose.sortedGetChoices(gui, 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);
|
||||
public static <T> T sortedOne(final IGuiBase gui, final String message, final T[] choices, Comparator<T> comparer) {
|
||||
final List<T> choice = SGuiChoose.sortedGetChoices(gui, 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) {
|
||||
public static <T> T sortedOne(final IGuiBase gui, 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);
|
||||
final List<T> choice = SGuiChoose.sortedGetChoices(gui, 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);
|
||||
public static <T> List<T> sortedNoneOrMany(final IGuiBase gui, final String message, final List<T> choices, Comparator<T> comparer) {
|
||||
return SGuiChoose.sortedGetChoices(gui, 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) {
|
||||
public static <T> List<T> sortedGetChoices(final IGuiBase gui, 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);
|
||||
return getChoices(gui, 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) {
|
||||
public static <T> List<T> sortedGetChoices(final IGuiBase gui, 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);
|
||||
return getChoices(gui, message, min, max, choices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package forge.util.gui;
|
||||
|
||||
import forge.game.card.Card;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.view.CardView;
|
||||
|
||||
/**
|
||||
* Holds player interactions using standard windows
|
||||
*
|
||||
@@ -11,22 +12,21 @@ import org.apache.commons.lang3.StringUtils;
|
||||
public class SGuiDialog {
|
||||
private static final String[] defaultConfirmOptions = { "Yes", "No" };
|
||||
|
||||
public static boolean confirm(final Card c, final String question) {
|
||||
return SGuiDialog.confirm(c, question, true, null);
|
||||
public static boolean confirm(final IGuiBase gui, final CardView c, final String question) {
|
||||
return SGuiDialog.confirm(gui, c, question, true, null);
|
||||
}
|
||||
public static boolean confirm(final Card c, final String question, final boolean defaultChoice) {
|
||||
return SGuiDialog.confirm(c, question, defaultChoice, null);
|
||||
public static boolean confirm(final IGuiBase gui, final CardView c, final String question, final boolean defaultChoice) {
|
||||
return SGuiDialog.confirm(gui, c, question, defaultChoice, null);
|
||||
}
|
||||
public static boolean confirm(final Card c, final String question, String[] options) {
|
||||
return SGuiDialog.confirm(c, question, true, options);
|
||||
public static boolean confirm(final IGuiBase gui, final CardView c, final String question, String[] options) {
|
||||
return SGuiDialog.confirm(gui, c, question, true, options);
|
||||
}
|
||||
|
||||
public static boolean confirm(Card c, final String question, final boolean defaultIsYes, final String[] options) {
|
||||
c = Card.getCardForUi(c);
|
||||
final String title = c == null ? "Question" : c.getName() + " - Ability";
|
||||
public static boolean confirm(final IGuiBase gui, final CardView c, final String question, final boolean defaultIsYes, final String[] options) {
|
||||
final String title = c == null ? "Question" : c + " - Ability";
|
||||
String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question;
|
||||
String[] opts = options == null ? defaultConfirmOptions : options;
|
||||
int answer = SOptionPane.showCardOptionDialog(c, questionToUse, title, SOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1);
|
||||
int answer = SOptionPane.showCardOptionDialog(gui, c, questionToUse, title, SOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1);
|
||||
return answer == 0;
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ public class SGuiDialog {
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
public static void message(final String message) {
|
||||
message(message, "Forge");
|
||||
public static void message(final IGuiBase gui, final String message) {
|
||||
message(gui, message, "Forge");
|
||||
}
|
||||
|
||||
public static void message(final String message, final String title) {
|
||||
SOptionPane.showMessageDialog(message, title, null);
|
||||
public static void message(final IGuiBase gui, final String message, final String title) {
|
||||
SOptionPane.showMessageDialog(gui, message, title, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package forge.util.gui;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.card.Card;
|
||||
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.view.CardView;
|
||||
|
||||
public class SOptionPane {
|
||||
public static final FSkinProp QUESTION_ICON = FSkinProp.ICO_QUESTION;
|
||||
@@ -11,74 +10,74 @@ 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) {
|
||||
showMessageDialog(message, "Forge", INFORMATION_ICON);
|
||||
public static void showMessageDialog(IGuiBase gui, String message) {
|
||||
showMessageDialog(gui, message, "Forge", INFORMATION_ICON);
|
||||
}
|
||||
|
||||
public static void showMessageDialog(String message, String title) {
|
||||
showMessageDialog(message, title, INFORMATION_ICON);
|
||||
public static void showMessageDialog(IGuiBase gui, String message, String title) {
|
||||
showMessageDialog(gui, message, title, INFORMATION_ICON);
|
||||
}
|
||||
|
||||
public static void showErrorDialog(String message) {
|
||||
showMessageDialog(message, "Forge", ERROR_ICON);
|
||||
public static void showErrorDialog(IGuiBase gui, String message) {
|
||||
showMessageDialog(gui, message, "Forge", ERROR_ICON);
|
||||
}
|
||||
|
||||
public static void showErrorDialog(String message, String title) {
|
||||
showMessageDialog(message, title, ERROR_ICON);
|
||||
public static void showErrorDialog(IGuiBase gui, String message, String title) {
|
||||
showMessageDialog(gui, message, title, ERROR_ICON);
|
||||
}
|
||||
|
||||
public static void showMessageDialog(String message, String title, FSkinProp icon) {
|
||||
showOptionDialog(message, title, icon, new String[] {"OK"}, 0);
|
||||
public static void showMessageDialog(IGuiBase gui, String message, String title, FSkinProp icon) {
|
||||
showOptionDialog(gui, message, title, icon, new String[] {"OK"}, 0);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message) {
|
||||
return showConfirmDialog(message, "Forge");
|
||||
public static boolean showConfirmDialog(IGuiBase gui, String message) {
|
||||
return showConfirmDialog(gui, message, "Forge");
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title) {
|
||||
return showConfirmDialog(message, title, "Yes", "No", true);
|
||||
public static boolean showConfirmDialog(IGuiBase gui, String message, String title) {
|
||||
return showConfirmDialog(gui, message, title, "Yes", "No", true);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title, boolean defaultYes) {
|
||||
return showConfirmDialog(message, title, "Yes", "No", defaultYes);
|
||||
public static boolean showConfirmDialog(IGuiBase gui, String message, String title, boolean defaultYes) {
|
||||
return showConfirmDialog(gui, message, title, "Yes", "No", defaultYes);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText) {
|
||||
return showConfirmDialog(message, title, yesButtonText, noButtonText, true);
|
||||
public static boolean showConfirmDialog(IGuiBase gui, String message, String title, String yesButtonText, String noButtonText) {
|
||||
return showConfirmDialog(gui, message, title, yesButtonText, noButtonText, true);
|
||||
}
|
||||
|
||||
public static boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText, boolean defaultYes) {
|
||||
public static boolean showConfirmDialog(IGuiBase gui, 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);
|
||||
int reply = SOptionPane.showOptionDialog(gui, message, title, QUESTION_ICON, options, defaultYes ? 0 : 1);
|
||||
return (reply == 0);
|
||||
}
|
||||
|
||||
public static int showOptionDialog(String message, String title, FSkinProp icon, String[] options) {
|
||||
return showOptionDialog(message, title, icon, options, 0);
|
||||
public static int showOptionDialog(IGuiBase gui, String message, String title, FSkinProp icon, String[] options) {
|
||||
return showOptionDialog(gui, message, title, icon, options, 0);
|
||||
}
|
||||
|
||||
public static int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption) {
|
||||
return GuiBase.getInterface().showOptionDialog(message, title, icon, options, defaultOption);
|
||||
public static int showOptionDialog(IGuiBase gui, String message, String title, FSkinProp icon, String[] options, int defaultOption) {
|
||||
return gui.showOptionDialog(message, title, icon, options, defaultOption);
|
||||
}
|
||||
|
||||
public static int showCardOptionDialog(Card card, String message, String title, FSkinProp icon, String[] options, int defaultOption) {
|
||||
return GuiBase.getInterface().showCardOptionDialog(card, message, title, icon, options, defaultOption);
|
||||
public static int showCardOptionDialog(IGuiBase gui, CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption) {
|
||||
return gui.showCardOptionDialog(card, message, title, icon, options, defaultOption);
|
||||
}
|
||||
|
||||
public static String showInputDialog(String message, String title) {
|
||||
return showInputDialog(message, title, null, "", null);
|
||||
public static String showInputDialog(IGuiBase gui, String message, String title) {
|
||||
return showInputDialog(gui, message, title, null, "", null);
|
||||
}
|
||||
|
||||
public static String showInputDialog(String message, String title, FSkinProp icon) {
|
||||
return showInputDialog(message, title, icon, "", null);
|
||||
public static String showInputDialog(IGuiBase gui, String message, String title, FSkinProp icon) {
|
||||
return showInputDialog(gui, message, title, icon, "", null);
|
||||
}
|
||||
|
||||
public static String showInputDialog(String message, String title, FSkinProp icon, String initialInput) {
|
||||
return showInputDialog(message, title, icon, initialInput, null);
|
||||
public static String showInputDialog(IGuiBase gui, String message, String title, FSkinProp icon, String initialInput) {
|
||||
return showInputDialog(gui, message, title, icon, initialInput, null);
|
||||
}
|
||||
|
||||
public static <T> T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions) {
|
||||
return GuiBase.getInterface().showInputDialog(message, title, icon, initialInput, inputOptions);
|
||||
public static <T> T showInputDialog(IGuiBase gui, String message, String title, FSkinProp icon, T initialInput, T[] inputOptions) {
|
||||
return gui.showInputDialog(message, title, icon, initialInput, inputOptions);
|
||||
}
|
||||
|
||||
private SOptionPane() {
|
||||
|
||||
61
forge-gui/src/main/java/forge/view/Cache.java
Normal file
61
forge-gui/src/main/java/forge/view/Cache.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package forge.view;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class Cache<K, V> {
|
||||
|
||||
private final Map<K, V> cache;
|
||||
private final Map<V, K> inverseCache;
|
||||
public Cache() {
|
||||
this.cache = Maps.newHashMap();
|
||||
this.inverseCache = Maps.newHashMap();
|
||||
}
|
||||
|
||||
public boolean containsKey(final K key) {
|
||||
return cache.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
* @see java.util.Map#get(java.lang.Object)
|
||||
*/
|
||||
public V get(final K key) {
|
||||
return cache.get(key);
|
||||
}
|
||||
|
||||
public K getKey(final V value) {
|
||||
return inverseCache.get(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void put(final K key, final V value) {
|
||||
if (key == null || value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
if (inverseCache.containsKey(value)) {
|
||||
cache.remove(inverseCache.get(value));
|
||||
inverseCache.remove(value);
|
||||
}
|
||||
|
||||
final V oldValue = cache.put(key, value);
|
||||
inverseCache.remove(oldValue);
|
||||
inverseCache.put(value, key);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void retainAllKeys(final Collection<K> keys) {
|
||||
cache.keySet().retainAll(keys);
|
||||
inverseCache.values().retainAll(keys);
|
||||
}
|
||||
}
|
||||
1044
forge-gui/src/main/java/forge/view/CardView.java
Normal file
1044
forge-gui/src/main/java/forge/view/CardView.java
Normal file
File diff suppressed because it is too large
Load Diff
99
forge-gui/src/main/java/forge/view/CombatView.java
Normal file
99
forge-gui/src/main/java/forge/view/CombatView.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package forge.view;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public class CombatView {
|
||||
|
||||
private Map<CardView, GameEntityView> attackersWithDefenders = Maps.newHashMap();
|
||||
private Map<CardView, Iterable<CardView>> attackersWithBlockers = Maps.newHashMap();
|
||||
private Map<Iterable<CardView>, GameEntityView> bandsWithDefenders = Maps.newHashMap();
|
||||
private Map<Iterable<CardView>, Iterable<CardView>> bandsWithBlockers = Maps.newHashMap();
|
||||
|
||||
public CombatView() {
|
||||
}
|
||||
|
||||
public int getNumAttackers() {
|
||||
return attackersWithDefenders.size();
|
||||
}
|
||||
|
||||
public boolean isAttacking(final CardView card) {
|
||||
return attackersWithDefenders.containsKey(card);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getAttackers() {
|
||||
return attackersWithDefenders.keySet();
|
||||
}
|
||||
|
||||
public Iterable<GameEntityView> getDefenders() {
|
||||
return Sets.newHashSet(attackersWithDefenders.values());
|
||||
}
|
||||
|
||||
public GameEntityView getDefender(final CardView attacker) {
|
||||
return attackersWithDefenders.get(attacker);
|
||||
}
|
||||
|
||||
public boolean isBlocking(final CardView card) {
|
||||
for (final Iterable<CardView> blockers : attackersWithBlockers.values()) {
|
||||
if (blockers == null) {
|
||||
continue;
|
||||
}
|
||||
if (Iterables.contains(blockers, card)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attacker
|
||||
* @return the blockers associated with an attacker, or {@code null} if the
|
||||
* attacker is unblocked.
|
||||
*/
|
||||
public Iterable<CardView> getBlockers(final CardView attacker) {
|
||||
return attackersWithBlockers.get(attacker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an {@link Iterable} of the blockers of the specified band, or
|
||||
* {@code null} if that band is unblocked.
|
||||
*
|
||||
* @param attackingBand
|
||||
* an {@link Iterable} representing an attacking band.
|
||||
* @return an {@link Iterable} of {@link CardView} objects, or {@code null}.
|
||||
*/
|
||||
public Iterable<CardView> getBlockers(final Iterable<CardView> attackingBand) {
|
||||
return bandsWithBlockers.get(attackingBand);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getAttackersOf(final GameEntityView defender) {
|
||||
return Maps.filterValues(attackersWithDefenders, Predicates.equalTo(defender)).keySet();
|
||||
}
|
||||
public Iterable<Iterable<CardView>> getAttackingBandsOf(final GameEntityView defender) {
|
||||
return Maps.filterValues(bandsWithDefenders, Predicates.equalTo(defender)).keySet();
|
||||
}
|
||||
|
||||
public void addAttackingBand(final Iterable<CardView> attackingBand, final GameEntityView defender, final Iterable<CardView> blockers) {
|
||||
final List<CardView> attackingBandCopy = Lists.newArrayList(attackingBand),
|
||||
blockersCopy;
|
||||
if (blockers == null) {
|
||||
blockersCopy = null;
|
||||
} else {
|
||||
blockersCopy = Lists.newArrayList(blockers);
|
||||
}
|
||||
|
||||
for (final CardView attacker : attackingBandCopy) {
|
||||
this.attackersWithDefenders.put(attacker, defender);
|
||||
this.attackersWithBlockers.put(attacker, blockersCopy);
|
||||
}
|
||||
this.bandsWithDefenders.put(attackingBandCopy, defender);
|
||||
this.bandsWithBlockers.put(attackingBandCopy, blockersCopy);
|
||||
}
|
||||
|
||||
}
|
||||
5
forge-gui/src/main/java/forge/view/GameEntityView.java
Normal file
5
forge-gui/src/main/java/forge/view/GameEntityView.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package forge.view;
|
||||
|
||||
public abstract class GameEntityView {
|
||||
|
||||
}
|
||||
116
forge-gui/src/main/java/forge/view/IGameView.java
Normal file
116
forge-gui/src/main/java/forge/view/IGameView.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package forge.view;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Observer;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.GameLogEntry;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.GameOutcome;
|
||||
import forge.game.GameType;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
public interface IGameView {
|
||||
|
||||
public abstract boolean isCommander();
|
||||
|
||||
public abstract GameType getGameType();
|
||||
|
||||
// Game-related methods
|
||||
public abstract int getTurnNumber();
|
||||
public abstract boolean isCommandZoneNeeded();
|
||||
public abstract boolean isWinner(LobbyPlayer p);
|
||||
public abstract LobbyPlayer getWinningPlayer();
|
||||
public abstract int getWinningTeam();
|
||||
|
||||
// Match-related methods
|
||||
public abstract boolean isFirstGameInMatch();
|
||||
public abstract boolean isMatchOver();
|
||||
public abstract int getNumGamesInMatch();
|
||||
public abstract int getNumPlayedGamesInMatch();
|
||||
public abstract Iterable<GameOutcome> getOutcomesOfMatch();
|
||||
public abstract boolean isMatchWonBy(LobbyPlayer p);
|
||||
public abstract int getGamesWonBy(LobbyPlayer p);
|
||||
public abstract GameOutcome.AnteResult getAnteResult();
|
||||
public abstract Deck getDeck(LobbyPlayer player);
|
||||
|
||||
public abstract boolean isGameOver();
|
||||
public abstract void updateAchievements();
|
||||
|
||||
public abstract int getPoisonCountersToLose();
|
||||
|
||||
public abstract void subscribeToEvents(Object subscriber);
|
||||
|
||||
public abstract CombatView getCombat();
|
||||
|
||||
public abstract void addLogObserver(Observer o);
|
||||
public abstract List<GameLogEntry> getLogEntries(GameLogEntryType maxLogLevel);
|
||||
public abstract List<GameLogEntry> getLogEntriesExact(GameLogEntryType logLevel);
|
||||
|
||||
// Input controls
|
||||
public abstract boolean canUndoLastAction();
|
||||
public abstract boolean tryUndoLastAction();
|
||||
|
||||
public abstract void selectButtonOk();
|
||||
public abstract void selectButtonCancel();
|
||||
public abstract void confirm();
|
||||
public abstract boolean passPriority();
|
||||
public abstract boolean passPriorityUntilEndOfTurn();
|
||||
public abstract void useMana(byte mana);
|
||||
public abstract void selectPlayer(PlayerView player, ITriggerEvent triggerEvent);
|
||||
public abstract boolean selectCard(CardView card, ITriggerEvent triggerEvent);
|
||||
public abstract void selectAbility(SpellAbilityView sa);
|
||||
public abstract void alphaStrike();
|
||||
|
||||
// the following method should eventually be replaced by methods returning
|
||||
// View classes
|
||||
@Deprecated
|
||||
public abstract RegisteredPlayer getGuiRegisteredPlayer(LobbyPlayer p);
|
||||
|
||||
public abstract List<PlayerView> getPlayers();
|
||||
|
||||
public abstract PlayerView getPlayerTurn();
|
||||
|
||||
public abstract PhaseType getPhase();
|
||||
|
||||
public abstract List<StackItemView> getStack();
|
||||
public abstract StackItemView peekStack();
|
||||
|
||||
public abstract boolean mayShowCard(CardView c);
|
||||
public abstract boolean mayShowCardFace(CardView c);
|
||||
|
||||
// Auto-yield related methods
|
||||
public abstract Iterable<String> getAutoYields();
|
||||
public abstract boolean shouldAutoYield(String key);
|
||||
public abstract void setShouldAutoYield(String key, boolean autoYield);
|
||||
public abstract boolean getDisableAutoYields();
|
||||
public abstract void setDisableAutoYields(boolean b);
|
||||
|
||||
public abstract boolean shouldAlwaysAcceptTrigger(Integer trigger);
|
||||
public abstract boolean shouldAlwaysDeclineTrigger(Integer trigger);
|
||||
public abstract boolean shouldAlwaysAskTrigger(Integer trigger);
|
||||
|
||||
public abstract void setShouldAlwaysAcceptTrigger(Integer trigger);
|
||||
public abstract void setShouldAlwaysDeclineTrigger(Integer trigger);
|
||||
public abstract void setShouldAlwaysAskTrigger(Integer trigger);
|
||||
|
||||
public abstract void autoPassCancel();
|
||||
|
||||
public abstract void devTogglePlayManyLands(boolean b);
|
||||
public abstract void devGenerateMana();
|
||||
public abstract void devSetupGameState();
|
||||
public abstract void devTutorForCard();
|
||||
public abstract void devAddCardToHand();
|
||||
public abstract void devAddCounterToPermanent();
|
||||
public abstract void devTapPermanent();
|
||||
public abstract void devUntapPermanent();
|
||||
public abstract void devSetPlayerLife();
|
||||
public abstract void devWinGame();
|
||||
public abstract void devAddCardToBattlefield();
|
||||
public abstract void devRiggedPlanerRoll();
|
||||
public abstract void devPlaneswalkTo();
|
||||
|
||||
}
|
||||
553
forge-gui/src/main/java/forge/view/LocalGameView.java
Normal file
553
forge-gui/src/main/java/forge/view/LocalGameView.java
Normal file
@@ -0,0 +1,553 @@
|
||||
package forge.view;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Observer;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.MagicColor;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameLogEntry;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.GameOutcome;
|
||||
import forge.game.GameType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.combat.AttackingBand;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public abstract class LocalGameView implements IGameView {
|
||||
|
||||
private final Game game;
|
||||
public LocalGameView(final Game game) {
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
protected final Game getGame() {
|
||||
return this.game;
|
||||
}
|
||||
|
||||
/** Cache of players. */
|
||||
private final Cache<Player, PlayerView> players = new Cache<>();
|
||||
/** Cache of cards. */
|
||||
private final Cache<Card, CardView> cards = new Cache<>();
|
||||
/** Cache of spellabilities. */
|
||||
private final Cache<SpellAbility, SpellAbilityView> spabs = new Cache<>();
|
||||
/** Cache of stack items. */
|
||||
private final Cache<SpellAbilityStackInstance, StackItemView> stackItems = new Cache<>();
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#isCommander()
|
||||
*/
|
||||
@Override
|
||||
public boolean isCommander() {
|
||||
return game.getRules().hasAppliedVariant(GameType.Commander);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getGameType()
|
||||
*/
|
||||
@Override
|
||||
public GameType getGameType() {
|
||||
return this.game.getMatch().getRules().getGameType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTurnNumber() {
|
||||
return this.game.getPhaseHandler().getTurn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCommandZoneNeeded() {
|
||||
return this.game.getMatch().getRules().getGameType().isCommandZoneNeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWinner(final LobbyPlayer p) {
|
||||
return game.getOutcome() == null ? null : game.getOutcome().isWinner(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LobbyPlayer getWinningPlayer() {
|
||||
return game.getOutcome() == null ? null : game.getOutcome().getWinningLobbyPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWinningTeam() {
|
||||
return game.getOutcome() == null ? -1 : game.getOutcome().getWinningTeam();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#isFirstGameInMatch()
|
||||
*/
|
||||
@Override
|
||||
public boolean isFirstGameInMatch() {
|
||||
return this.game.getMatch().getPlayedGames().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchOver() {
|
||||
return this.game.getMatch().isMatchOver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumGamesInMatch() {
|
||||
return this.game.getMatch().getRules().getGamesPerMatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumPlayedGamesInMatch() {
|
||||
return this.game.getMatch().getPlayedGames().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<GameOutcome> getOutcomesOfMatch() {
|
||||
return Iterables.unmodifiableIterable(this.game.getMatch().getPlayedGames());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchWonBy(final LobbyPlayer p) {
|
||||
return this.game.getMatch().isWonBy(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGamesWonBy(final LobbyPlayer p) {
|
||||
return this.game.getMatch().getGamesWonBy(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameOutcome.AnteResult getAnteResult() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deck getDeck(final LobbyPlayer player) {
|
||||
for (final RegisteredPlayer rp : this.game.getMatch().getPlayers()) {
|
||||
if (rp.getPlayer().equals(player)) {
|
||||
return rp.getDeck();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#isGameOver()
|
||||
*/
|
||||
@Override
|
||||
public boolean isGameOver() {
|
||||
return game.isGameOver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPoisonCountersToLose() {
|
||||
return game.getRules().getPoisonCountersToLose();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#subscribeToEvents(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void subscribeToEvents(final Object subscriber) {
|
||||
game.subscribeToEvents(subscriber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombatView getCombat() {
|
||||
return getCombat(game.getCombat());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getCombat()
|
||||
*/
|
||||
public CombatView getCombat(final Combat combat) {
|
||||
if (combat == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final CombatView combatView = new CombatView();
|
||||
for (final AttackingBand b : combat.getAttackingBands()) {
|
||||
if (b == null) continue;
|
||||
final GameEntity defender = combat.getDefenderByAttacker(b);
|
||||
final List<Card> blockers = (b.isBlocked() != null && b.isBlocked()) ? combat.getBlockers(b) : null;
|
||||
combatView.addAttackingBand(getCardViews(b.getAttackers()), getGameEntityView(defender), blockers == null ? null : getCardViews(blockers));
|
||||
}
|
||||
return combatView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLogObserver(final Observer o) {
|
||||
game.getGameLog().addObserver(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GameLogEntry> getLogEntries(final GameLogEntryType maxLogLevel) {
|
||||
return game.getGameLog().getLogEntries(maxLogLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GameLogEntry> getLogEntriesExact(final GameLogEntryType logLevel) {
|
||||
return game.getGameLog().getLogEntriesExact(logLevel);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getGuiRegisteredPlayer(forge.LobbyPlayer)
|
||||
*/
|
||||
@Override
|
||||
public RegisteredPlayer getGuiRegisteredPlayer(final LobbyPlayer p) {
|
||||
for (final RegisteredPlayer player : game.getMatch().getPlayers()) {
|
||||
if (player.getPlayer() == p) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getRegisteredPlayers()
|
||||
*/
|
||||
@Override
|
||||
public List<PlayerView> getPlayers() {
|
||||
return getPlayerViews(game.getRegisteredPlayers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerView getPlayerTurn() {
|
||||
return getPlayerView(game.getPhaseHandler().getPlayerTurn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhaseType getPhase() {
|
||||
return game.getPhaseHandler().getPhase();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getStack()
|
||||
*/
|
||||
@Override
|
||||
public List<StackItemView> getStack() {
|
||||
final List<SpellAbilityStackInstance> stack = Lists.newArrayList(game.getStack());
|
||||
final List<StackItemView> items = Collections.unmodifiableList(getStack(stack));
|
||||
// clear the cache
|
||||
stackItems.retainAllKeys(stack);
|
||||
return items;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#peekStack()
|
||||
*/
|
||||
@Override
|
||||
public StackItemView peekStack() {
|
||||
final SpellAbilityStackInstance top =
|
||||
Iterables.getFirst(game.getStack(), null);
|
||||
if (top == null) {
|
||||
return null;
|
||||
}
|
||||
return getStack(Lists.newArrayList(top)).iterator().next();
|
||||
}
|
||||
|
||||
private List<StackItemView> getStack(final Iterable<SpellAbilityStackInstance> stack) {
|
||||
synchronized (this) {
|
||||
stackItems.retainAllKeys(Lists.newArrayList(stack));
|
||||
final List<StackItemView> items = Lists.newLinkedList();
|
||||
for (final SpellAbilityStackInstance si : stack) {
|
||||
if (stackItems.containsKey(si)) {
|
||||
items.add(stackItems.get(si));
|
||||
} else {
|
||||
items.add(getStackItemView(si));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
public StackItemView getStackItemView(final SpellAbilityStackInstance si) {
|
||||
final StackItemView newItem = new StackItemView(
|
||||
si.getSpellAbility().toUnsuppressedString(),
|
||||
si.getSpellAbility().getSourceTrigger(),
|
||||
si.getStackDescription(), getCardView(si.getSourceCard()),
|
||||
getPlayerView(si.getActivator()), getCardViews(si.getTargetChoices().getTargetCards()),
|
||||
getPlayerViews(si.getTargetChoices().getTargetPlayers()), si.isAbility(), si.isOptionalTrigger());
|
||||
stackItems.put(si, newItem);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
public SpellAbilityStackInstance getStackItem(final StackItemView view) {
|
||||
return stackItems.getKey(view);
|
||||
}
|
||||
|
||||
public final GameEntityView getGameEntityView(final GameEntity e) {
|
||||
if (e instanceof Card) {
|
||||
return getCardView((Card)e);
|
||||
} else if (e instanceof Player) {
|
||||
return getPlayerView((Player)e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private final Function<GameEntity, GameEntityView> FN_GET_GAME_ENTITY_VIEW = new Function<GameEntity, GameEntityView>() {
|
||||
@Override
|
||||
public GameEntityView apply(GameEntity input) {
|
||||
return getGameEntityView(input);
|
||||
}
|
||||
};
|
||||
|
||||
public final List<GameEntityView> getGameEntityViews(final Iterable<GameEntity> entities) {
|
||||
return ViewUtil.transformIfNotNull(entities, FN_GET_GAME_ENTITY_VIEW);
|
||||
}
|
||||
|
||||
public final GameEntity getGameEntity(final GameEntityView view) {
|
||||
if (view instanceof CardView) {
|
||||
return getCard((CardView) view);
|
||||
} else if (view instanceof PlayerView) {
|
||||
return getPlayer((PlayerView) view);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private final Function<Player, PlayerView> FN_GET_PLAYER_VIEW = new Function<Player, PlayerView>() {
|
||||
@Override
|
||||
public PlayerView apply(final Player input) {
|
||||
return getPlayerView(input);
|
||||
}
|
||||
};
|
||||
|
||||
public final List<PlayerView> getPlayerViews(final Iterable<Player> players) {
|
||||
return ViewUtil.transformIfNotNull(players, FN_GET_PLAYER_VIEW);
|
||||
}
|
||||
|
||||
public PlayerView getPlayerView(final Player p) {
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PlayerView view;
|
||||
if (players.containsKey(p)) {
|
||||
view = players.get(p);
|
||||
getPlayerView(p, view);
|
||||
} else {
|
||||
view = new PlayerView(p.getLobbyPlayer(), p.getId());
|
||||
players.put(p, view);
|
||||
getPlayerView(p, view);
|
||||
view.setOpponents(getPlayerViews(p.getOpponents()));
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private PlayerView getPlayerViewFast(final Player p) {
|
||||
return players.get(p);
|
||||
}
|
||||
|
||||
public Player getPlayer(final PlayerView p) {
|
||||
return players.getKey(p);
|
||||
}
|
||||
|
||||
private void getPlayerView(final Player p, final PlayerView view) {
|
||||
view.setCommanderInfo(CardFactoryUtil.getCommanderInfo(p).trim().replace("\r\n", "; "));
|
||||
view.setKeywords(p.getKeywords());
|
||||
view.setLife(p.getLife());
|
||||
view.setMaxHandSize(p.getMaxHandSize());
|
||||
view.setNumDrawnThisTurn(p.getNumDrawnThisTurn());
|
||||
view.setPoisonCounters(p.getPoisonCounters());
|
||||
view.setPreventNextDamage(p.getPreventNextDamageTotalShields());
|
||||
view.setHasUnlimitedHandSize(p.isUnlimitedHandSize());
|
||||
view.setAnteCards(getCardViews(p.getCardsIn(ZoneType.Ante)));
|
||||
view.setBfCards(getCardViews(p.getCardsIn(ZoneType.Battlefield)));
|
||||
view.setCommandCards(getCardViews(p.getCardsIn(ZoneType.Command)));
|
||||
view.setExileCards(getCardViews(p.getCardsIn(ZoneType.Exile)));
|
||||
view.setFlashbackCards(getCardViews(p.getCardsActivableInExternalZones(false)));
|
||||
view.setGraveCards(getCardViews(p.getCardsIn(ZoneType.Graveyard)));
|
||||
final List<Card> handCards = p.getCardsIn(ZoneType.Hand),
|
||||
libraryCards = p.getCardsIn(ZoneType.Library);
|
||||
view.setHandCards(getCardViews(handCards));
|
||||
view.setLibraryCards(getCardViews(libraryCards));
|
||||
view.setnHandCards(handCards.size());
|
||||
view.setnLibraryCards(libraryCards.size());
|
||||
|
||||
for (final byte b : MagicColor.WUBRGC) {
|
||||
view.setMana(b, p.getManaPool().getAmountOfColor(b));
|
||||
}
|
||||
}
|
||||
|
||||
public CardView getCardView(final Card c) {
|
||||
if (c == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Card cUi = c.getCardForUi();
|
||||
final boolean isDisplayable = cUi == c &&
|
||||
!(c.isInZone(ZoneType.Hand) || c.isInZone(ZoneType.Library));
|
||||
|
||||
CardView view = cards.get(c);
|
||||
final boolean mayShow;
|
||||
if (view != null) {
|
||||
// Put here again to ensure the Card reference in the cache
|
||||
// is not an outdated Card.
|
||||
cards.put(c, view);
|
||||
mayShow = mayShowCard(view);
|
||||
} else {
|
||||
view = new CardView(isDisplayable);
|
||||
mayShow = mayShowCard(view);
|
||||
if (isDisplayable && mayShow) {
|
||||
cards.put(c, view);
|
||||
}
|
||||
}
|
||||
|
||||
if (mayShow) {
|
||||
writeCardToView(cUi, view);
|
||||
} else if (isDisplayable) {
|
||||
view.reset();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private final Function<Card, CardView> FN_GET_CARD_VIEW = new Function<Card, CardView>() {
|
||||
@Override
|
||||
public CardView apply(final Card input) {
|
||||
return getCardView(input);
|
||||
}
|
||||
};
|
||||
|
||||
public final List<CardView> getCardViews(final Iterable<Card> cards) {
|
||||
return ViewUtil.transformIfNotNull(cards, FN_GET_CARD_VIEW);
|
||||
}
|
||||
|
||||
private CardView getCardViewFast(final Card c) {
|
||||
if (c == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final CardView view = cards.get(c);
|
||||
if (mayShowCard(view)) {
|
||||
return view;
|
||||
} else if (view.isUiDisplayable()) {
|
||||
view.reset();
|
||||
return view;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private final Function<Card, CardView> FN_GET_CARDVIEW_FAST = new Function<Card, CardView>() {
|
||||
@Override
|
||||
public CardView apply(Card input) {
|
||||
return getCardViewFast(input);
|
||||
}
|
||||
};
|
||||
|
||||
private List<CardView> getCardViewsFast(final Iterable<Card> cards) {
|
||||
return ViewUtil.transformIfNotNull(cards, FN_GET_CARDVIEW_FAST);
|
||||
}
|
||||
|
||||
public Card getCard(final CardView c) {
|
||||
return cards.getKey(c);
|
||||
}
|
||||
|
||||
private final Function<CardView, Card> FN_GET_CARD = new Function<CardView, Card>() {
|
||||
@Override
|
||||
public Card apply(final CardView input) {
|
||||
return getCard(input);
|
||||
}
|
||||
};
|
||||
|
||||
public final List<Card> getCards(final List<CardView> cards) {
|
||||
return ViewUtil.transformIfNotNull(cards, FN_GET_CARD);
|
||||
}
|
||||
|
||||
private void writeCardToView(final Card c, final CardView view) {
|
||||
// First, write the values independent of other views.
|
||||
ViewUtil.writeNonDependentCardViewProperties(c, view, mayShowCardFace(view));
|
||||
// Next, write the values that depend on other views.
|
||||
view.setOwner(getPlayerViewFast(c.getOwner()));
|
||||
view.setController(getPlayerViewFast(c.getController()));
|
||||
view.setAttacking(game.getCombat() != null && game.getCombat().isAttacking(c));
|
||||
view.setBlocking(game.getCombat() != null && game.getCombat().isBlocking(c));
|
||||
view.setChosenPlayer(getPlayerViewFast(c.getChosenPlayer()));
|
||||
view.setEquipping(getCardViewFast(Iterables.getFirst(c.getEquipping(), null)));
|
||||
view.setEquippedBy(getCardViewsFast(c.getEquippedBy()));
|
||||
view.setEnchantingCard(getCardViewFast(c.getEnchantingCard()));
|
||||
view.setEnchantingPlayer(getPlayerViewFast(c.getEnchantingPlayer()));
|
||||
view.setEnchantedBy(getCardViewsFast(c.getEnchantedBy()));
|
||||
view.setFortifiedBy(getCardViewsFast(c.getFortifiedBy()));
|
||||
view.setGainControlTargets(getCardViewsFast(c.getGainControlTargets()));
|
||||
view.setCloneOrigin(getCardViewFast(c.getCloneOrigin()));
|
||||
view.setImprinted(getCardViewsFast(c.getImprinted()));
|
||||
view.setHauntedBy(getCardViewsFast(c.getHauntedBy()));
|
||||
view.setHaunting(getCardViewFast(c.getHaunting()));
|
||||
view.setMustBlock(c.getMustBlockCards() == null ? Collections.<CardView>emptySet() : getCardViewsFast(c.getMustBlockCards()));
|
||||
view.setPairedWith(getCardViewFast(c.getPairedWith()));
|
||||
}
|
||||
|
||||
public SpellAbilityView getSpellAbilityView(final SpellAbility sa) {
|
||||
if (sa == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final SpellAbilityView view;
|
||||
if (spabs.containsKey(sa)) {
|
||||
view = spabs.get(sa);
|
||||
writeSpellAbilityToView(sa, view);
|
||||
} else {
|
||||
view = new SpellAbilityView();
|
||||
writeSpellAbilityToView(sa, view);
|
||||
spabs.put(sa, view);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private final Function<SpellAbility, SpellAbilityView> FN_GET_SPAB_VIEW = new Function<SpellAbility, SpellAbilityView>() {
|
||||
@Override
|
||||
public SpellAbilityView apply(final SpellAbility input) {
|
||||
return getSpellAbilityView(input);
|
||||
}
|
||||
};
|
||||
|
||||
public final List<SpellAbilityView> getSpellAbilityViews(final List<SpellAbility> cards) {
|
||||
return ViewUtil.transformIfNotNull(cards, FN_GET_SPAB_VIEW);
|
||||
}
|
||||
|
||||
public SpellAbility getSpellAbility(final SpellAbilityView c) {
|
||||
return spabs.getKey(c);
|
||||
}
|
||||
|
||||
private final Function<SpellAbilityView, SpellAbility> FN_GET_SPAB = new Function<SpellAbilityView, SpellAbility>() {
|
||||
@Override
|
||||
public SpellAbility apply(final SpellAbilityView input) {
|
||||
return getSpellAbility(input);
|
||||
}
|
||||
};
|
||||
|
||||
public final List<SpellAbility> getSpellAbilities(final List<SpellAbilityView> cards) {
|
||||
return ViewUtil.transformIfNotNull(cards, FN_GET_SPAB);
|
||||
}
|
||||
|
||||
private void writeSpellAbilityToView(final SpellAbility sa, final SpellAbilityView view) {
|
||||
view.setHostCard(getCardView(sa.getHostCard()));
|
||||
view.setDescription(sa.getDescription());
|
||||
view.setCanPlay(sa.canPlay());
|
||||
view.setPromptIfOnlyPossibleAbility(sa.promptIfOnlyPossibleAbility());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDisableAutoYields() {
|
||||
return this.game.getDisableAutoYields();
|
||||
}
|
||||
@Override
|
||||
public void setDisableAutoYields(final boolean b) {
|
||||
this.game.setDisableAutoYields(b);
|
||||
}
|
||||
|
||||
}
|
||||
375
forge-gui/src/main/java/forge/view/PlayerView.java
Normal file
375
forge-gui/src/main/java/forge/view/PlayerView.java
Normal file
@@ -0,0 +1,375 @@
|
||||
package forge.view;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public class PlayerView extends GameEntityView {
|
||||
|
||||
private final LobbyPlayer lobbyPlayer;
|
||||
private final int id;
|
||||
|
||||
private Set<PlayerView> opponents;
|
||||
private int life, poisonCounters, maxHandSize, numDrawnThisTurn, preventNextDamage;
|
||||
private List<String> keywords;
|
||||
private String commanderInfo;
|
||||
private List<CardView>
|
||||
anteCards = Lists.newArrayList(),
|
||||
bfCards = Lists.newArrayList(),
|
||||
commandCards = Lists.newArrayList(),
|
||||
exileCards = Lists.newArrayList(),
|
||||
flashbackCards = Lists.newArrayList(),
|
||||
graveCards = Lists.newArrayList(),
|
||||
handCards = Lists.newArrayList(),
|
||||
libraryCards = Lists.newArrayList();
|
||||
private int
|
||||
nHandCards,
|
||||
nLibraryCards;
|
||||
private boolean hasUnlimitedHandSize;
|
||||
private Map<Byte, Integer> mana = Maps.newHashMapWithExpectedSize(MagicColor.NUMBER_OR_COLORS + 1);
|
||||
|
||||
public PlayerView(final LobbyPlayer lobbyPlayer, final int id) {
|
||||
this.lobbyPlayer = lobbyPlayer;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lobbyPlayer
|
||||
*/
|
||||
public LobbyPlayer getLobbyPlayer() {
|
||||
return lobbyPlayer;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return obj instanceof PlayerView && this.getId() == ((PlayerView) obj).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setOpponents(final Iterable<PlayerView> opponents) {
|
||||
this.opponents = Sets.newHashSet(opponents);
|
||||
}
|
||||
|
||||
public boolean isOpponentOf(final PlayerView other) {
|
||||
return opponents.contains(other);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.getLobbyPlayer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the life
|
||||
*/
|
||||
public int getLife() {
|
||||
return life;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param life the life to set
|
||||
*/
|
||||
public void setLife(final int life) {
|
||||
this.life = life;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the poisonCounters
|
||||
*/
|
||||
public int getPoisonCounters() {
|
||||
return poisonCounters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param poisonCounters the poisonCounters to set
|
||||
*/
|
||||
public void setPoisonCounters(final int poisonCounters) {
|
||||
this.poisonCounters = poisonCounters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maxHandSize
|
||||
*/
|
||||
public int getMaxHandSize() {
|
||||
return maxHandSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param maxHandSize the maxHandSize to set
|
||||
*/
|
||||
public void setMaxHandSize(final int maxHandSize) {
|
||||
this.maxHandSize = maxHandSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the numDrawnThisTurn
|
||||
*/
|
||||
public int getNumDrawnThisTurn() {
|
||||
return numDrawnThisTurn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numDrawnThisTurn the numDrawnThisTurn to set
|
||||
*/
|
||||
public void setNumDrawnThisTurn(final int numDrawnThisTurn) {
|
||||
this.numDrawnThisTurn = numDrawnThisTurn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the preventNextDamage
|
||||
*/
|
||||
public int getPreventNextDamage() {
|
||||
return preventNextDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param preventNextDamage the preventNextDamage to set
|
||||
*/
|
||||
public void setPreventNextDamage(final int preventNextDamage) {
|
||||
this.preventNextDamage = preventNextDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the keywords
|
||||
*/
|
||||
public List<String> getKeywords() {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keywords the keywords to set
|
||||
*/
|
||||
public void setKeywords(final List<String> keywords) {
|
||||
this.keywords = ImmutableList.copyOf(keywords);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the commanderInfo
|
||||
*/
|
||||
public String getCommanderInfo() {
|
||||
return commanderInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param commanderInfo the commanderInfo to set
|
||||
*/
|
||||
public void setCommanderInfo(final String commanderInfo) {
|
||||
this.commanderInfo = commanderInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the anteCards
|
||||
*/
|
||||
public List<CardView> getAnteCards() {
|
||||
return anteCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param anteCards the anteCards to set
|
||||
*/
|
||||
public void setAnteCards(final List<CardView> anteCards) {
|
||||
this.anteCards = ImmutableList.copyOf(anteCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the bfCards
|
||||
*/
|
||||
public List<CardView> getBfCards() {
|
||||
return bfCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bfCards the bfCards to set
|
||||
*/
|
||||
public void setBfCards(final List<CardView> bfCards) {
|
||||
this.bfCards = ImmutableList.copyOf(bfCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the commandCards
|
||||
*/
|
||||
public List<CardView> getCommandCards() {
|
||||
return commandCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param commandCards the commandCards to set
|
||||
*/
|
||||
public void setCommandCards(List<CardView> commandCards) {
|
||||
this.commandCards = ImmutableList.copyOf(commandCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the exileCards
|
||||
*/
|
||||
public List<CardView> getExileCards() {
|
||||
return exileCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param exileCards the exileCards to set
|
||||
*/
|
||||
public void setExileCards(final List<CardView> exileCards) {
|
||||
this.exileCards = ImmutableList.copyOf(exileCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the flashbackCards
|
||||
*/
|
||||
public List<CardView> getFlashbackCards() {
|
||||
return flashbackCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param flashbackCards the flashbackCards to set
|
||||
*/
|
||||
public void setFlashbackCards(final List<CardView> flashbackCards) {
|
||||
this.flashbackCards = ImmutableList.copyOf(flashbackCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the graveCards
|
||||
*/
|
||||
public List<CardView> getGraveCards() {
|
||||
return graveCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param graveCards the graveCards to set
|
||||
*/
|
||||
public void setGraveCards(final List<CardView> graveCards) {
|
||||
this.graveCards = ImmutableList.copyOf(graveCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the handCards
|
||||
*/
|
||||
public List<CardView> getHandCards() {
|
||||
return handCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param handCards the handCards to set
|
||||
*/
|
||||
public void setHandCards(final List<CardView> handCards) {
|
||||
this.handCards = ImmutableList.copyOf(handCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the libraryCards
|
||||
*/
|
||||
public List<CardView> getLibraryCards() {
|
||||
return libraryCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param libraryCards the libraryCards to set
|
||||
*/
|
||||
public void setLibraryCards(final List<CardView> libraryCards) {
|
||||
this.libraryCards = ImmutableList.copyOf(libraryCards);
|
||||
}
|
||||
|
||||
public List<CardView> getCards(final ZoneType zone) {
|
||||
switch (zone) {
|
||||
case Ante:
|
||||
return getAnteCards();
|
||||
case Battlefield:
|
||||
return getBfCards();
|
||||
case Command:
|
||||
return getCommandCards();
|
||||
case Exile:
|
||||
return getExileCards();
|
||||
case Graveyard:
|
||||
return getGraveCards();
|
||||
case Hand:
|
||||
return getHandCards();
|
||||
case Library:
|
||||
return getLibraryCards();
|
||||
default:
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
||||
public int getNCards(final ZoneType zone) {
|
||||
switch (zone) {
|
||||
case Hand:
|
||||
return getnHandCards();
|
||||
case Library:
|
||||
return getnLibraryCards();
|
||||
default:
|
||||
return getCards(zone).size();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nHandCards
|
||||
*/
|
||||
public int getnHandCards() {
|
||||
return nHandCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nHandCards the nHandCards to set
|
||||
*/
|
||||
public void setnHandCards(int nHandCards) {
|
||||
this.nHandCards = nHandCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nLibraryCards
|
||||
*/
|
||||
public int getnLibraryCards() {
|
||||
return nLibraryCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nLibraryCards the nLibraryCards to set
|
||||
*/
|
||||
public void setnLibraryCards(int nLibraryCards) {
|
||||
this.nLibraryCards = nLibraryCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hasUnlimitedHandSize
|
||||
*/
|
||||
public boolean hasUnlimitedHandSize() {
|
||||
return hasUnlimitedHandSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hasUnlimitedHandSize the hasUnlimitedHandSize to set
|
||||
*/
|
||||
public void setHasUnlimitedHandSize(final boolean hasUnlimitedHandSize) {
|
||||
this.hasUnlimitedHandSize = hasUnlimitedHandSize;
|
||||
}
|
||||
|
||||
public int getMana(final Byte color) {
|
||||
return this.mana.containsKey(color) ? this.mana.get(color).intValue() : 0;
|
||||
}
|
||||
|
||||
public void setMana(final byte color, final int mana) {
|
||||
this.mana.put(Byte.valueOf(color), Integer.valueOf(mana));
|
||||
}
|
||||
|
||||
}
|
||||
70
forge-gui/src/main/java/forge/view/SpellAbilityView.java
Normal file
70
forge-gui/src/main/java/forge/view/SpellAbilityView.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package forge.view;
|
||||
|
||||
public class SpellAbilityView {
|
||||
|
||||
private CardView hostCard;
|
||||
private String description;
|
||||
private boolean canPlay, promptIfOnlyPossibleAbility;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hostCard
|
||||
*/
|
||||
public CardView getHostCard() {
|
||||
return hostCard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hostCard the hostCard to set
|
||||
*/
|
||||
public void setHostCard(CardView hostCard) {
|
||||
this.hostCard = hostCard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param description the description to set
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the canPlay
|
||||
*/
|
||||
public boolean canPlay() {
|
||||
return canPlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param canPlay the canPlay to set
|
||||
*/
|
||||
public void setCanPlay(boolean canPlay) {
|
||||
this.canPlay = canPlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the promptIfOnlyPossibleAbility
|
||||
*/
|
||||
public boolean isPromptIfOnlyPossibleAbility() {
|
||||
return promptIfOnlyPossibleAbility;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param promptIfOnlyPossibleAbility the promptIfOnlyPossibleAbility to set
|
||||
*/
|
||||
public void setPromptIfOnlyPossibleAbility(boolean promptIfOnlyPossibleAbility) {
|
||||
this.promptIfOnlyPossibleAbility = promptIfOnlyPossibleAbility;
|
||||
}
|
||||
|
||||
}
|
||||
71
forge-gui/src/main/java/forge/view/StackItemView.java
Normal file
71
forge-gui/src/main/java/forge/view/StackItemView.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package forge.view;
|
||||
|
||||
public class StackItemView {
|
||||
|
||||
private final String key;
|
||||
private final int sourceTrigger;
|
||||
private final String text;
|
||||
private final CardView source;
|
||||
private final PlayerView activatingPlayer;
|
||||
private final Iterable<CardView> targetCards;
|
||||
private final Iterable<PlayerView> targetPlayers;
|
||||
private final boolean ability, optionalTrigger;
|
||||
|
||||
public StackItemView(final String key, final int sourceTrigger,
|
||||
final String text, final CardView source,
|
||||
final PlayerView activatingPlayer,
|
||||
final Iterable<CardView> targetCards,
|
||||
final Iterable<PlayerView> targetPlayers, final boolean isAbility,
|
||||
final boolean isOptionalTrigger) {
|
||||
this.key = key;
|
||||
this.sourceTrigger = sourceTrigger;
|
||||
this.text = text;
|
||||
this.source = source;
|
||||
this.activatingPlayer = activatingPlayer;
|
||||
this.targetCards = targetCards;
|
||||
this.targetPlayers = targetPlayers;
|
||||
this.ability = isAbility;
|
||||
this.optionalTrigger = isOptionalTrigger;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public int getSourceTrigger() {
|
||||
return sourceTrigger;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public CardView getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public PlayerView getActivatingPlayer() {
|
||||
return activatingPlayer;
|
||||
}
|
||||
|
||||
public Iterable<CardView> getTargetCards() {
|
||||
return targetCards;
|
||||
}
|
||||
|
||||
public Iterable<PlayerView> getTargetPlayers() {
|
||||
return targetPlayers;
|
||||
}
|
||||
|
||||
public boolean isAbility() {
|
||||
return ability;
|
||||
}
|
||||
|
||||
public boolean isOptionalTrigger() {
|
||||
return optionalTrigger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getText();
|
||||
}
|
||||
}
|
||||
141
forge-gui/src/main/java/forge/view/ViewUtil.java
Normal file
141
forge-gui/src/main/java/forge/view/ViewUtil.java
Normal file
@@ -0,0 +1,141 @@
|
||||
package forge.view;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCharacteristics;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.view.CardView.CardStateView;
|
||||
|
||||
public final class ViewUtil {
|
||||
|
||||
private ViewUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Write those properties of a {@link Card} to a {@link CardView} that do
|
||||
* <i>not</i> depend on other cards.
|
||||
*
|
||||
* @param c
|
||||
* the {@link Card} to read from.
|
||||
* @param view
|
||||
* the {@link CardView} to write to.
|
||||
*/
|
||||
public static void writeNonDependentCardViewProperties(final Card c, final CardView view, final boolean mayShowCardFace) {
|
||||
final boolean hasAltState = c.isDoubleFaced() || c.isFlipCard() || c.isSplitCard() || (c.isFaceDown() && mayShowCardFace);
|
||||
view.setId(c.getUniqueNumber());
|
||||
view.setZone(c.getZone() == null ? null : c.getZone().getZoneType());
|
||||
view.setHasAltState(hasAltState);
|
||||
view.setFaceDown(c.isFaceDown());
|
||||
view.setFoilIndex(c.getFoil());
|
||||
view.setCloned(c.isCloned());
|
||||
view.setFlipCard(c.isFlipCard());
|
||||
view.setFlipped(c.getCurState().equals(CardCharacteristicName.Flipped));
|
||||
view.setSplitCard(c.isSplitCard());
|
||||
view.setTransformed(c.getCurState().equals(CardCharacteristicName.Transformed));
|
||||
view.setSetCode(c.getCurSetCode());
|
||||
view.setRarity(c.getRarity());
|
||||
view.setTimestamp(c.getTimestamp());
|
||||
view.setPhasedOut(c.isPhasedOut());
|
||||
view.setSick(c.isInPlay() && c.isSick());
|
||||
view.setTapped(c.isTapped());
|
||||
view.setToken(c.isToken());
|
||||
view.setCounters(c.getCounters());
|
||||
view.setDamage(c.getDamage());
|
||||
view.setAssignedDamage(c.getTotalAssignedDamage());
|
||||
view.setRegenerationShields(c.getShield().size());
|
||||
view.setPreventNextDamage(c.getPreventNextDamageTotalShields());
|
||||
view.setChosenType(c.getChosenType());
|
||||
view.setChosenColors(c.getChosenColor());
|
||||
view.setNamedCard(c.getNamedCard());
|
||||
|
||||
if (c.isSplitCard()) {
|
||||
final CardCharacteristicName orig, alt;
|
||||
if (c.getCurState() == CardCharacteristicName.RightSplit) {
|
||||
// If right half on stack, place it first
|
||||
orig = CardCharacteristicName.RightSplit;
|
||||
alt = CardCharacteristicName.LeftSplit;
|
||||
} else {
|
||||
orig = CardCharacteristicName.LeftSplit;
|
||||
alt = CardCharacteristicName.RightSplit;
|
||||
}
|
||||
writeCardStateViewProperties(c, view.getOriginal(), orig);
|
||||
writeCardStateViewProperties(c, view.getAlternate(), alt);
|
||||
return;
|
||||
}
|
||||
|
||||
final CardStateView origView = view.getOriginal();
|
||||
origView.setName(c.getName());
|
||||
origView.setColors(c.determineColor());
|
||||
origView.setImageKey(c.getImageKey() );
|
||||
origView.setType(Collections.unmodifiableList(c.getType()));
|
||||
origView.setManaCost(c.getManaCost());
|
||||
origView.setPower(c.getNetAttack());
|
||||
origView.setToughness(c.getNetDefense());
|
||||
origView.setLoyalty(c.getCurrentLoyalty());
|
||||
origView.setText(c.getText());
|
||||
origView.setChangedColorWords(c.getChangedTextColorWords());
|
||||
origView.setChangedTypes(c.getChangedTextTypeWords());
|
||||
origView.setManaCost(c.getManaCost());
|
||||
origView.setHasDeathtouch(c.hasKeyword("Deathtouch"));
|
||||
origView.setHasInfect(c.hasKeyword("Infect"));
|
||||
origView.setHasStorm(c.hasKeyword("Storm"));
|
||||
origView.setHasTrample(c.hasKeyword("Trample"));
|
||||
|
||||
final CardStateView altView = view.getAlternate();
|
||||
CardCharacteristicName altState = null;
|
||||
if (hasAltState) {
|
||||
if (c.isFlipCard() && !c.getCurState().equals(CardCharacteristicName.Flipped)) {
|
||||
altState = CardCharacteristicName.Flipped;
|
||||
} else if (c.isDoubleFaced() && !c.getCurState().equals(CardCharacteristicName.Transformed)) {
|
||||
altState = CardCharacteristicName.Transformed;
|
||||
} else {
|
||||
altState = CardCharacteristicName.Original;
|
||||
}
|
||||
|
||||
if (altState != null) {
|
||||
writeCardStateViewProperties(c, altView, altState);
|
||||
}
|
||||
}
|
||||
|
||||
if (altState == null) {
|
||||
altView.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeCardStateViewProperties(final Card c, final CardStateView view, final CardCharacteristicName state) {
|
||||
final CardCharacteristics chars = c.getState(state);
|
||||
view.setName(chars.getName());
|
||||
view.setColors(chars.determineColor());
|
||||
view.setImageKey(chars.getImageKey());
|
||||
view.setType(Collections.unmodifiableList(chars.getType()));
|
||||
view.setManaCost(chars.getManaCost());
|
||||
view.setPower(chars.getBaseAttack());
|
||||
view.setToughness(chars.getBaseDefense());
|
||||
view.setLoyalty(0); // FIXME why is loyalty not a property of CardCharacteristic?
|
||||
view.setText(chars.getOracleText());
|
||||
}
|
||||
|
||||
public static CardView getCardForUi(final IPaperCard pc) {
|
||||
final Card c = Card.getCardForUi(pc);
|
||||
final CardView view = new CardView(true);
|
||||
writeNonDependentCardViewProperties(c, view, c.getCardForUi() == c);
|
||||
return view;
|
||||
}
|
||||
|
||||
public static <T,V> List<V> transformIfNotNull(final Iterable<T> input, final Function<T, V> transformation) {
|
||||
final List<V> ret = Lists.newLinkedList();
|
||||
for (final T t : input) {
|
||||
final V v = transformation.apply(t);
|
||||
if (v != null) {
|
||||
ret.add(v);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
179
forge-gui/src/main/java/forge/view/WatchLocalGame.java
Normal file
179
forge-gui/src/main/java/forge/view/WatchLocalGame.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package forge.view;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.match.input.Input;
|
||||
import forge.match.input.InputPlaybackControl;
|
||||
import forge.match.input.InputQueue;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
/**
|
||||
* @author lennaert
|
||||
*
|
||||
*/
|
||||
public class WatchLocalGame extends LocalGameView {
|
||||
|
||||
private final InputQueue inputQueue;
|
||||
/**
|
||||
* @param game
|
||||
* @param inputQueue
|
||||
*/
|
||||
public WatchLocalGame(final Game game, final InputQueue inputQueue) {
|
||||
super(game);
|
||||
this.inputQueue = inputQueue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAchievements() {
|
||||
}
|
||||
|
||||
public boolean canUndoLastAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryUndoLastAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectButtonOk() {
|
||||
final Input i = inputQueue.getInput();
|
||||
if (i instanceof InputPlaybackControl) {
|
||||
i.selectButtonOK();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectButtonCancel() {
|
||||
final Input i = inputQueue.getInput();
|
||||
if (i instanceof InputPlaybackControl) {
|
||||
i.selectButtonCancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void confirm() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passPriority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passPriorityUntilEndOfTurn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useMana(final byte mana) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectCard(final CardView card, final ITriggerEvent triggerEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectAbility(final SpellAbilityView sa) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alphaStrike() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayShowCard(final CardView c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayShowCardFace(final CardView c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Dev mode functions
|
||||
@Override
|
||||
public void devTogglePlayManyLands(final boolean b) {
|
||||
}
|
||||
@Override
|
||||
public void devGenerateMana() {
|
||||
}
|
||||
@Override
|
||||
public void devSetupGameState() {
|
||||
}
|
||||
@Override
|
||||
public void devTutorForCard() {
|
||||
}
|
||||
@Override
|
||||
public void devAddCardToHand() {
|
||||
}
|
||||
@Override
|
||||
public void devAddCounterToPermanent() {
|
||||
}
|
||||
@Override
|
||||
public void devTapPermanent() {
|
||||
}
|
||||
@Override
|
||||
public void devUntapPermanent() {
|
||||
}
|
||||
@Override
|
||||
public void devSetPlayerLife() {
|
||||
}
|
||||
@Override
|
||||
public void devWinGame() {
|
||||
}
|
||||
@Override
|
||||
public void devAddCardToBattlefield() {
|
||||
}
|
||||
@Override
|
||||
public void devRiggedPlanerRoll() {
|
||||
}
|
||||
@Override
|
||||
public void devPlaneswalkTo() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getAutoYields() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean shouldAutoYield(final String key) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void setShouldAutoYield(final String key, final boolean autoYield) {
|
||||
}
|
||||
@Override
|
||||
public boolean shouldAlwaysAcceptTrigger(final Integer trigger) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean shouldAlwaysDeclineTrigger(final Integer trigger) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean shouldAlwaysAskTrigger(final Integer trigger) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void setShouldAlwaysAcceptTrigger(final Integer trigger) {
|
||||
}
|
||||
@Override
|
||||
public void setShouldAlwaysDeclineTrigger(final Integer trigger) {
|
||||
}
|
||||
@Override
|
||||
public void setShouldAlwaysAskTrigger(final Integer trigger) {
|
||||
}
|
||||
@Override
|
||||
public void autoPassCancel() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user