Merge remote-tracking branch 'core/master'

This commit is contained in:
Anthony Calosa
2021-10-21 12:40:54 +08:00
34 changed files with 170 additions and 232 deletions

View File

@@ -30,7 +30,7 @@ public class ControlExchangeAi extends SpellAbilityAi {
sa.resetTargets(); sa.resetTargets();
CardCollection list = CardCollection list =
CardLists.getValidCards(AiAttackController.choosePreferredDefenderPlayer(ai).getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa); CardLists.getValidCards(ai.getOpponents().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa);
// AI won't try to grab cards that are filtered out of AI decks on purpose // AI won't try to grab cards that are filtered out of AI decks on purpose
list = CardLists.filter(list, new Predicate<Card>() { list = CardLists.filter(list, new Predicate<Card>() {
@Override @Override
@@ -65,7 +65,7 @@ public class ControlExchangeAi extends SpellAbilityAi {
} }
} else { } else {
if (mandatory) { if (mandatory) {
return chkAIDrawback(sa, aiPlayer); return chkAIDrawback(sa, aiPlayer) || sa.isTargetNumberValid();
} else { } else {
return canPlayAI(aiPlayer, sa); return canPlayAI(aiPlayer, sa);
} }
@@ -97,8 +97,12 @@ public class ControlExchangeAi extends SpellAbilityAi {
Card best = ComputerUtilCard.getBestAI(list); Card best = ComputerUtilCard.getBestAI(list);
// add best Target:
// do it here already even if we don't want to play this as it might be for targeting a trigger
sa.getTargets().add(best);
// if Param has Defined, check if the best Target is better than the Defined // if Param has Defined, check if the best Target is better than the Defined
if (sa.hasParam("Defined")) { if (sa.hasParam("Defined") && (!sa.isTrigger() || sa.getRootAbility().isOptionalTrigger())) {
final Card object = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa).get(0); final Card object = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa).get(0);
// TODO add evaluate Land if able // TODO add evaluate Land if able
final Card realBest = ComputerUtilCard.getBestAI(Lists.newArrayList(best, object)); final Card realBest = ComputerUtilCard.getBestAI(Lists.newArrayList(best, object));
@@ -109,9 +113,6 @@ public class ControlExchangeAi extends SpellAbilityAi {
} }
} }
// add best Target
sa.getTargets().add(best);
// second target needed (the AI's own worst) // second target needed (the AI's own worst)
if ("TrigTwoTargets".equals(sa.getParam("AILogic"))) { if ("TrigTwoTargets".equals(sa.getParam("AILogic"))) {
return doTrigTwoTargetsLogic(aiPlayer, sa, best); return doTrigTwoTargetsLogic(aiPlayer, sa, best);

View File

@@ -37,7 +37,7 @@ public class CountersPutAllAi extends SpellAbilityAi {
final boolean curse = sa.isCurse(); final boolean curse = sa.isCurse();
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if ("OwnCreatsAndOtherPWs".equals(sa.getParam("AILogic"))) { if ("OwnCreatsAndOtherPWs".equals(logic)) {
hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source, sa); hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source, sa);
cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source, sa); cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source, sa);
} else { } else {

View File

@@ -94,7 +94,7 @@ public class DamageAllAi extends SpellAbilityAi {
private Player determineOppToKill(Player ai, SpellAbility sa, Card source, int x) { private Player determineOppToKill(Player ai, SpellAbility sa, Card source, int x) {
// Attempt to determine which opponent can be finished off such that the most players // Attempt to determine which opponent can be finished off such that the most players
// are killed at the same time, given X damage tops // are killed at the same time, given X damage tops
final String validP = sa.hasParam("ValidPlayers") ? sa.getParam("ValidPlayers") : ""; final String validP = sa.getParamOrDefault("ValidPlayers", "");
int aiLife = ai.getLife(); int aiLife = ai.getLife();
Player bestOpp = null; // default opponent, if all else fails Player bestOpp = null; // default opponent, if all else fails
@@ -125,7 +125,7 @@ public class DamageAllAi extends SpellAbilityAi {
computerList.clear(); computerList.clear();
} }
final String validP = sa.hasParam("ValidPlayers") ? sa.getParam("ValidPlayers") : ""; final String validP = sa.getParamOrDefault("ValidPlayers", "");
// TODO: if damage is dependant on mana paid, maybe have X be human's max life // TODO: if damage is dependant on mana paid, maybe have X be human's max life
// Don't kill yourself // Don't kill yourself
if (validP.equals("Player") && (ai.getLife() <= ComputerUtilCombat.predictDamageTo(ai, dmg, source, false))) { if (validP.equals("Player") && (ai.getLife() <= ComputerUtilCombat.predictDamageTo(ai, dmg, source, false))) {
@@ -191,7 +191,7 @@ public class DamageAllAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
String validP = ""; final String validP = sa.getParamOrDefault("ValidPlayers", "");
final String damage = sa.getParam("NumDmg"); final String damage = sa.getParam("NumDmg");
int dmg; int dmg;
@@ -203,10 +203,6 @@ public class DamageAllAi extends SpellAbilityAi {
dmg = AbilityUtils.calculateAmount(source, damage, sa); dmg = AbilityUtils.calculateAmount(source, damage, sa);
} }
if (sa.hasParam("ValidPlayers")) {
validP = sa.getParam("ValidPlayers");
}
// Evaluate creatures getting killed // Evaluate creatures getting killed
Player enemy = ai.getWeakestOpponent(); Player enemy = ai.getWeakestOpponent();
final CardCollection humanList = getKillableCreatures(sa, enemy, dmg); final CardCollection humanList = getKillableCreatures(sa, enemy, dmg);
@@ -251,7 +247,7 @@ public class DamageAllAi extends SpellAbilityAi {
*/ */
private CardCollection getKillableCreatures(final SpellAbility sa, final Player player, final int dmg) { private CardCollection getKillableCreatures(final SpellAbility sa, final Player player, final int dmg) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
String validC = sa.hasParam("ValidCards") ? sa.getParam("ValidCards") : ""; String validC = sa.getParamOrDefault("ValidCards", "");
// TODO: X may be something different than X paid // TODO: X may be something different than X paid
CardCollection list = CardCollection list =
@@ -273,7 +269,7 @@ public class DamageAllAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
String validP = ""; final String validP = sa.getParamOrDefault("ValidPlayers", "");
final String damage = sa.getParam("NumDmg"); final String damage = sa.getParam("NumDmg");
int dmg; int dmg;
@@ -286,10 +282,6 @@ public class DamageAllAi extends SpellAbilityAi {
dmg = AbilityUtils.calculateAmount(source, damage, sa); dmg = AbilityUtils.calculateAmount(source, damage, sa);
} }
if (sa.hasParam("ValidPlayers")) {
validP = sa.getParam("ValidPlayers");
}
// Evaluate creatures getting killed // Evaluate creatures getting killed
Player enemy = ai.getWeakestOpponent(); Player enemy = ai.getWeakestOpponent();
final CardCollection humanList = getKillableCreatures(sa, enemy, dmg); final CardCollection humanList = getKillableCreatures(sa, enemy, dmg);

View File

@@ -81,10 +81,7 @@ public class DestroyAllAi extends SpellAbilityAi {
return true; // e.g. Tetzimoc, Primal Death, where we want to cast the permanent even if the removal trigger does nothing return true; // e.g. Tetzimoc, Primal Death, where we want to cast the permanent even if the removal trigger does nothing
} }
String valid = ""; String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
if (valid.contains("X") && sa.getSVar("X").equals("Count$xPaid")) { if (valid.contains("X") && sa.getSVar("X").equals("Count$xPaid")) {
// Set PayX here to maximum value. // Set PayX here to maximum value.

View File

@@ -33,7 +33,6 @@ public class PumpAllAi extends PumpAiBase {
*/ */
@Override @Override
protected boolean canPlayAI(final Player ai, final SpellAbility sa) { protected boolean canPlayAI(final Player ai, final SpellAbility sa) {
String valid = "";
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final Game game = ai.getGame(); final Game game = ai.getGame();
final Combat combat = game.getCombat(); final Combat combat = game.getCombat();
@@ -78,9 +77,7 @@ public class PumpAllAi extends PumpAiBase {
final List<String> keywords = sa.hasParam("KW") ? Arrays.asList(sa.getParam("KW").split(" & ")) : new ArrayList<>(); final List<String> keywords = sa.hasParam("KW") ? Arrays.asList(sa.getParam("KW").split(" & ")) : new ArrayList<>();
final PhaseType phase = game.getPhaseHandler().getPhase(); final PhaseType phase = game.getPhaseHandler().getPhase();
if (sa.hasParam("ValidCards")) { final String valid = sa.getParamOrDefault("ValidCards", "");
valid = sa.getParam("ValidCards");
}
CardCollection comp = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa); CardCollection comp = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa);
CardCollection human = CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa); CardCollection human = CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa);

View File

@@ -26,11 +26,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
final Game game = ai.getGame(); final Game game = ai.getGame();
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield); CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa); list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa);

View File

@@ -34,10 +34,7 @@ public class TapAllAi extends SpellAbilityAi {
return false; return false;
} }
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
CardCollectionView validTappables = game.getCardsIn(ZoneType.Battlefield); CardCollectionView validTappables = game.getCardsIn(ZoneType.Battlefield);
@@ -99,10 +96,7 @@ public class TapAllAi extends SpellAbilityAi {
protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
CardCollectionView validTappables = getTapAllTargets(valid, source, sa); CardCollectionView validTappables = getTapAllTargets(valid, source, sa);

View File

@@ -24,10 +24,7 @@ public class TwoPilesAi extends SpellAbilityAi {
zone = ZoneType.smartValueOf(sa.getParam("Zone")); zone = ZoneType.smartValueOf(sa.getParam("Zone"));
} }
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
final Player opp = AiAttackController.choosePreferredDefenderPlayer(ai); final Player opp = AiAttackController.choosePreferredDefenderPlayer(ai);

View File

@@ -24,11 +24,8 @@ public class UntapAllAi extends SpellAbilityAi {
&& source.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_END)) { && source.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_END)) {
return false; return false;
} }
String valid = "";
CardCollectionView list = CardLists.filter(aiPlayer.getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.TAPPED); CardCollectionView list = CardLists.filter(aiPlayer.getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.TAPPED);
if (sa.hasParam("ValidCards")) { final String valid = sa.getParamOrDefault("ValidCards", "");
valid = sa.getParam("ValidCards");
}
list = CardLists.getValidCards(list, valid.split(","), source.getController(), source, sa); list = CardLists.getValidCards(list, valid.split(","), source.getController(), source, sa);
// don't untap if only opponent benefits // don't untap if only opponent benefits
PlayerCollection goodControllers = aiPlayer.getAllies(); PlayerCollection goodControllers = aiPlayer.getAllies();

View File

@@ -121,11 +121,7 @@ public class AnimateAllEffect extends AnimateEffectBase {
sVars.addAll(Arrays.asList(sa.getParam("sVars").split(","))); sVars.addAll(Arrays.asList(sa.getParam("sVars").split(",")));
} }
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
CardCollectionView list; CardCollectionView list;

