mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Add "Auto" button for automatically paying a mana cost
Code cleanup
This commit is contained in:
@@ -12,8 +12,8 @@ import forge.util.ThreadUtil;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FThreads {
|
public class FThreads {
|
||||||
|
|
||||||
private FThreads() { } // no instances supposed
|
private FThreads() { } // no instances supposed
|
||||||
|
|
||||||
/** Checks if calling method uses event dispatch thread.
|
/** Checks if calling method uses event dispatch thread.
|
||||||
* Exception thrown if method is on "wrong" thread.
|
* Exception thrown if method is on "wrong" thread.
|
||||||
* A boolean is passed to indicate if the method must be EDT or not.
|
* A boolean is passed to indicate if the method must be EDT or not.
|
||||||
@@ -22,11 +22,11 @@ public class FThreads {
|
|||||||
* @param mustBeEDT   boolean: true = exception if not EDT, false = exception if EDT
|
* @param mustBeEDT   boolean: true = exception if not EDT, false = exception if EDT
|
||||||
*/
|
*/
|
||||||
public static void assertExecutedByEdt(final boolean mustBeEDT) {
|
public static void assertExecutedByEdt(final boolean mustBeEDT) {
|
||||||
if (isGuiThread() != mustBeEDT ) {
|
if (isGuiThread() != mustBeEDT) {
|
||||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||||
final String methodName = trace[2].getClassName() + "." + trace[2].getMethodName();
|
final String methodName = trace[2].getClassName() + "." + trace[2].getMethodName();
|
||||||
String modalOperator = mustBeEDT ? " must be" : " may not be";
|
String modalOperator = mustBeEDT ? " must be" : " may not be";
|
||||||
throw new IllegalStateException( methodName + modalOperator + " accessed from the event dispatch thread.");
|
throw new IllegalStateException(methodName + modalOperator + " accessed from the event dispatch thread.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +42,12 @@ public class FThreads {
|
|||||||
* TODO: Write javadoc for this method.
|
* TODO: Write javadoc for this method.
|
||||||
*/
|
*/
|
||||||
public static void invokeInEdtNowOrLater(Runnable proc) {
|
public static void invokeInEdtNowOrLater(Runnable proc) {
|
||||||
if( isGuiThread() )
|
if (isGuiThread()) {
|
||||||
proc.run();
|
proc.run();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
invokeInEdtLater(proc);
|
invokeInEdtLater(proc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,20 +66,20 @@ public class FThreads {
|
|||||||
if (SwingUtilities.isEventDispatchThread()) {
|
if (SwingUtilities.isEventDispatchThread()) {
|
||||||
// Just run in the current thread.
|
// Just run in the current thread.
|
||||||
proc.run();
|
proc.run();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
try {
|
try {
|
||||||
SwingUtilities.invokeAndWait(proc);
|
SwingUtilities.invokeAndWait(proc);
|
||||||
} catch (final InterruptedException exn) {
|
}
|
||||||
|
catch (final InterruptedException exn) {
|
||||||
throw new RuntimeException(exn);
|
throw new RuntimeException(exn);
|
||||||
} catch (final InvocationTargetException exn) {
|
}
|
||||||
|
catch (final InvocationTargetException exn) {
|
||||||
throw new RuntimeException(exn);
|
throw new RuntimeException(exn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this method.
|
* TODO: Write javadoc for this method.
|
||||||
* @return
|
* @return
|
||||||
@@ -86,16 +88,16 @@ public class FThreads {
|
|||||||
return SwingUtilities.isEventDispatchThread();
|
return SwingUtilities.isEventDispatchThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void delayInEDT(int milliseconds, final Runnable inputUpdater) {
|
public static void delayInEDT(int milliseconds, final Runnable inputUpdater) {
|
||||||
Runnable runInEdt = new Runnable() {
|
Runnable runInEdt = new Runnable() {
|
||||||
@Override public void run() {
|
@Override
|
||||||
|
public void run() {
|
||||||
FThreads.invokeInEdtNowOrLater(inputUpdater);
|
FThreads.invokeInEdtNowOrLater(inputUpdater);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ThreadUtil.delay(milliseconds, runInEdt);
|
ThreadUtil.delay(milliseconds, runInEdt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String debugGetCurrThreadId() {
|
public static String debugGetCurrThreadId() {
|
||||||
return isGuiThread() ? "EDT" : Thread.currentThread().getName();
|
return isGuiThread() ? "EDT" : Thread.currentThread().getName();
|
||||||
}
|
}
|
||||||
@@ -103,28 +105,30 @@ public class FThreads {
|
|||||||
public static String prependThreadId(String message) {
|
public static String prependThreadId(String message) {
|
||||||
return debugGetCurrThreadId() + " > " + message;
|
return debugGetCurrThreadId() + " > " + message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dumpStackTrace(PrintStream stream) {
|
public static void dumpStackTrace(PrintStream stream) {
|
||||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||||
stream.printf("%s > %s called from %s%n", debugGetCurrThreadId(), trace[2].getClassName()+"."+trace[2].getMethodName(), trace[3].toString());
|
stream.printf("%s > %s called from %s%n", debugGetCurrThreadId(),
|
||||||
int i = 0;
|
trace[2].getClassName() + "." + trace[2].getMethodName(), trace[3].toString());
|
||||||
for(StackTraceElement se : trace) {
|
int i = 0;
|
||||||
if(i<2) i++;
|
for (StackTraceElement se : trace) {
|
||||||
else stream.println(se.toString());
|
if (i<2) { i++; }
|
||||||
}
|
else { stream.println(se.toString()); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String debugGetStackTraceItem(int depth, boolean shorter) {
|
public static String debugGetStackTraceItem(int depth, boolean shorter) {
|
||||||
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
|
||||||
String lastItem = trace[depth].toString();
|
String lastItem = trace[depth].toString();
|
||||||
if( shorter ) {
|
if (shorter) {
|
||||||
int lastPeriod = lastItem.lastIndexOf('.');
|
int lastPeriod = lastItem.lastIndexOf('.');
|
||||||
lastPeriod = lastItem.lastIndexOf('.', lastPeriod-1);
|
lastPeriod = lastItem.lastIndexOf('.', lastPeriod-1);
|
||||||
lastPeriod = lastItem.lastIndexOf('.', lastPeriod-1);
|
lastPeriod = lastItem.lastIndexOf('.', lastPeriod-1);
|
||||||
lastItem = lastItem.substring(lastPeriod+1);
|
lastItem = lastItem.substring(lastPeriod+1);
|
||||||
return String.format("%s > from %s", debugGetCurrThreadId(), lastItem);
|
return String.format("%s > from %s", debugGetCurrThreadId(), lastItem);
|
||||||
}
|
}
|
||||||
return String.format("%s > %s called from %s", debugGetCurrThreadId(), trace[2].getClassName()+"."+trace[2].getMethodName(), lastItem);
|
return String.format("%s > %s called from %s", debugGetCurrThreadId(),
|
||||||
|
trace[2].getClassName() + "." + trace[2].getMethodName(), lastItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String debugGetStackTraceItem(int depth) {
|
public static String debugGetStackTraceItem(int depth) {
|
||||||
|
|||||||
@@ -47,9 +47,17 @@ import forge.util.maps.MapOfLists;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ComputerUtilMana {
|
public class ComputerUtilMana {
|
||||||
|
|
||||||
private final static boolean DEBUG_MANA_PAYMENT = false;
|
private final static boolean DEBUG_MANA_PAYMENT = false;
|
||||||
|
|
||||||
|
public static boolean canPayManaCost(ManaCostBeingPaid cost, final SpellAbility sa, final Player ai) {
|
||||||
|
cost = new ManaCostBeingPaid(cost); //check copy of cost so it doesn't modify the exist cost being paid
|
||||||
|
return payManaCost(cost, sa, ai, true, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean payManaCost(ManaCostBeingPaid cost, final SpellAbility sa, final Player ai) {
|
||||||
|
return payManaCost(cost, sa, ai, false, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean canPayManaCost(final SpellAbility sa, final Player ai, final int extraMana) {
|
public static boolean canPayManaCost(final SpellAbility sa, final Player ai, final int extraMana) {
|
||||||
return payManaCost(sa, ai, true, extraMana, true);
|
return payManaCost(sa, ai, true, extraMana, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import forge.util.maps.MapToAmount;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* ManaCost class.
|
* ManaCostBeingPaid class.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Forge
|
* @author Forge
|
||||||
@@ -62,45 +62,49 @@ public class ManaCostBeingPaid {
|
|||||||
private ManaCostShard nextShard = null;
|
private ManaCostShard nextShard = null;
|
||||||
private int remainingShards = 0;
|
private int remainingShards = 0;
|
||||||
private boolean hasSentX = false;
|
private boolean hasSentX = false;
|
||||||
|
|
||||||
public ManaCostBeingPaidIterator() {
|
public ManaCostBeingPaidIterator() {
|
||||||
mch = unpaidShards.keySet().iterator();
|
mch = unpaidShards.keySet().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove() {
|
public void remove() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ManaCostShard next() {
|
public ManaCostShard next() {
|
||||||
if (remainingShards == 0)
|
if (remainingShards == 0) {
|
||||||
throw new UnsupportedOperationException("All shards were depleted, call hasNext()");
|
throw new UnsupportedOperationException("All shards were depleted, call hasNext()");
|
||||||
|
}
|
||||||
remainingShards--;
|
remainingShards--;
|
||||||
return nextShard;
|
return nextShard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
if ( remainingShards > 0 ) return true;
|
if (remainingShards > 0) { return true; }
|
||||||
if ( !hasSentX ) {
|
if (!hasSentX) {
|
||||||
if ( nextShard != ManaCostShard.X && cntX > 0) {
|
if (nextShard != ManaCostShard.X && cntX > 0) {
|
||||||
nextShard = ManaCostShard.X;
|
nextShard = ManaCostShard.X;
|
||||||
remainingShards = cntX;
|
remainingShards = cntX;
|
||||||
return true;
|
return true;
|
||||||
} else
|
}
|
||||||
|
else {
|
||||||
hasSentX = true;
|
hasSentX = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( !mch.hasNext() ) return false;
|
if (!mch.hasNext()) { return false; }
|
||||||
|
|
||||||
nextShard = mch.next();
|
nextShard = mch.next();
|
||||||
if ( nextShard == ManaCostShard.COLORLESS )
|
if (nextShard == ManaCostShard.COLORLESS) {
|
||||||
return this.hasNext(); // skip colorless
|
return this.hasNext(); // skip colorless
|
||||||
|
}
|
||||||
remainingShards = unpaidShards.get(nextShard);
|
remainingShards = unpaidShards.get(nextShard);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTotalColorlessCost() {
|
public int getTotalColorlessCost() {
|
||||||
Integer c = unpaidShards.get(ManaCostShard.COLORLESS);
|
Integer c = unpaidShards.get(ManaCostShard.COLORLESS);
|
||||||
@@ -110,15 +114,25 @@ public class ManaCostBeingPaid {
|
|||||||
|
|
||||||
// holds Mana_Part objects
|
// holds Mana_Part objects
|
||||||
// ManaPartColor is stored before ManaPartColorless
|
// ManaPartColor is stored before ManaPartColorless
|
||||||
private final MapToAmount<ManaCostShard> unpaidShards = new EnumMapToAmount<ManaCostShard>(ManaCostShard.class);
|
private final MapToAmount<ManaCostShard> unpaidShards;
|
||||||
|
private final String sourceRestriction;
|
||||||
private byte sunburstMap = 0;
|
private byte sunburstMap = 0;
|
||||||
private int cntX = 0;
|
private int cntX = 0;
|
||||||
private final String sourceRestriction;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param manaCostBeingPaid
|
||||||
|
*/
|
||||||
|
public ManaCostBeingPaid(ManaCostBeingPaid manaCostBeingPaid) {
|
||||||
|
unpaidShards = new EnumMapToAmount<ManaCostShard>(manaCostBeingPaid.unpaidShards);
|
||||||
|
sourceRestriction = manaCostBeingPaid.sourceRestriction;
|
||||||
|
sunburstMap = manaCostBeingPaid.sunburstMap;
|
||||||
|
cntX = manaCostBeingPaid.cntX;
|
||||||
|
}
|
||||||
|
|
||||||
// manaCost can be like "0", "3", "G", "GW", "10", "3 GW", "10 GW"
|
// manaCost can be like "0", "3", "G", "GW", "10", "3 GW", "10 GW"
|
||||||
// or "split hybrid mana" like "2/G 2/G", "2/B 2/B 2/B"
|
// or "split hybrid mana" like "2/G 2/G", "2/B 2/B 2/B"
|
||||||
// "GW" can be paid with either G or W
|
// "GW" can be paid with either G or W
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Constructor for ManaCost.
|
* Constructor for ManaCost.
|
||||||
@@ -134,9 +148,11 @@ public class ManaCostBeingPaid {
|
|||||||
public ManaCostBeingPaid(ManaCost manaCost) {
|
public ManaCostBeingPaid(ManaCost manaCost) {
|
||||||
this(manaCost, null);
|
this(manaCost, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManaCostBeingPaid(ManaCost manaCost, String srcRestriction) {
|
public ManaCostBeingPaid(ManaCost manaCost, String srcRestriction) {
|
||||||
|
unpaidShards = new EnumMapToAmount<ManaCostShard>(ManaCostShard.class);
|
||||||
sourceRestriction = srcRestriction;
|
sourceRestriction = srcRestriction;
|
||||||
if( manaCost == null ) return;
|
if (manaCost == null) { return; }
|
||||||
for (ManaCostShard shard : manaCost.getShards()) {
|
for (ManaCostShard shard : manaCost.getShards()) {
|
||||||
if (shard == ManaCostShard.X) {
|
if (shard == ManaCostShard.X) {
|
||||||
cntX++;
|
cntX++;
|
||||||
@@ -163,7 +179,6 @@ public class ManaCostBeingPaid {
|
|||||||
return sunburstMap;
|
return sunburstMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final boolean containsPhyrexianMana() {
|
public final boolean containsPhyrexianMana() {
|
||||||
for (ManaCostShard shard : unpaidShards.keySet()) {
|
for (ManaCostShard shard : unpaidShards.keySet()) {
|
||||||
if (shard.isPhyrexian()) {
|
if (shard.isPhyrexian()) {
|
||||||
@@ -175,32 +190,36 @@ public class ManaCostBeingPaid {
|
|||||||
|
|
||||||
public final boolean payPhyrexian() {
|
public final boolean payPhyrexian() {
|
||||||
ManaCostShard phy = null;
|
ManaCostShard phy = null;
|
||||||
for(ManaCostShard mcs : unpaidShards.keySet()) {
|
for (ManaCostShard mcs : unpaidShards.keySet()) {
|
||||||
if( mcs.isPhyrexian() ) {
|
if (mcs.isPhyrexian()) {
|
||||||
phy = mcs;
|
phy = mcs;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phy == null )
|
if (phy == null) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
decreaseShard(phy, 1);
|
decreaseShard(phy, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// takes a Short Color and returns true if it exists in the mana cost.
|
// takes a Short Color and returns true if it exists in the mana cost.
|
||||||
// Easier for split costs
|
// Easier for split costs
|
||||||
public final boolean needsColor(final byte colorMask) {
|
public final boolean needsColor(final byte colorMask) {
|
||||||
for (ManaCostShard shard : unpaidShards.keySet()) {
|
for (ManaCostShard shard : unpaidShards.keySet()) {
|
||||||
if (shard == ManaCostShard.COLORLESS)
|
if (shard == ManaCostShard.COLORLESS) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (shard.isOr2Colorless()) {
|
if (shard.isOr2Colorless()) {
|
||||||
if ((shard.getColorMask() & colorMask) != 0 )
|
if ((shard.getColorMask() & colorMask) != 0) {
|
||||||
return true;
|
return true;
|
||||||
} else if (shard.canBePaidWithManaOfColor(colorMask))
|
}
|
||||||
|
}
|
||||||
|
else if (shard.canBePaidWithManaOfColor(colorMask)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -224,10 +243,9 @@ public class ManaCostBeingPaid {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final boolean isPaid() {
|
public final boolean isPaid() {
|
||||||
return unpaidShards.isEmpty();
|
return unpaidShards.isEmpty();
|
||||||
} // isPaid()
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -242,18 +260,20 @@ public class ManaCostBeingPaid {
|
|||||||
List<String> unused = new ArrayList<String>(4);
|
List<String> unused = new ArrayList<String>(4);
|
||||||
for (String manaPart : TextUtil.split(mana, ' ')) {
|
for (String manaPart : TextUtil.split(mana, ' ')) {
|
||||||
if (StringUtils.isNumeric(manaPart)) {
|
if (StringUtils.isNumeric(manaPart)) {
|
||||||
for(int i = Integer.parseInt(manaPart); i > 0; i--) {
|
for (int i = Integer.parseInt(manaPart); i > 0; i--) {
|
||||||
boolean wasNeeded = this.payMana("1");
|
boolean wasNeeded = this.payMana("1");
|
||||||
if(!wasNeeded) {
|
if (!wasNeeded) {
|
||||||
unused.add(Integer.toString(i));
|
unused.add(Integer.toString(i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
String color = MagicColor.toShortString(manaPart);
|
String color = MagicColor.toShortString(manaPart);
|
||||||
boolean wasNeeded = this.payMana(color);
|
boolean wasNeeded = this.payMana(color);
|
||||||
if(!wasNeeded)
|
if (!wasNeeded) {
|
||||||
unused.add(color);
|
unused.add(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unused.isEmpty() ? null : StringUtils.join(unused, ' ');
|
return unused.isEmpty() ? null : StringUtils.join(unused, ' ');
|
||||||
@@ -305,7 +325,8 @@ public class ManaCostBeingPaid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Predicate<ManaCostShard> predCanBePaid = new Predicate<ManaCostShard>() {
|
Predicate<ManaCostShard> predCanBePaid = new Predicate<ManaCostShard>() {
|
||||||
@Override public boolean apply(ManaCostShard ms) {
|
@Override
|
||||||
|
public boolean apply(ManaCostShard ms) {
|
||||||
return ms.canBePaidWithManaOfColor(colorMask);
|
return ms.canBePaidWithManaOfColor(colorMask);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -328,11 +349,12 @@ public class ManaCostBeingPaid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Predicate<ManaCostShard> predCanBePaid = new Predicate<ManaCostShard>() {
|
Predicate<ManaCostShard> predCanBePaid = new Predicate<ManaCostShard>() {
|
||||||
@Override public boolean apply(ManaCostShard ms) {
|
@Override
|
||||||
|
public boolean apply(ManaCostShard ms) {
|
||||||
return canBePaidWith(ms, mana);
|
return canBePaidWith(ms, mana);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return tryPayMana(mana.getColorCode(), Iterables.filter(unpaidShards.keySet(), predCanBePaid));
|
return tryPayMana(mana.getColorCode(), Iterables.filter(unpaidShards.keySet(), predCanBePaid));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,12 +373,12 @@ public class ManaCostBeingPaid {
|
|||||||
if (choice == null) {
|
if (choice == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
decreaseShard(choice, 1);
|
decreaseShard(choice, 1);
|
||||||
if (choice.isOr2Colorless() && choice.getColorMask() != colorMask ) {
|
if (choice.isOr2Colorless() && choice.getColorMask() != colorMask) {
|
||||||
this.increaseColorlessMana(1);
|
this.increaseColorlessMana(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sunburstMap |= colorMask;
|
this.sunburstMap |= colorMask;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -386,7 +408,7 @@ public class ManaCostBeingPaid {
|
|||||||
if (shard.isSnow() && !mana.isSnow()) {
|
if (shard.isSnow() && !mana.isSnow()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte color = mana.getColorCode();
|
byte color = mana.getColorCode();
|
||||||
return shard.canBePaidWithManaOfColor(color);
|
return shard.canBePaidWithManaOfColor(color);
|
||||||
}
|
}
|
||||||
@@ -395,7 +417,8 @@ public class ManaCostBeingPaid {
|
|||||||
for (ManaCostShard shard : extra.getShards()) {
|
for (ManaCostShard shard : extra.getShards()) {
|
||||||
if (shard == ManaCostShard.X) {
|
if (shard == ManaCostShard.X) {
|
||||||
cntX++;
|
cntX++;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
increaseShard(shard, 1);
|
increaseShard(shard, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,9 +429,11 @@ public class ManaCostBeingPaid {
|
|||||||
for (ManaCostShard shard : subThisManaCost.getShards()) {
|
for (ManaCostShard shard : subThisManaCost.getShards()) {
|
||||||
if (shard == ManaCostShard.X) {
|
if (shard == ManaCostShard.X) {
|
||||||
cntX--;
|
cntX--;
|
||||||
} else if (unpaidShards.containsKey(shard)) {
|
}
|
||||||
|
else if (unpaidShards.containsKey(shard)) {
|
||||||
decreaseShard(shard, 1);
|
decreaseShard(shard, 1);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
decreaseColorlessMana(1);
|
decreaseColorlessMana(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -484,7 +509,7 @@ public class ManaCostBeingPaid {
|
|||||||
}
|
}
|
||||||
return cmc;
|
return cmc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManaCost toManaCost() {
|
public ManaCost toManaCost() {
|
||||||
return new ManaCost(new ManaCostBeingPaidIterator());
|
return new ManaCost(new ManaCostBeingPaidIterator());
|
||||||
}
|
}
|
||||||
@@ -493,20 +518,19 @@ public class ManaCostBeingPaid {
|
|||||||
return cntX;
|
return cntX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final List<ManaCostShard> getUnpaidShards() {
|
||||||
public final List<ManaCostShard> getUnpaidShards() {
|
|
||||||
List<ManaCostShard> result = new ArrayList<ManaCostShard>();
|
List<ManaCostShard> result = new ArrayList<ManaCostShard>();
|
||||||
for(Entry<ManaCostShard, Integer> kv : unpaidShards.entrySet()) {
|
for (Entry<ManaCostShard, Integer> kv : unpaidShards.entrySet()) {
|
||||||
for(int i = kv.getValue().intValue(); i > 0; i--) {
|
for (int i = kv.getValue().intValue(); i > 0; i--) {
|
||||||
result.add(kv.getKey());
|
result.add(kv.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int i = cntX; i > 0; i--) {
|
for (int i = cntX; i > 0; i--) {
|
||||||
result.add(ManaCostShard.X);
|
result.add(ManaCostShard.X);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* removeColorlessMana.
|
* removeColorlessMana.
|
||||||
@@ -524,7 +548,6 @@ public class ManaCostBeingPaid {
|
|||||||
final Card originalCard = sa.getSourceCard();
|
final Card originalCard = sa.getSourceCard();
|
||||||
final SpellAbility spell = sa;
|
final SpellAbility spell = sa;
|
||||||
|
|
||||||
|
|
||||||
if (sa.isXCost() && !originalCard.isCopiedSpell()) {
|
if (sa.isXCost() && !originalCard.isCopiedSpell()) {
|
||||||
originalCard.setXManaCostPaid(0);
|
originalCard.setXManaCostPaid(0);
|
||||||
}
|
}
|
||||||
@@ -544,7 +567,8 @@ public class ManaCostBeingPaid {
|
|||||||
pc.getGame().getAction().exile(c);
|
pc.getGame().getAction().exile(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (spell.getSourceCard().hasKeyword("Convoke")) {
|
}
|
||||||
|
else if (spell.getSourceCard().hasKeyword("Convoke")) {
|
||||||
adjustCostByConvoke(sa, spell);
|
adjustCostByConvoke(sa, spell);
|
||||||
}
|
}
|
||||||
} // isSpell
|
} // isSpell
|
||||||
@@ -565,9 +589,11 @@ public class ManaCostBeingPaid {
|
|||||||
for (final StaticAbility stAb : staticAbilities) {
|
for (final StaticAbility stAb : staticAbilities) {
|
||||||
if (stAb.getMapParams().get("Mode").equals("RaiseCost")) {
|
if (stAb.getMapParams().get("Mode").equals("RaiseCost")) {
|
||||||
raiseAbilities.add(stAb);
|
raiseAbilities.add(stAb);
|
||||||
} else if (stAb.getMapParams().get("Mode").equals("ReduceCost")) {
|
}
|
||||||
|
else if (stAb.getMapParams().get("Mode").equals("ReduceCost")) {
|
||||||
reduceAbilities.add(stAb);
|
reduceAbilities.add(stAb);
|
||||||
} else if (stAb.getMapParams().get("Mode").equals("SetCost")) {
|
}
|
||||||
|
else if (stAb.getMapParams().get("Mode").equals("SetCost")) {
|
||||||
setAbilities.add(stAb);
|
setAbilities.add(stAb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -601,27 +627,29 @@ public class ManaCostBeingPaid {
|
|||||||
String chosenColor = null;
|
String chosenColor = null;
|
||||||
if (sa.getActivatingPlayer().isHuman()) {
|
if (sa.getActivatingPlayer().isHuman()) {
|
||||||
workingCard = GuiChoose.oneOrNone("Tap for Convoke? " + toString(), untappedCreats);
|
workingCard = GuiChoose.oneOrNone("Tap for Convoke? " + toString(), untappedCreats);
|
||||||
if( null == workingCard )
|
if (null == workingCard) {
|
||||||
break; // that means "I'm done"
|
break; // that means "I'm done"
|
||||||
|
}
|
||||||
|
|
||||||
List<String> usableColors = getConvokableColors(workingCard);
|
List<String> usableColors = getConvokableColors(workingCard);
|
||||||
if ( !usableColors.isEmpty() ) {
|
if (!usableColors.isEmpty()) {
|
||||||
chosenColor = usableColors.size() == 1 ? usableColors.get(0) : GuiChoose.one("Convoke for which color?", usableColors);
|
chosenColor = usableColors.size() == 1 ? usableColors.get(0) : GuiChoose.one("Convoke for which color?", usableColors);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// TODO: AI to choose a creature to tap would go here
|
// TODO: AI to choose a creature to tap would go here
|
||||||
// Probably along with deciding how many creatures to tap
|
// Probably along with deciding how many creatures to tap
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
untappedCreats.remove(workingCard);
|
untappedCreats.remove(workingCard);
|
||||||
|
|
||||||
|
if (null == chosenColor) {
|
||||||
if ( null == chosenColor )
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
else if (chosenColor.equals("colorless")) {
|
else if (chosenColor.equals("colorless")) {
|
||||||
decreaseColorlessMana(1);
|
decreaseColorlessMana(1);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
decreaseShard(ManaCostShard.valueOf(MagicColor.fromName(chosenColor)), 1);
|
decreaseShard(ManaCostShard.valueOf(MagicColor.fromName(chosenColor)), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,7 +668,6 @@ public class ManaCostBeingPaid {
|
|||||||
for (final Card c : sa.getTappedForConvoke()) {
|
for (final Card c : sa.getTappedForConvoke()) {
|
||||||
c.setTapped(true);
|
c.setTapped(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -654,14 +681,15 @@ public class ManaCostBeingPaid {
|
|||||||
*/
|
*/
|
||||||
private List<String> getConvokableColors(final Card cardToConvoke) {
|
private List<String> getConvokableColors(final Card cardToConvoke) {
|
||||||
final ArrayList<String> usableColors = new ArrayList<String>();
|
final ArrayList<String> usableColors = new ArrayList<String>();
|
||||||
|
|
||||||
if (getColorlessManaAmount() > 0) {
|
if (getColorlessManaAmount() > 0) {
|
||||||
usableColors.add("colorless");
|
usableColors.add("colorless");
|
||||||
}
|
}
|
||||||
ColorSet cs = CardUtil.getColors(cardToConvoke);
|
ColorSet cs = CardUtil.getColors(cardToConvoke);
|
||||||
for(byte color : MagicColor.WUBRG) {
|
for (byte color : MagicColor.WUBRG) {
|
||||||
if( cs.hasAnyColor(color))
|
if (cs.hasAnyColor(color)) {
|
||||||
usableColors.add(MagicColor.toLongString(color));
|
usableColors.add(MagicColor.toLongString(color));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return usableColors;
|
return usableColors;
|
||||||
}
|
}
|
||||||
@@ -684,7 +712,8 @@ public class ManaCostBeingPaid {
|
|||||||
|
|
||||||
if (!toSacList.isEmpty()) {
|
if (!toSacList.isEmpty()) {
|
||||||
toSac = toSacList.get(0);
|
toSac = toSacList.get(0);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,13 +76,10 @@ import forge.util.TextUtil;
|
|||||||
* Handles phase skips for now.
|
* Handles phase skips for now.
|
||||||
*/
|
*/
|
||||||
public class PlayerControllerHuman extends PlayerController {
|
public class PlayerControllerHuman extends PlayerController {
|
||||||
|
|
||||||
|
|
||||||
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp) {
|
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp) {
|
||||||
super(game0, p, lp);
|
super(game0, p, lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
||||||
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
|
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,7 +280,9 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
* a {@link forge.game.spellability.SpellAbility} object.
|
* a {@link forge.game.spellability.SpellAbility} object.
|
||||||
*/
|
*/
|
||||||
public final void add(final SpellAbility sp) {
|
public final void add(final SpellAbility sp) {
|
||||||
FThreads.assertExecutedByEdt(false);
|
if (!sp.isManaAbility()) { //allow adding mana abilities on EDT
|
||||||
|
FThreads.assertExecutedByEdt(false);
|
||||||
|
}
|
||||||
SpellAbilityStackInstance si = null;
|
SpellAbilityStackInstance si = null;
|
||||||
final Card source = sp.getSourceCard();
|
final Card source = sp.getSourceCard();
|
||||||
Player activator = sp.getActivatingPlayer();
|
Player activator = sp.getActivatingPlayer();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.util.List;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
|
import forge.ai.ComputerUtilMana;
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
@@ -109,7 +110,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
boolean canUseColorless = manaCost.isAnyPartPayableWith((byte)0);
|
boolean canUseColorless = manaCost.isAnyPartPayableWith((byte)0);
|
||||||
|
|
||||||
List<SpellAbility> abilities = new ArrayList<SpellAbility>();
|
List<SpellAbility> abilities = new ArrayList<SpellAbility>();
|
||||||
// you can't remove unneeded abilities inside a for(am:abilities) loop :(
|
// you can't remove unneeded abilities inside a for (am:abilities) loop :(
|
||||||
|
|
||||||
final String typeRes = manaCost.getSourceRestriction();
|
final String typeRes = manaCost.getSourceRestriction();
|
||||||
if (StringUtils.isNotBlank(typeRes) && !card.isType(typeRes)) {
|
if (StringUtils.isNotBlank(typeRes) && !card.isType(typeRes)) {
|
||||||
@@ -193,7 +194,6 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
game.getAction().invoke(proc);
|
game.getAction().invoke(proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* canMake. color is like "G", returns "Green".
|
* canMake. color is like "G", returns "Green".
|
||||||
@@ -272,16 +272,52 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
return bPaid;
|
return bPaid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean supportAutoPay() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
protected void onOk() {
|
||||||
|
if (supportAutoPay()) {
|
||||||
|
//use AI utility to automatically pay mana cost if possible
|
||||||
|
ComputerUtilMana.payManaCost(manaCost, saPaidFor, player);
|
||||||
|
this.showMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateButtons() {
|
||||||
|
if (supportAutoPay()) {
|
||||||
|
ButtonUtil.setButtonText("Auto", "Cancel");
|
||||||
|
}
|
||||||
|
ButtonUtil.enableOnlyCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void updateMessage() {
|
||||||
|
if (supportAutoPay() && ComputerUtilMana.canPayManaCost(manaCost, saPaidFor, player)) {
|
||||||
|
ButtonUtil.enableAllFocusOk(); //enabled Auto button if mana cost can be paid
|
||||||
|
}
|
||||||
|
showMessage(getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
protected final void onStop() {
|
||||||
|
if (supportAutoPay()) {
|
||||||
|
ButtonUtil.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public void showMessage() {
|
public void showMessage() {
|
||||||
if (isFinished()) { return; }
|
if (isFinished()) { return; }
|
||||||
ButtonUtil.enableOnlyCancel();
|
updateButtons();
|
||||||
onStateChanged();
|
onStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onStateChanged() {
|
protected void onStateChanged() {
|
||||||
if(isAlreadyPaid()) {
|
if (isAlreadyPaid()) {
|
||||||
done();
|
done();
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
@@ -297,11 +333,11 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
|
|
||||||
protected void onManaAbilityPaid() {} // some inputs overload it
|
protected void onManaAbilityPaid() {} // some inputs overload it
|
||||||
protected abstract void done();
|
protected abstract void done();
|
||||||
protected abstract void updateMessage();
|
protected abstract String getMessage();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("PayManaBase %s left", manaCost.toString() );
|
return String.format("PayManaBase %s left", manaCost.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPaid() { return bPaid; }
|
public boolean isPaid() { return bPaid; }
|
||||||
|
|||||||
@@ -102,11 +102,9 @@ public class InputPayManaExecuteCommands extends InputPayMana {
|
|||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/** {@inheritDoc} */
|
||||||
* @see forge.control.input.InputPayManaBase#updateMessage()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateMessage() {
|
protected String getMessage() {
|
||||||
final StringBuilder msg = new StringBuilder(this.message + "Pay Mana Cost: " + this.manaCost);
|
final StringBuilder msg = new StringBuilder(this.message + "Pay Mana Cost: " + this.manaCost);
|
||||||
if (this.phyLifeToLose > 0) {
|
if (this.phyLifeToLose > 0) {
|
||||||
msg.append(" (");
|
msg.append(" (");
|
||||||
@@ -117,6 +115,6 @@ public class InputPayManaExecuteCommands extends InputPayMana {
|
|||||||
if (this.manaCost.containsPhyrexianMana()) {
|
if (this.manaCost.containsPhyrexianMana()) {
|
||||||
msg.append("\n(Click on your life total to pay life for phyrexian mana.)");
|
msg.append("\n(Click on your life total to pay life for phyrexian mana.)");
|
||||||
}
|
}
|
||||||
showMessage(msg.toString());
|
return msg.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import forge.game.player.Player;
|
|||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
public class InputPayManaOfCostPayment extends InputPayMana {
|
public class InputPayManaOfCostPayment extends InputPayMana {
|
||||||
|
|
||||||
public InputPayManaOfCostPayment(ManaCostBeingPaid cost, SpellAbility spellAbility) {
|
public InputPayManaOfCostPayment(ManaCostBeingPaid cost, SpellAbility spellAbility) {
|
||||||
super(spellAbility);
|
super(spellAbility);
|
||||||
manaCost = cost;
|
manaCost = cost;
|
||||||
@@ -39,7 +38,8 @@ public class InputPayManaOfCostPayment extends InputPayMana {
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateMessage() {
|
@Override
|
||||||
|
protected String getMessage() {
|
||||||
final String displayMana = manaCost.toString(false);
|
final String displayMana = manaCost.toString(false);
|
||||||
|
|
||||||
final StringBuilder msg = new StringBuilder("Pay Mana Cost: " + displayMana);
|
final StringBuilder msg = new StringBuilder("Pay Mana Cost: " + displayMana);
|
||||||
@@ -53,6 +53,6 @@ public class InputPayManaOfCostPayment extends InputPayMana {
|
|||||||
msg.append("\n(Click on your life total to pay life for phyrexian mana.)");
|
msg.append("\n(Click on your life total to pay life for phyrexian mana.)");
|
||||||
}
|
}
|
||||||
|
|
||||||
showMessage(msg.toString());
|
return msg.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import forge.game.card.Card;
|
|||||||
import forge.game.mana.ManaCostBeingPaid;
|
import forge.game.mana.ManaCostBeingPaid;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.view.ButtonUtil;
|
|
||||||
|
|
||||||
//pays the cost of a card played from the player's hand
|
//pays the cost of a card played from the player's hand
|
||||||
//the card is removed from the players hand if the cost is paid
|
//the card is removed from the players hand if the cost is paid
|
||||||
@@ -102,7 +101,7 @@ public class InputPayManaSimple extends InputPayMana {
|
|||||||
public final void showMessage() {
|
public final void showMessage() {
|
||||||
if (isFinished()) { return; }
|
if (isFinished()) { return; }
|
||||||
|
|
||||||
ButtonUtil.enableOnlyCancel();
|
updateButtons();
|
||||||
|
|
||||||
if (this.manaCost.isPaid() && !new ManaCostBeingPaid(this.originalManaCost).isPaid()) {
|
if (this.manaCost.isPaid() && !new ManaCostBeingPaid(this.originalManaCost).isPaid()) {
|
||||||
this.done();
|
this.done();
|
||||||
@@ -117,7 +116,7 @@ public class InputPayManaSimple extends InputPayMana {
|
|||||||
* @see forge.control.input.InputPayManaBase#updateMessage()
|
* @see forge.control.input.InputPayManaBase#updateMessage()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void updateMessage() {
|
protected String getMessage() {
|
||||||
final StringBuilder msg = new StringBuilder("Pay Mana Cost: " + this.manaCost.toString());
|
final StringBuilder msg = new StringBuilder("Pay Mana Cost: " + this.manaCost.toString());
|
||||||
if (this.phyLifeToLose > 0) {
|
if (this.phyLifeToLose > 0) {
|
||||||
msg.append(" (");
|
msg.append(" (");
|
||||||
@@ -130,6 +129,6 @@ public class InputPayManaSimple extends InputPayMana {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// has its own variant of checkIfPaid
|
// has its own variant of checkIfPaid
|
||||||
showMessage(msg.toString());
|
return msg.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ public class InputPayManaX extends InputPayMana {
|
|||||||
return !canceled && (xPaid > 0 || xCanBe0);
|
return !canceled && (xPaid > 0 || xCanBe0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportAutoPay() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showMessage() {
|
public void showMessage() {
|
||||||
if (isFinished()) { return; }
|
if (isFinished()) { return; }
|
||||||
@@ -63,7 +68,7 @@ public class InputPayManaX extends InputPayMana {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateMessage() {
|
protected String getMessage() {
|
||||||
StringBuilder msg = new StringBuilder("Pay X Mana Cost for ");
|
StringBuilder msg = new StringBuilder("Pay X Mana Cost for ");
|
||||||
msg.append(saPaidFor.getSourceCard().getName()).append("\n").append(this.xPaid);
|
msg.append(saPaidFor.getSourceCard().getName()).append("\n").append(this.xPaid);
|
||||||
msg.append(" Paid so far.");
|
msg.append(" Paid so far.");
|
||||||
@@ -79,7 +84,7 @@ public class InputPayManaX extends InputPayMana {
|
|||||||
ButtonUtil.enableAllFocusOk();
|
ButtonUtil.enableAllFocusOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
showMessage(msg.toString());
|
return msg.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import forge.FThreads;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.error.BugReporter;
|
import forge.error.BugReporter;
|
||||||
|
|
||||||
public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized {
|
public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized {
|
||||||
private static final long serialVersionUID = 8756177361251703052L;
|
private static final long serialVersionUID = 8756177361251703052L;
|
||||||
private final CountDownLatch cdlDone;
|
private final CountDownLatch cdlDone;
|
||||||
|
|
||||||
public InputSyncronizedBase() {
|
public InputSyncronizedBase() {
|
||||||
cdlDone = new CountDownLatch(1);
|
cdlDone = new CountDownLatch(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void awaitLatchRelease() {
|
public void awaitLatchRelease() {
|
||||||
FThreads.assertExecutedByEdt(false);
|
FThreads.assertExecutedByEdt(false);
|
||||||
try{
|
try{
|
||||||
@@ -22,17 +22,26 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
|||||||
BugReporter.reportException(e);
|
BugReporter.reportException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void relaseLatchWhenGameIsOver() {
|
public final void relaseLatchWhenGameIsOver() {
|
||||||
cdlDone.countDown();
|
cdlDone.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void stop() {
|
|
||||||
// ensure input won't accept any user actions.
|
|
||||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { setFinished(); } });
|
|
||||||
|
|
||||||
// thread irrelevant
|
protected final void stop() {
|
||||||
|
onStop();
|
||||||
|
|
||||||
|
// ensure input won't accept any user actions.
|
||||||
|
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
setFinished();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// thread irrelevant
|
||||||
Singletons.getControl().getInputQueue().removeInput(InputSyncronizedBase.this);
|
Singletons.getControl().getInputQueue().removeInput(InputSyncronizedBase.this);
|
||||||
cdlDone.countDown();
|
cdlDone.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onStop() { }
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ import java.util.EnumMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this type.
|
* TODO: Write javadoc for this type.
|
||||||
*
|
*
|
||||||
@@ -12,7 +11,6 @@ import java.util.Map;
|
|||||||
public class EnumMapToAmount<T extends Enum<T>> extends EnumMap<T, Integer> implements MapToAmount<T> {
|
public class EnumMapToAmount<T extends Enum<T>> extends EnumMap<T, Integer> implements MapToAmount<T> {
|
||||||
private static final long serialVersionUID = -4749796492075359368L;
|
private static final long serialVersionUID = -4749796492075359368L;
|
||||||
|
|
||||||
|
|
||||||
public EnumMapToAmount(Class<T> keyType) {
|
public EnumMapToAmount(Class<T> keyType) {
|
||||||
super(keyType);
|
super(keyType);
|
||||||
}
|
}
|
||||||
@@ -32,15 +30,17 @@ public class EnumMapToAmount<T extends Enum<T>> extends EnumMap<T, Integer> impl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(T item, int amount) {
|
public void add(T item, int amount) {
|
||||||
if (amount <= 0) return; // throw an exception maybe?
|
if (amount <= 0) { return; } // throw an exception maybe?
|
||||||
Integer cur = get(item);
|
Integer cur = get(item);
|
||||||
int newVal = cur == null ? amount : amount + cur.intValue();
|
int newVal = cur == null ? amount : amount + cur.intValue();
|
||||||
put(item, Integer.valueOf(newVal));
|
put(item, Integer.valueOf(newVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAll(Iterable<T> item) {
|
public void addAll(Iterable<T> items) {
|
||||||
for(T i : item) add(i, 1);
|
for (T i : items) {
|
||||||
|
add(i, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,39 +48,39 @@ public class EnumMapToAmount<T extends Enum<T>> extends EnumMap<T, Integer> impl
|
|||||||
return substract(item, 1);
|
return substract(item, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean substract(T item, int amount) {
|
public boolean substract(T item, int amount) {
|
||||||
Integer cur = get(item);
|
Integer cur = get(item);
|
||||||
if( cur == null ) return false;
|
if (cur == null) { return false; }
|
||||||
int newVal = cur.intValue() - amount;
|
int newVal = cur.intValue() - amount;
|
||||||
if(newVal > 0)
|
if (newVal > 0) {
|
||||||
put(item, Integer.valueOf(newVal));
|
put(item, Integer.valueOf(newVal));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
remove(item);
|
remove(item);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void substractAll(Iterable<T> item) {
|
public void substractAll(Iterable<T> items) {
|
||||||
for(T i : item) substract(i);
|
for (T i : items) {
|
||||||
|
substract(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countAll() {
|
public int countAll() {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
for(java.util.Map.Entry<T, Integer> kv : this.entrySet()) {
|
for (java.util.Map.Entry<T, Integer> kv : this.entrySet()) {
|
||||||
c += kv.getValue().intValue();
|
c += kv.getValue().intValue();
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int count(T item) {
|
public int count(T item) {
|
||||||
Integer cur = get(item);
|
Integer cur = get(item);
|
||||||
return cur == null ? 0 : cur.intValue();
|
return cur == null ? 0 : cur.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import java.util.Map;
|
|||||||
public interface MapToAmount<K> extends Map<K, Integer> {
|
public interface MapToAmount<K> extends Map<K, Integer> {
|
||||||
void add(K item);
|
void add(K item);
|
||||||
void add(K item, int amount);
|
void add(K item, int amount);
|
||||||
void addAll(Iterable<K> item);
|
void addAll(Iterable<K> items);
|
||||||
boolean substract(K item);
|
boolean substract(K item);
|
||||||
boolean substract(K item, int amount);
|
boolean substract(K item, int amount);
|
||||||
void substractAll(Iterable<K> item);
|
void substractAll(Iterable<K> items);
|
||||||
int countAll();
|
int countAll();
|
||||||
int count(K item); // just unboxes and returns zero instead of null
|
int count(K item); // just unboxes and returns zero instead of null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,34 +86,33 @@ public abstract class CardPanelContainer extends JPanel {
|
|||||||
* @param scrollPane
|
* @param scrollPane
|
||||||
* a {@link javax.swing.JScrollPane} object.
|
* a {@link javax.swing.JScrollPane} object.
|
||||||
*/
|
*/
|
||||||
public CardPanelContainer(final JScrollPane scrollPane) {
|
public CardPanelContainer(final JScrollPane scrollPane) {
|
||||||
this.scrollPane = scrollPane;
|
this.scrollPane = scrollPane;
|
||||||
this.setOpaque(true);
|
this.setOpaque(true);
|
||||||
setupMouseListeners();
|
setupMouseListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupMouseListeners() {
|
private void setupMouseListeners() {
|
||||||
final MouseMotionListener mml = setupMotionMouseListener();
|
final MouseMotionListener mml = setupMotionMouseListener();
|
||||||
setupMouseListener(mml);
|
setupMouseListener(mml);
|
||||||
setupMouseWheelListener();
|
setupMouseWheelListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupMouseWheelListener() {
|
private void setupMouseWheelListener() {
|
||||||
this.addMouseWheelListener(new MouseWheelListener() {
|
this.addMouseWheelListener(new MouseWheelListener() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
final CardPanel hitPanel = CardPanelContainer.this.getCardPanel(e.getX(), e.getY());
|
final CardPanel hitPanel = CardPanelContainer.this.getCardPanel(e.getX(), e.getY());
|
||||||
if (hitPanel != null) {
|
if (hitPanel != null) {
|
||||||
if (e.getWheelRotation() < 0) {
|
if (e.getWheelRotation() < 0) {
|
||||||
CardZoomer.SINGLETON_INSTANCE.doMouseWheelZoom(hitPanel.getCard());
|
CardZoomer.SINGLETON_INSTANCE.doMouseWheelZoom(hitPanel.getCard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupMouseListener(final MouseMotionListener mml) {
|
private void setupMouseListener(final MouseMotionListener mml) {
|
||||||
|
|
||||||
this.addMouseListener(new MouseAdapter() {
|
this.addMouseListener(new MouseAdapter() {
|
||||||
private final boolean[] buttonsDown = new boolean[4];
|
private final boolean[] buttonsDown = new boolean[4];
|
||||||
|
|
||||||
@@ -181,13 +180,10 @@ public abstract class CardPanelContainer extends JPanel {
|
|||||||
CardPanelContainer.this.mouseOutPanel(evt);
|
CardPanelContainer.this.mouseOutPanel(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MouseMotionListener setupMotionMouseListener() {
|
|
||||||
|
|
||||||
|
private MouseMotionListener setupMotionMouseListener() {
|
||||||
final MouseMotionListener mml = new MouseMotionListener() {
|
final MouseMotionListener mml = new MouseMotionListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged(final MouseEvent evt) {
|
public void mouseDragged(final MouseEvent evt) {
|
||||||
if (CardZoomer.SINGLETON_INSTANCE.isZoomerOpen() || !SwingUtilities.isLeftMouseButton(evt)) {
|
if (CardZoomer.SINGLETON_INSTANCE.isZoomerOpen() || !SwingUtilities.isLeftMouseButton(evt)) {
|
||||||
@@ -229,7 +225,7 @@ public abstract class CardPanelContainer extends JPanel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseMoved(final MouseEvent evt) {
|
public void mouseMoved(final MouseEvent evt) {
|
||||||
final CardPanel hitPanel = CardPanelContainer.this.getCardPanel(evt.getX(), evt.getY());
|
final CardPanel hitPanel = CardPanelContainer.this.getCardPanel(evt.getX(), evt.getY());
|
||||||
|
|
||||||
if (CardPanelContainer.this.hoveredPanel == hitPanel) { // no big change
|
if (CardPanelContainer.this.hoveredPanel == hitPanel) { // no big change
|
||||||
return;
|
return;
|
||||||
@@ -246,7 +242,7 @@ public abstract class CardPanelContainer extends JPanel {
|
|||||||
CardPanelContainer.this.hoveredPanel.setSelected(true);
|
CardPanelContainer.this.hoveredPanel.setSelected(true);
|
||||||
CardPanelContainer.this.mouseOver(hitPanel, evt);
|
CardPanelContainer.this.mouseOver(hitPanel, evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// System.err.format("%d %d over %s%n", evt.getX(), evt.getY(), hitPanel == null ? null : hitPanel.getCard().getName());
|
// System.err.format("%d %d over %s%n", evt.getX(), evt.getY(), hitPanel == null ? null : hitPanel.getCard().getName());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -348,8 +344,6 @@ public abstract class CardPanelContainer extends JPanel {
|
|||||||
CardPanelContainer.this.remove(fromPanel);
|
CardPanelContainer.this.remove(fromPanel);
|
||||||
CardPanelContainer.this.invalidate();
|
CardPanelContainer.this.invalidate();
|
||||||
CardPanelContainer.this.repaint();
|
CardPanelContainer.this.repaint();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -590,12 +584,12 @@ public abstract class CardPanelContainer extends JPanel {
|
|||||||
// the already-hovered card, though, since we cannot tell the difference between that and clicking
|
// the already-hovered card, though, since we cannot tell the difference between that and clicking
|
||||||
// on the hovered card when the app already has focus.
|
// on the hovered card when the app already has focus.
|
||||||
CardPanel p = getCardPanel(e.getX(), e.getY());
|
CardPanel p = getCardPanel(e.getX(), e.getY());
|
||||||
|
|
||||||
// if cursor has jumped, for example via the above alt-tabbing example, fix the card hover highlight
|
// if cursor has jumped, for example via the above alt-tabbing example, fix the card hover highlight
|
||||||
if (null != hoveredPanel && p != hoveredPanel) {
|
if (null != hoveredPanel && p != hoveredPanel) {
|
||||||
mouseOut(hoveredPanel, e);
|
mouseOut(hoveredPanel, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (null == p || p != hoveredPanel) ? null : p.getGameCard();
|
return (null == p || p != hoveredPanel) ? null : p.getGameCard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user