View File

@@ -20,7 +20,7 @@ public class CountersPutAllEffect extends SpellAbilityEffect {
final CounterType cType = CounterType.getType(sa.getParam("CounterType")); final CounterType cType = CounterType.getType(sa.getParam("CounterType"));
final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("CounterNum"), sa); final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("CounterNum"), sa);
final String zone = sa.hasParam("ValidZone") ? sa.getParam("ValidZone") : "Battlefield"; final String zone = sa.getParamOrDefault("ValidZone", "Battlefield");
sb.append("Put ").append(amount).append(" ").append(cType.getName()).append(" counter"); sb.append("Put ").append(amount).append(" ").append(cType.getName()).append(" counter");
if (amount != 1) { if (amount != 1) {

View File

@@ -22,7 +22,7 @@ public class CountersRemoveAllEffect extends SpellAbilityEffect {
final CounterType cType = CounterType.getType(sa.getParam("CounterType")); final CounterType cType = CounterType.getType(sa.getParam("CounterType"));
final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("CounterNum"), sa); final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("CounterNum"), sa);
final String zone = sa.hasParam("ValidZone") ? sa.getParam("ValidZone") : "Battlefield"; final String zone = sa.getParamOrDefault("ValidZone", "Battlefield");
String amountString = Integer.toString(amount); String amountString = Integer.toString(amount);
if (sa.hasParam("AllCounters")) { if (sa.hasParam("AllCounters")) {

View File

@@ -22,10 +22,7 @@ public class DamageAllEffect extends DamageBaseEffect {
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
String desc = ""; final String desc = sa.getParamOrDefault("ValidDescription", "");
if (sa.hasParam("ValidDescription")) {
desc = sa.getParam("ValidDescription");
}
final String damage = sa.getParam("NumDmg"); final String damage = sa.getParam("NumDmg");
final int dmg = AbilityUtils.calculateAmount(sa.getHostCard(), damage, sa); final int dmg = AbilityUtils.calculateAmount(sa.getHostCard(), damage, sa);
@@ -63,11 +60,7 @@ public class DamageAllEffect extends DamageBaseEffect {
//Remember params from this effect have been moved to dealDamage in GameAction //Remember params from this effect have been moved to dealDamage in GameAction
Player targetPlayer = sa.getTargets().getFirstTargetedPlayer(); Player targetPlayer = sa.getTargets().getFirstTargetedPlayer();
String players = ""; final String players = sa.getParamOrDefault("ValidPlayers", "");
if (sa.hasParam("ValidPlayers")) {
players = sa.getParam("ValidPlayers");
}
CardCollectionView list; CardCollectionView list;
if (sa.hasParam("ValidCards")) { if (sa.hasParam("ValidCards")) {

View File

@@ -15,11 +15,7 @@ public class DamagePreventAllEffect extends DamagePreventEffectBase {
final Game game = sa.getActivatingPlayer().getGame(); final Game game = sa.getActivatingPlayer().getGame();
final int numDam = AbilityUtils.calculateAmount(source, sa.getParam("Amount"), sa); final int numDam = AbilityUtils.calculateAmount(source, sa.getParam("Amount"), sa);
String players = ""; final String players = sa.getParamOrDefault("ValidPlayers", "");
if (sa.hasParam("ValidPlayers")) {
players = sa.getParam("ValidPlayers");
}
if (sa.hasParam("ValidCards")) { if (sa.hasParam("ValidCards")) {
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield); CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);

View File

@@ -24,7 +24,6 @@ public class DestroyAllEffect extends SpellAbilityEffect {
@Override @Override
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
if (sa.hasParam("SpellDescription")) { if (sa.hasParam("SpellDescription")) {
return sa.getParam("SpellDescription"); return sa.getParam("SpellDescription");
} }
@@ -51,11 +50,7 @@ public class DestroyAllEffect extends SpellAbilityEffect {
Player targetPlayer = sa.getTargets().getFirstTargetedPlayer(); Player targetPlayer = sa.getTargets().getFirstTargetedPlayer();
String valid = ""; String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
// Ugh. If calculateAmount needs to be called with DestroyAll it _needs_ // Ugh. If calculateAmount needs to be called with DestroyAll it _needs_
// to use the X variable // to use the X variable

View File

@@ -72,7 +72,7 @@ public class DigEffect extends SpellAbilityEffect {
int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : -1; int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : -1;
int destZone1ChangeNum = 1; int destZone1ChangeNum = 1;
final boolean mitosis = sa.hasParam("Mitosis"); final boolean mitosis = sa.hasParam("Mitosis");
String changeValid = sa.hasParam("ChangeValid") ? sa.getParam("ChangeValid") : ""; String changeValid = sa.getParamOrDefault("ChangeValid", "");
final boolean anyNumber = sa.hasParam("AnyNumber"); final boolean anyNumber = sa.hasParam("AnyNumber");
final int libraryPosition2 = sa.hasParam("LibraryPosition2") ? Integer.parseInt(sa.getParam("LibraryPosition2")) : -1; final int libraryPosition2 = sa.hasParam("LibraryPosition2") ? Integer.parseInt(sa.getParam("LibraryPosition2")) : -1;
@@ -86,7 +86,7 @@ public class DigEffect extends SpellAbilityEffect {
// These parameters are used to indicate that a dialog box must be show to the player asking if the player wants to proceed // These parameters are used to indicate that a dialog box must be show to the player asking if the player wants to proceed
// with an optional ability, otherwise the optional ability is skipped. // with an optional ability, otherwise the optional ability is skipped.
final boolean mayBeSkipped = sa.hasParam("PromptToSkipOptionalAbility"); final boolean mayBeSkipped = sa.hasParam("PromptToSkipOptionalAbility");
final String optionalAbilityPrompt = sa.hasParam("OptionalAbilityPrompt") ? sa.getParam("OptionalAbilityPrompt") : ""; final String optionalAbilityPrompt = sa.getParamOrDefault("OptionalAbilityPrompt", "");
boolean remZone1 = false; boolean remZone1 = false;
boolean remZone2 = false; boolean remZone2 = false;

View File

@@ -35,7 +35,7 @@ public class DigMultipleEffect extends SpellAbilityEffect {
int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : -1; int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : -1;
final int libraryPosition2 = sa.hasParam("LibraryPosition2") ? Integer.parseInt(sa.getParam("LibraryPosition2")) : -1; final int libraryPosition2 = sa.hasParam("LibraryPosition2") ? Integer.parseInt(sa.getParam("LibraryPosition2")) : -1;
String changeValid = sa.hasParam("ChangeValid") ? sa.getParam("ChangeValid") : ""; String changeValid = sa.getParamOrDefault("ChangeValid", "");
boolean chooseOptional = sa.hasParam("Optional"); boolean chooseOptional = sa.hasParam("Optional");
CardZoneTable table = new CardZoneTable(); CardZoneTable table = new CardZoneTable();

View File

@@ -60,7 +60,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
} }
final boolean noCall = sa.hasParam("NoCall"); final boolean noCall = sa.hasParam("NoCall");
String varName = sa.hasParam("SaveNumFlipsToSVar") ? sa.getParam("SaveNumFlipsToSVar") : "X"; String varName = sa.getParamOrDefault("SaveNumFlipsToSVar", "X");
boolean victory = false; boolean victory = false;
int amount = 1; int amount = 1;
if (sa.hasParam("Amount")) { if (sa.hasParam("Amount")) {

View File

@@ -27,7 +27,7 @@ public class ManifestEffect extends SpellAbilityEffect {
final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(source, final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(source,
sa.getParam("Amount"), sa) : 1; sa.getParam("Amount"), sa) : 1;
// Most commonly "defined" is Top of Library // Most commonly "defined" is Top of Library
final String defined = sa.hasParam("Defined") ? sa.getParam("Defined") : "TopOfLibrary"; final String defined = sa.getParamOrDefault("Defined", "TopOfLibrary");
CardCollectionView lastStateBattlefield = game.copyLastStateBattlefield(); CardCollectionView lastStateBattlefield = game.copyLastStateBattlefield();
CardCollectionView lastStateGraveyard = game.copyLastStateGraveyard(); CardCollectionView lastStateGraveyard = game.copyLastStateGraveyard();

View File

@@ -31,12 +31,8 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
String valid = "";
String piles = sa.getParam("Piles"); String piles = sa.getParam("Piles");
if (sa.hasParam("ValidCards")) { final String valid = sa.getParamOrDefault("ValidCards", "");
valid = sa.getParam("ValidCards");
}
sb.append("Separate all ").append(valid).append(" cards "); sb.append("Separate all ").append(valid).append(" cards ");
@@ -58,10 +54,7 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
final int piles = Integer.parseInt(sa.getParam("Piles")); final int piles = Integer.parseInt(sa.getParam("Piles"));
final Map<Player, List<CardCollectionView>> record = Maps.newHashMap(); final Map<Player, List<CardCollectionView>> record = Maps.newHashMap();
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);

View File

@@ -37,8 +37,8 @@ public class PeekAndRevealEffect extends SpellAbilityEffect {
Card source = sa.getHostCard(); Card source = sa.getHostCard();
final boolean rememberRevealed = sa.hasParam("RememberRevealed"); final boolean rememberRevealed = sa.hasParam("RememberRevealed");
final boolean imprintRevealed = sa.hasParam("ImprintRevealed"); final boolean imprintRevealed = sa.hasParam("ImprintRevealed");
String revealValid = sa.hasParam("RevealValid") ? sa.getParam("RevealValid") : "Card"; String revealValid = sa.getParamOrDefault("RevealValid", "Card");
String peekAmount = sa.hasParam("PeekAmount") ? sa.getParam("PeekAmount") : "1"; String peekAmount = sa.getParamOrDefault("PeekAmount", "1");
int numPeek = AbilityUtils.calculateAmount(sa.getHostCard(), peekAmount, sa); int numPeek = AbilityUtils.calculateAmount(sa.getHostCard(), peekAmount, sa);
// Right now, this is only used on your own library. // Right now, this is only used on your own library.

View File

@@ -82,10 +82,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
} }
// Deal with permanents // Deal with permanents
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
if (!valid.equals("")) { if (!valid.equals("")) {
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield); CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, valid, sa.getActivatingPlayer(), host, sa); list = CardLists.getValidCards(list, valid, sa.getActivatingPlayer(), host, sa);
@@ -113,10 +110,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
} }
// Deal with Players // Deal with Players
String players = ""; final String players = sa.getParamOrDefault("ValidPlayers", "");
if (sa.hasParam("ValidPlayers")) {
players = sa.getParam("ValidPlayers");
}
if (!players.equals("")) { if (!players.equals("")) {
final List<Player> playerList = AbilityUtils.getDefinedPlayers(host, players, sa); final List<Player> playerList = AbilityUtils.getDefinedPlayers(host, players, sa);
for (final Player player : playerList) { for (final Player player : playerList) {

View File

@@ -137,10 +137,7 @@ public class PumpAllEffect extends SpellAbilityEffect {
list = tgtPlayers.getCardsIn(affectedZones); list = tgtPlayers.getCardsIn(affectedZones);
} }
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
list = AbilityUtils.filterListByType(list, valid, sa); list = AbilityUtils.filterListByType(list, valid, sa);

View File

@@ -26,11 +26,7 @@ public class RegenerateAllEffect extends RegenerateBaseEffect {
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final Card hostCard = sa.getHostCard(); final Card hostCard = sa.getHostCard();
final Game game = hostCard.getGame(); final Game game = hostCard.getGame();
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield); CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa); list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa);

View File

@@ -76,11 +76,7 @@ public class RepeatEffect extends SpellAbilityEffect {
if (sa.hasParam("RepeatPresent")) { if (sa.hasParam("RepeatPresent")) {
final String repeatPresent = sa.getParam("RepeatPresent"); final String repeatPresent = sa.getParam("RepeatPresent");
String repeatCompare = sa.getParamOrDefault("RepeatCompare", "GE1");
String repeatCompare = "GE1";
if (sa.hasParam("RepeatCompare")) {
repeatCompare = sa.getParam("RepeatCompare");
}
CardCollectionView list; CardCollectionView list;
if (sa.hasParam("RepeatDefined")) { if (sa.hasParam("RepeatDefined")) {

View File

@@ -243,7 +243,6 @@ public class SacrificeEffect extends SpellAbilityEffect {
removeCandidates(validTargets, validTargetsList, union, index + 1, included, amount); removeCandidates(validTargets, validTargetsList, union, index + 1, included, amount);
CardCollection candidate = validTargetsList.get(index); CardCollection candidate = validTargetsList.get(index);
if (candidate.isEmpty()) { if (candidate.isEmpty()) {
return; return;

View File

@@ -28,8 +28,7 @@ public class TapOrUntapAllEffect extends SpellAbilityEffect {
if (sa.hasParam("ValidMessage")) { if (sa.hasParam("ValidMessage")) {
sb.append(sa.getParam("ValidMessage")); sb.append(sa.getParam("ValidMessage"));
} } else {
else {
final List<Card> tgtCards = getTargetCards(sa); final List<Card> tgtCards = getTargetCards(sa);
sb.append(StringUtils.join(tgtCards, ", ")); sb.append(StringUtils.join(tgtCards, ", "));
} }

View File

@@ -26,10 +26,7 @@ public class TwoPilesEffect extends SpellAbilityEffect {
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
String valid = ""; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
sb.append("Separate all ").append(valid).append(" cards "); sb.append("Separate all ").append(valid).append(" cards ");
@@ -54,10 +51,7 @@ public class TwoPilesEffect extends SpellAbilityEffect {
zone = ZoneType.smartValueOf(sa.getParam("Zone")); zone = ZoneType.smartValueOf(sa.getParam("Zone"));
} }
String valid = "Card"; final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);

View File

@@ -24,15 +24,9 @@ public class UntapAllEffect extends SpellAbilityEffect {
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final Card card = sa.getHostCard(); final Card card = sa.getHostCard();
String valid = "";
CardCollectionView list; CardCollectionView list;
List<Player> tgtPlayers = getTargetPlayers(sa); List<Player> tgtPlayers = getTargetPlayers(sa);
final String valid = sa.getParamOrDefault("ValidCards", "");
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
if (!sa.usesTargeting() && !sa.hasParam("Defined")) { if (!sa.usesTargeting() && !sa.hasParam("Defined")) {
list = sa.getActivatingPlayer().getGame().getCardsIn(ZoneType.Battlefield); list = sa.getActivatingPlayer().getGame().getCardsIn(ZoneType.Battlefield);

View File

@@ -213,7 +213,7 @@ public final class LayoutMenu {
private static ActionListener getSetWindowSizeAction() { private static ActionListener getSetWindowSizeAction() {
return new ActionListener() { return new ActionListener() {
@Override public void actionPerformed(final ActionEvent e) { @Override public void actionPerformed(final ActionEvent e) {
final String[] options = {"800x600", "1024x768", "1280x720"}; final String[] options = {"800x600", "1024x768", "1280x720", "1600x900", "1920x1080", "2560x1440", "3840x2160"};
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
final String choice = GuiChoose.oneOrNone(localizer.getMessage("lblChooseNewWindowSize"), options); final String choice = GuiChoose.oneOrNone(localizer.getMessage("lblChooseNewWindowSize"), options);
if (choice != null) { if (choice != null) {

View File

@@ -0,0 +1,26 @@
Name:Hawkins National Laboratory
ManaCost:no cost
Types:Legendary Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Investigate | Cost$ 4 T | SpellDescription$ Investigate.
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ ClueResearch | SVarCompare$ GE3 | Execute$ TrigTransform | TriggerDescription$ At the beginning of your end step, if you sacrificed three or more clues this turn, transform CARDNAME.
SVar:TrigTransform:DB$ SetState | Defined$ Self | Mode$ Transform
SVar:ClueResearch:Count$SacrificedThisTurn Clue
AlternateMode:DoubleFaced
DeckHints:Ability$Investigate
DeckHas:Ability$Investigate & Ability$Token & Ability$Sacrifice
Oracle:{T}: Add {C}.\n{4}, {T}: Investigate.\nAt the beginning of your end step, if you sacrificed three or more clues this turn, transform Hawkins National Laboratory.
ALTERNATE
Name:The Upside Down
ManaCost:no cost
Types:Legendary Land
T:Mode$ Transformed | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When this land transforms into CARDNAME, return target creature card from your graveyard to the battlefield.
SVar:TrigReturn:DB$ ChangeZone | ValidTgts$ Creature.YouOwn | TgtPrompt$ Select target creature card from your graveyard | Origin$ Graveyard | Destination$ Battlefield | RememberTargets$ True
T:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Battlefield | Destination$ Any | Execute$ TrigTransform2 | TriggerZones$ Battlefield | TriggerDescription$ When the creature card put onto the battlefield with CARDNAME leaves the battlefield, transform CARDNAME.
SVar:TrigTransform2:DB$ SetState | Defined$ Self | Mode$ Transform | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ Mana | Cost$ T PayLife<1> | Produced$ B | SpellDescription$ Add {B}.
DeckHas:Ability$Graveyard
Oracle:When this land transforms into The Upside Down, return target creature card from your graveyard to the battlefield.\nWhen the creature card put onto the battlefield with The Upside Down leaves the battlefield, transform The Upside Down.\n{T}, Pay 1 life: Add {B}.

View File

@@ -168,7 +168,7 @@ nlRemoveSmall=Verhindert 1/1- und 0/X-Kreaturen in erzeugten Decks
nlSingletons=Verhindert Duplikate von Nicht-Landkarten in erzeugten Decks nlSingletons=Verhindert Duplikate von Nicht-Landkarten in erzeugten Decks
nlRemoveArtifacts=Verhindert Artefakte in erzeugten Decks nlRemoveArtifacts=Verhindert Artefakte in erzeugten Decks
nlCardBased=Erzeugt stimmigere zufällig erzeugte Decks (Erfordert Neustart) nlCardBased=Erzeugt stimmigere zufällig erzeugte Decks (Erfordert Neustart)
DeckEditorOptions=Deck Editor Optionen DeckEditorOptions=Deck-Editor-Optionen
nlFilterLandsByColorId=Macht es einfacher die richtigen Länder zu finden, wenn Farbfilter genutzt werden. nlFilterLandsByColorId=Macht es einfacher die richtigen Länder zu finden, wenn Farbfilter genutzt werden.
AdvancedSettings=Erweiterte Optionen AdvancedSettings=Erweiterte Optionen
nlDevMode=Ativiert ein Menü mit Funktionen, welche das Testen vereinfachen. nlDevMode=Ativiert ein Menü mit Funktionen, welche das Testen vereinfachen.
@@ -466,7 +466,7 @@ lblBrawlDesc=Jeder Spieler hat eine legendäre \"General\"-Karte, welche (fast)
lblPlaneswalker=Planeswalker lblPlaneswalker=Planeswalker
lblPlaneswalkerDesc=Jeder Spieler hat eine Planeswalker-Karte, welche (fast) jederzeit gespielt werden kann. lblPlaneswalkerDesc=Jeder Spieler hat eine Planeswalker-Karte, welche (fast) jederzeit gespielt werden kann.
lblPlanechase=Weltenjagd lblPlanechase=Weltenjagd
lblPlanechaseDesc=Weltenkarten haben globale Effekte. Wenn ein Spieler auf dem Weltenwürfel \"Planeswalk\"wirft, wechselt die Weltenkarte. lblPlanechaseDesc=Weltenkarten haben globale Effekte. Wenn ein Spieler auf dem Weltenwürfel \"Planeswalk\" wirft, wechselt die Weltenkarte.
lblArchenemyDesc=Ein Spieler ist der Erzfeind und kämpft gegen die anderen Spieler. Er hat Komplottkarten.\nEiner gegen alle. lblArchenemyDesc=Ein Spieler ist der Erzfeind und kämpft gegen die anderen Spieler. Er hat Komplottkarten.\nEiner gegen alle.
lblArchenemyRumble=Erzfeind Rumble lblArchenemyRumble=Erzfeind Rumble
lblArchenemyRumbleDesc=Alle Spieler sind Erzfeinde und haben Komplottkarten.\nJeder gegen jeden. lblArchenemyRumbleDesc=Alle Spieler sind Erzfeinde und haben Komplottkarten.\nJeder gegen jeden.
@@ -1355,7 +1355,7 @@ lblRemoveCardBelongingWitchPlayer=Entferne Karte(n) von welchem Spielers?
lblRemoveCardFromWhichZone=Entferne Karte(n) aus welcher Zone? lblRemoveCardFromWhichZone=Entferne Karte(n) aus welcher Zone?
lblChooseCardsRemoveFromGame=Welche Karten aus dem Spiel entfernen? lblChooseCardsRemoveFromGame=Welche Karten aus dem Spiel entfernen?
lblRemoved=Entfernt lblRemoved=Entfernt
lblEnterASequence=Gib Abfolge ein (Karten-ID und/oder "opponen"/"me"(z.B. 7, opponent, 18)). lblEnterASequence=Gib Abfolge ein (Karten-ID und/oder "opponent"/"me"(z.B. 7, opponent, 18)).
lblActionSequenceCleared=Aktion gelöscht lblActionSequenceCleared=Aktion gelöscht
lblRestartingActionSequence=Starte Aktion neu. lblRestartingActionSequence=Starte Aktion neu.
lblErrorPleaseCheckID=Fehler: Prüfe IDs und ob sie durch Leerzeichen und/oder Kommas getrennt sind. lblErrorPleaseCheckID=Fehler: Prüfe IDs und ob sie durch Leerzeichen und/oder Kommas getrennt sind.
@@ -2636,95 +2636,90 @@ lblTargetingArcsAlwaysOn=Zielpfleile: Immer an
#ListCardArea.java #ListCardArea.java
lblDone=Fertig lblDone=Fertig
#DeckImport.java #DeckImport.java
lblDeckImporterPanelTitle=Deck Importer - {0} lblDeckImporterPanelTitle=Deck-Importer - {0}
ttUseOnlySetsReleasedBefore=Use in combination with Card Art Preference ttUseOnlySetsReleasedBefore=In Kombination mit bevorzugtem Kartenbild nutzen
nlUseOnlySetsReleasedBefore=Filter card editions by release date nlUseOnlySetsReleasedBefore=Filtere Karten-Editionen nach Erscheinungsdatum
lblUseFormatFilter=Choose a Format for the Decklist lblUseFormatFilter=Wähle ein Format für die Deckliste
lblIgnoreBnR=Also import Banned and Restricted Cards lblIgnoreBnR=Importiere auch gebannte und eingeschränkte Karten
ttIgnoreBnR=If activated, any Banned or Restricted Card will be also imported in the Deck. ttIgnoreBnR=Wenn aktiviert, erden auch gebannte oder eingeschränkte Karten ins Deck importiert.
nlIgnoreBnR=Warning: The Deck may not be playable if Deck Conformance is enabled. nlIgnoreBnR=Warnung: Das Deck kann bei eingeschalteter Deckkonkonformität nicht spielbar sein.
lblExtraOptions=Show Options lblExtraOptions=Zeige Optionen
lblHideOptions=Hide Options lblHideOptions=Verstecke Optionen
lblCardPreview=Card Preview lblCardPreview=Karten-Vorschau
lblCardListTitle=Card List lblCardListTitle=Karten-Liste
lblDecklistTitle=Decklist lblDecklistTitle=Deckliste
lblSummaryStats=Summary Statistics lblSummaryStats=Gesamt-Statistik
lblDeckSection=Section lblDeckSection=Bereich
lblNewDeckCheckbox=Create a New Deck lblNewDeckCheckbox=Erzeuge ein neues Deck
lblImportCardsCmd=Import Cards lblImportCardsCmd=Importiere Karten
lblCreateNewCmd=New Deck lblCreateNewCmd=Neues Deck
lblErrNotAllowedCard=Set not allowed in {0} lblErrNotAllowedCard=Set ist nicht erlaubt in {0}
lblWarnLimitedCard={0} in {1} lblWarnLimitedCard={0} in {1}
lblErrCardEditionDate=Set not compliant with Release Date option lblErrCardEditionDate=Set verträgt sich nicht mit der Erscheinungsdatum-Option
lblErrUnsupportedCard=Not allowed in {0} lblErrUnsupportedCard=Ist nicht erlaubt in {0}
lblWarnUnknownCardMsg=Unknown Card or Unsupported in Forge lblWarnUnknownCardMsg=Unbekannte oder in Forge nicht unterstützte Karte
lblWarnTooManyCommanders=Current {0} Section contains {1} potential Commander Cards: {2} lblWarnTooManyCommanders=Aktueller {0}-Bereich enthält {1} mögliche Commander-Karten: {2}
lblWarnCommandersInSideExtra=Please check and move one to the Commander Section, in case. lblWarnCommandersInSideExtra=Bitte prüfen und, falls nötig, min. eine Karte in den Commander-Bereich verschieben.
lblWarnDeckSectionNotAllowedInEditor={0} Section is not allowed in {1} lblWarnDeckSectionNotAllowedInEditor=In {1} ist der {0}-Bereich nicht erlaubt.
lblWarnCardInInvalidSection={0} moved from {1} to {2}. lblWarnCardInInvalidSection={0} wurde verschoben von {1} nach {2}.
lblWarningMsgPrefix=WARNING lblWarningMsgPrefix=WARNUNG
lblNewDeckName=New Deck lblNewDeckName=Neues Deck
lblCurrentDecklist=Current Decklist lblCurrentDecklist=Aktuelle Deckliste
lblDeckName=Deck Name lblDeckName=Deck-Name
nlGuideTitle=Quick Instructions nlGuideTitle=Kurz-Anleitung
nlGuideQuickInstructions=To start using the Deck Importer just type or paste the names of the \ nlGuideQuickInstructions=Um den Deck-Importer zu nutzen tippe oder kopiere den (englischen) Namen einer Karte (eine pro Zeile) in die \
cards you want in the Card List (one per line). The Card list can contain either a few spare cards, \ Kartenliste ein. Die Kartenliste kann entweder einige beliebige Karten, oder ein ganzes Deck in einem der beliebten M:TG-Formate enthalten \
or a full deck in one of the most popular M:TG formats (Please see below the list of supported Deck formats). \n \ (Eine Liste der unterstützten Formate findet sich unten). \n \
Each line in the Card list is processed immediately, and any recognized entry will appear in the Decklist in one \ Jede Zeile wird umgehend verarbeitet, und jeder erkannte Eintrag erscheint in der Deckliste in einer der folgenden Farben: {0}
of the following colors: {0} lblGuideImportCard=Karte wurde erfolgreich erkannt und ist fertig zum Übernehmen.
lblGuideImportCard=Card successfully recognized and ready to be imported. lblGuideWarnMessage=Unbekannte oder eingeschränkte Karte (steht auf der Bann- o. Beschränkungsliste), oder generälle Warnung.
lblGuideWarnMessage=Unknown or Limited Card (i.e. Banned or Restricted), or general warning message. lblGuideNoImportCard=Ungültige oder nicht unterstützte Karte, welche nicht übernommen werden kann.
lblGuideNoImportCard=Invalid or Unsupported Card that cannot be imported. nlGuideTipsTitle=Importer-Optionen und Anpassungen
nlGuideTipsTitle=Importer Options and Customizations nlGuideTipsText=Bitte lese diesen Abschnitt, wenn du mehr über die Möglicjkeiten wissen willst, wie der Importer deine Deckliste bearbeiten \
nlGuideTipsText=Please read this section if you want to know the many ways the Deck Importer allows to refine and organize \ und organisieren kann. \n {0}
your Decklist. \n {0} lblGuideTipsTitleCount=Karten-Anzahl
lblGuideTipsTitleCount=Card Amount lblGuideTipsCount={0}: Stelle jeder Karte die zu importierende Anzahl voran (Vorgabe: 1). \n\
lblGuideTipsCount={0}: Prepend to each card line the number of copies to import (default: 1). \n\ Zum Beispiel sind {1} und {2} beides akzeptierte Einträge.
For example, both {1} and {2} are accepted entries. lblGuideTipsTitleSet=Kartenbild
lblGuideTipsTitleSet=Card Art lblGuideTipsSet={0}: Gebe den Code eines M:TG-Sets (direkt vor oder nach dem Kartennamen) an, um ein spezielles Kartenbild zu wählen. \
lblGuideTipsSet={0}: Specify the code of an M:TG set (right before or right after card name) to choose a \ Außerdem gib die Sammlernummer oder eine Bild-Versionsnummer an, falls mehrere Bildversionen einer Karte im Set existieren \
specific card art. Also add card collector number or the art index at the end of the line, if the chosen \ (weitere Beispiele unten).
set has multiple arts for the same card (See more examples below). lblGuideTipsTitleFoil=Foil-Karten
lblGuideTipsTitleFoil=Foil Cards lblGuideTipsFoil={0}: Jede Karte endend mit "+" wird als Foil importiert, z.B. {1}. Anhängen des {2}-Symbols am Ende der Kartenzeile \
lblGuideTipsFoil={0}: Any card name ending with the "+" sign will be imported foiled, e.g. {1}. Alternatively, \ (üblich in einigen beliebten Deck-Formaten) bewirkt das Gleiche (siehe Beispiele unten).
appending the {2} symbol at the end of card line (as it is customary in some M:TG deck formats) will \ lblGuideTipsTitlePlaceholder=Karten-Gruppierung
do the same (Please see the Examples Section below). lblGuideTipsPlaceholder={0}: Spezielle Schlüsselwörter können zur Organisation der Deckliste genutzt werden. Sie können \
lblGuideTipsTitlePlaceholder=Card Groups Kartentypen (z.B. {1}), Seltenheit (z.B. {2}), Manakosten (z.B. {3}), or Manafarben (z.B. {4}) sein.
lblGuideTipsPlaceholder={0}: Special placeholder keywords can be used to organize the Card list. They can be either \ lblGuideTipsTitleDeckSections=Deck-Bereiche
Core Card Types (e.g. {1}), Card Rarity (i.e. {2}), Mana Cost (e.g. {3}), or Mana Colors (e.g. {4}). lblGuideTipsDeckSection={0}: Genauso wie Grupierungen kann die Kartenliste in Bereiche eingeteilt werden \
lblGuideTipsTitleDeckSections=Deck Sections (z.B. {1}), welche der Importer nutzt, um die Karten im Deck zuzuweisen (Vorgabe: {2}). \
lblGuideTipsDeckSection={0}: Similar to Card Groups, the Card list can also be organized in Deck Sections \ Aus diesem Grund nutzt der Importer eine automatische Gegenprüfung der Karten in den Bereichen um das Risiko von Fehler zu verringern.
(e.g. {1}), that will also used by the Importer to assign cards in the deck (default: {2}). \ lblGuideTipsTitleDeckName=Deck-Name
For this reason, the Importer also integrates an automated validation of cards in sections to \ lblGuideTipsDeckName={0}: Um dem Deck einen Namen zuzuweisen, gib "Deck:" oder "Name:" ein, gefolgt vom gewünschten Namen des Decks.
reduce the risk of errors. lblGuideTipsTitleDeckFormat=Deck-Formate
lblGuideTipsTitleDeckName=Deck Name lblGuideTipsDeckFormats={0}: Diverse M:TG-Deckformate werden unterstützt: MTG Arena, \
lblGuideTipsDeckName={0}: Assign a name to your Deck. Just type "Deck:" or "Name:", followed by the name \ MTGO, XMage, MTG Goldfish (alle Exporte); TappedOut (alle Exporte, außer CSV); DeckStats.net; ".dec"-Dateien.
to assign to the deck. nlGuideExamplesTitle=Beispiele
lblGuideTipsTitleDeckFormat=Deck Formats
lblGuideTipsDeckFormats={0}: Several M:TG deck formats are supported: MTG Arena; \
MTGO, XMage, MTG Goldfish (all export); TappedOut (all export, but CSV); DeckStats.net; ".dec" files.
nlGuideExamplesTitle=Examples
lblExample1=10x Islands+ MIR 2 lblExample1=10x Islands+ MIR 2
nlExample1=10 FOIL "Island" from Set "Mirage", Art Index 2\. nlExample1=10 FOIL "Insel" vom Set "Trugbilder", Bildversion 2\.
lblExample2=4 Darksteel Citadel (M15) 242 lblExample2=4 Darksteel Citadel (M15) 242
nlExample2=4 "Darksteel Citadel" from "M15", Collector Nr. "242".\n\n \ nlExample2=4 "Nachtstahl-Zitadelle" von "M15", Sammlernummer "242".\n\n \
This is an exemplar entry in MTGArena format as exported by TappedOut. Dies ist ein Beispieleintrag im MTGArena-Format exportiert von TappedOut.
lblExample3=18 Forest &lt;254&gt; [THB] (F) lblExample3=18 Forest &lt;254&gt; [THB] (F)
nlExample3=18 FOIL "Forest" from "THB", Collector Nr. "254".\n\n \ nlExample3=18 FOIL "Wald" von "THB", Sammlernummer "254".\n\n \
This is an exemplar entry in MTGArena deck format as exported by MTGGoldfish. \ Dies ist ein Beispielentrag im MTGArena-Deckformat exportiert von MTGGoldfish. \
The "(F)" in the end denotes a foil card, and the Collector Number in angular brackets is \ Das "(F)" am Ende bezeichnet eine Foil-Karte, und die Sammlernummer in gewinkelten Klammern wird genutzt eine \
is used to select a specific Card Art). bestimmte Kartenbildversion zu wählen.
lblExample4=4x TMP|Counterspell lblExample4=4x TMP|Counterspell
nlExample4=4 copies of "Counterspell" from "Tempest".\n\n \ nlExample4=4 Kopien von "Gegenzauber" von "Sturmwind".\n\n \
In this entry, the Set code is specified before the card name using the (optional) pipe separator.\ In diesem Eintrag wird der Set-Code vor dem Kartennamen unter Nutzung des (optionalen) Trenners Pipe.\
Alternative valid separators for set codes are braces, brackets, and parenthesis. Andere gültige Trenner für Set-Codes sind geschweifte, eckige und runde Klammern.
lblExample5=SB: 2 [M19:28] Mighty Leap lblExample5=SB: 2 [M19:28] Mighty Leap
nlExample5=2 copies of "Mighty Leap" from "M19", Collector Nr. "28" to be added in "Sideboard".\n\n \ nlExample5=2 Kopien von "Mächtiger Sprung" von "M19", Sammlernummer "28" werden dem "Sideboard" zugeordnet.\n\n \
This is an exemplar entry in XMage deck format. In this format, the Set code and the Collector Number are \ Dies ist ein Beispieleintrag im XMage-Deckformat. In diesem Format sind der Set-Code und die Sammlernummer durch einen Doppelpunkt \
column-separated, and specified in brackets right before card name. \ getrennt, werden direkt vor dem Kartennamen in eckigen Klammern angegeben. \
Moreover, an optional Prefix (i.e. SB:) is used to denote the Deck Section where the card should be added to. \ Zusätzlich wird ein optionaler Prefix (z.B. SB:) genutzt um den gewünschten Bereich für die Karte anzugeben. \
The Deck Importer in Forge further extends this idea by also adding support to two extra prefixes, i.e. "MB:" and \ Der Deck-Importer in Forge unterstützt zwei weitere Prefixe, z.B. "MB:" und "CM:" für den "Haupt-" und den "Commander-"Bereich.
"CM:" as for "Main" and "Commander" Section, respectively.
#CEditorTokenViewer.java #CEditorTokenViewer.java
lblAllTokens=Alle Spielsteine lblAllTokens=Alle Spielsteine
#StartRenderer.java #StartRenderer.java
@@ -2748,14 +2743,14 @@ htmlPhaseCleanupTooltip=<html>Phase: Aufräumen<br>Klicke zum Umschalten.</html>
lblSideboardForPlayer=Sideboard für {0} lblSideboardForPlayer=Sideboard für {0}
lblOtherInteger=Andere... lblOtherInteger=Andere...
#DeckImportController.java #DeckImportController.java
lblConfirmCardImport=You are about to merge the Decklist in the {0} deck.{1}\n\nWould you like to proceed?\n\n Note: \ lblConfirmCardImport=Du bist dabei die Deckliste ins {0}-Deck einzufügen.{1}\n\nWillst du fortfahren?\n\n Hinweis: \
Please remember to click on the "Save" button in the Deck Editor to finalize the changes to current deck! Bitte denk daran den "Save"-Knopf im Deck-Editor zu klicken, um die Änderungen am aktuellen Deck zu bestätigen!
lblCardImportWarning=\nWarning: The deck {0} will be renamed as {1}. lblCardImportWarning=\nWarnung: Das Deck {0} wird umbenannt in {1}.
lblConfirmCreateNewDeck=You are about to create a new deck {0}. {1}\n\nWould you like to proceed?\n\n Note: \ lblConfirmCreateNewDeck=Du bist dabei das neue Deck {0} zu erzeugen. {1}\n\nWillst du fortfahren?\n\n Hinweis: \
Please remember to click on the "Save" button in the Deck Editor to add the new deck to the Catalog! Bitte denk daran den "Save"-Knopf im Deck-Editor zu klicken, um das neue Deck dem Deck-Katalog hinzuzufügen!
lblNewDeckWarning=\nWarning: Any unsaved changes to the current deck {0} will be lost. lblNewDeckWarning=\nWarnung: Alle ungesicherten Änderungen am aktuellen Deck {0} werden verlorengehen.
lblImportCardsDialogTitle=Import cards in the Current Deck lblImportCardsDialogTitle=Importiere Karten in aktuelles Deck
lblNewDeckDialogTitle=Create a New Deck lblNewDeckDialogTitle=Erzeuge neues Deck
#FNetOverlay.java #FNetOverlay.java
lblChat=Chat lblChat=Chat
lblSend=Senden lblSend=Senden

View File

@@ -16,6 +16,7 @@ import forge.gamemodes.quest.data.QuestPreferences;
import forge.gamemodes.tournament.system.TournamentBracket; import forge.gamemodes.tournament.system.TournamentBracket;
import forge.gamemodes.tournament.system.TournamentPairing; import forge.gamemodes.tournament.system.TournamentPairing;
import forge.gamemodes.tournament.system.TournamentPlayer; import forge.gamemodes.tournament.system.TournamentPlayer;
import forge.gui.FThreads;
import forge.gui.GuiBase; import forge.gui.GuiBase;
import forge.gui.interfaces.IGuiGame; import forge.gui.interfaces.IGuiGame;
import forge.gui.util.SGuiChoose; import forge.gui.util.SGuiChoose;
@@ -406,10 +407,15 @@ public class QuestTournamentController {
drafting = true; drafting = true;
final BoosterDraft draft = draftEvent.enter(); final BoosterDraft draft = draftEvent.enter();
FThreads.invokeInEdtLater(new Runnable() {
@Override
public void run() {
view.startDraft(draft); view.startDraft(draft);
} }
}); });
} }
});
}
public boolean cancelDraft() { public boolean cancelDraft() {
if (SOptionPane.showConfirmDialog(localizer.getMessage("lblLeaveDraftConfirm"), localizer.getMessage("lblLeaveDraft") + "?", localizer.getMessage("lblLeave"), localizer.getMessage("lblCancel"), false)) { if (SOptionPane.showConfirmDialog(localizer.getMessage("lblLeaveDraftConfirm"), localizer.getMessage("lblLeaveDraft") + "?", localizer.getMessage("lblLeave"), localizer.getMessage("lblCancel"), false)) {

View File

@@ -102,8 +102,7 @@ public abstract class AchievementCollection implements Iterable<Achievement> {
add(new TotalMatchWins(100, 250, 500, 1000)); add(new TotalMatchWins(100, 250, 500, 1000));
if (isLimitedFormat) { //make need for speed goal more realistic for limited formats if (isLimitedFormat) { //make need for speed goal more realistic for limited formats
add(new NeedForSpeed(8, 6, 4, 2)); add(new NeedForSpeed(8, 6, 4, 2));
} } else {
else {
add(new NeedForSpeed(5, 3, 1, 0)); add(new NeedForSpeed(5, 3, 1, 0));
} }
add(new Overkill(-25, -50, -100, -200)); add(new Overkill(-25, -50, -100, -200));
@@ -114,8 +113,7 @@ public abstract class AchievementCollection implements Iterable<Achievement> {
add(new ManaScrewed()); add(new ManaScrewed());
if (isLimitedFormat) { //lower gold and mythic thresholds based on smaller decks if (isLimitedFormat) { //lower gold and mythic thresholds based on smaller decks
add(new ManaFlooded(8, 11, 14, 17)); add(new ManaFlooded(8, 11, 14, 17));
} } else {
else {
add(new ManaFlooded(8, 12, 18, 24)); add(new ManaFlooded(8, 12, 18, 24));
} }
add(new RagsToRiches()); add(new RagsToRiches());