* Fixed more possible endless loops of while iterations not ending if a asked player left game.

This commit is contained in:
LevelX2 2014-06-05 23:18:39 +02:00
parent 6b817b0669
commit 53b8f1977a
67 changed files with 170 additions and 160 deletions

View file

@ -121,7 +121,7 @@ class ArchitectsOfWillEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of target player's library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of target player's library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (you.isInGame() && cards.size() > 1) {
you.choose(Outcome.Neutral, cards, target, game); you.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -111,7 +111,7 @@ class DefilerOfSoulsEffect extends OneShotEffect {
//had, if thats the case this ability should fizzle. //had, if thats the case this ability should fizzle.
if (amount > 0 && target.canChoose(source.getSourceId(), player.getId(), game)) { if (amount > 0 && target.canChoose(source.getSourceId(), player.getId(), game)) {
boolean abilityApplied = false; boolean abilityApplied = false;
while (!target.isChosen() && target.canChoose(player.getId(), game)) { while (player.isInGame() && !target.isChosen() && target.canChoose(player.getId(), game)) {
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
} }

View file

@ -123,7 +123,7 @@ class SagesOfTheAnimaReplacementEffect extends ReplacementEffectImpl {
} }
TargetCard target = new TargetCard(Zone.PICK, new FilterCard()); TargetCard target = new TargetCard(Zone.PICK, new FilterCard());
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -126,7 +126,7 @@ class GoblinRingleaderEffect extends OneShotEffect {
} }
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards2.size() > 0 && player.choose(Outcome.Detriment, cards2, target, game)) { while (player.isInGame() && cards2.size() > 0 && player.choose(Outcome.Detriment, cards2, target, game)) {
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
cards2.remove(card); cards2.remove(card);

View file

@ -132,7 +132,7 @@ class SylvanMessengerEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards2.size() > 0 && player.choose(Outcome.Detriment, cards2, target, game)) { while (player.isInGame() && cards2.size() > 0 && player.choose(Outcome.Detriment, cards2, target, game)) {
Card card = cards2.get(target.getFirstTarget(), game); Card card = cards2.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
cards2.remove(card); cards2.remove(card);

View file

@ -124,7 +124,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
return false; return false;
} }
while (player.chooseUse(Outcome.Benefit, "Attach an Aura from the battlefield?", game)) { while (player.isInGame() && player.chooseUse(Outcome.Benefit, "Attach an Aura from the battlefield?", game)) {
Target targetAura = new TargetPermanent(filterAura); Target targetAura = new TargetPermanent(filterAura);
if (player.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) { if (player.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) {
Permanent aura = game.getPermanent(targetAura.getFirstTarget()); Permanent aura = game.getPermanent(targetAura.getFirstTarget());
@ -139,7 +139,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
} }
int count = player.getHand().count(filterAuraCard, game); int count = player.getHand().count(filterAuraCard, game);
while (count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", game)) { while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", game)) {
TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) { if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());
@ -153,7 +153,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
} }
count = player.getGraveyard().count(filterAuraCard, game); count = player.getGraveyard().count(filterAuraCard, game);
while (count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", game)) { while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", game)) {
TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) { if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());

View file

@ -115,7 +115,7 @@ class DescentIntoMadnessEffect extends OneShotEffect {
private void exileCards(Player player, int count, Ability source, Game game) { private void exileCards(Player player, int count, Ability source, Game game) {
int amount = Math.min(count, player.getHand().size() + game.getBattlefield().getAllActivePermanents(player.getId()).size()); int amount = Math.min(count, player.getHand().size() + game.getBattlefield().getAllActivePermanents(player.getId()).size());
while (amount > 0) { while (player.isInGame() && amount > 0) {
Target target = new TargetControlledPermanent(0, 1, filter, true); Target target = new TargetControlledPermanent(0, 1, filter, true);
if (target.canChoose(player.getId(), game) if (target.canChoose(player.getId(), game)
&& player.choose(Outcome.Exile, target, source.getSourceId(), game)) { && player.choose(Outcome.Exile, target, source.getSourceId(), game)) {

View file

@ -109,7 +109,7 @@ class LairDelveEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -96,7 +96,7 @@ class PrimalSurgeEffect extends OneShotEffect {
if (player.getLibrary().size() > 0) { if (player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
card.moveToExile(null, "", source.getId(), game); card.moveToExile(null, "", source.getSourceId(), game);
List<CardType> cardType = card.getCardType(); List<CardType> cardType = card.getCardType();
if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE) if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE)
|| cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND) || cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND)
@ -114,7 +114,7 @@ class PrimalSurgeEffect extends OneShotEffect {
} }
} }
} }
} while (repeat); } while (player.isInGame() && repeat);
return true; return true;
} }

View file

@ -93,22 +93,22 @@ class RiteOfRuinEffect extends OneShotEffect {
return false; return false;
} }
HashSet<String> choices = new HashSet<String>(); HashSet<String> choices = new HashSet<>();
choices.add("Artifacts"); choices.add("Artifacts");
choices.add("Creatures"); choices.add("Creatures");
choices.add("Lands"); choices.add("Lands");
LinkedList<CardType> order = new LinkedList<CardType>(); LinkedList<CardType> order = new LinkedList<>();
ChoiceImpl choice = new ChoiceImpl(true); ChoiceImpl choice = new ChoiceImpl(true);
choice.setChoices(choices); choice.setChoices(choices);
while (controller.choose(Outcome.Sacrifice, choice, game) && choices.size() > 1) { while (controller.isInGame() && controller.choose(Outcome.Sacrifice, choice, game) && choices.size() > 1) {
order.add(getCardType(choice.getChoice())); order.add(getCardType(choice.getChoice()));
choices.remove(choice.getChoice()); choices.remove(choice.getChoice());
choice.clearChoice(); choice.clearChoice();
} }
order.add(getCardType(choices.iterator().next())); order.add(getCardType(choices.iterator().next()));
LinkedList<UUID> sacrifices = new LinkedList<UUID>(); LinkedList<UUID> sacrifices = new LinkedList<>();
int count = 1; int count = 1;
for (CardType cardType : order) { for (CardType cardType : order) {
FilterControlledPermanent filter = new FilterControlledPermanent(cardType + " permanent you control"); FilterControlledPermanent filter = new FilterControlledPermanent(cardType + " permanent you control");

View file

@ -109,7 +109,7 @@ class StolenGoodsEffect extends OneShotEffect {
class StolenGoodsCastFromExileEffect extends AsThoughEffectImpl { class StolenGoodsCastFromExileEffect extends AsThoughEffectImpl {
private UUID cardId; private final UUID cardId;
public StolenGoodsCastFromExileEffect(UUID cardId) { public StolenGoodsCastFromExileEffect(UUID cardId) {
super(AsThoughEffectType.CAST, Duration.EndOfTurn, Outcome.Benefit); super(AsThoughEffectType.CAST, Duration.EndOfTurn, Outcome.Benefit);

View file

@ -113,7 +113,7 @@ class OracleOfBonesCastEffect extends OneShotEffect {
controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", game)) { controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", game)) {
Card cardToCast = null; Card cardToCast = null;
boolean cancel = false; boolean cancel = false;
while (!cancel) { while (controller.isInGame() && !cancel) {
if (controller.chooseTarget(outcome, target, source, game)) { if (controller.chooseTarget(outcome, target, source, game)) {
cardToCast = game.getCard(target.getFirstTarget()); cardToCast = game.getCard(target.getFirstTarget());
if (cardToCast != null && cardToCast.getSpellAbility().canChooseTarget(game)) { if (cardToCast != null && cardToCast.getSpellAbility().canChooseTarget(game)) {

View file

@ -99,7 +99,7 @@ class WhimsOfTheFateEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
// Map of players and their piles (1,2,3) with values of UUID of the permanents // Map of players and their piles (1,2,3) with values of UUID of the permanents
Map<UUID, Map<Integer, Set<UUID>>> playerPermanents = new LinkedHashMap<UUID, Map<Integer, Set<UUID>>>(); Map<UUID, Map<Integer, Set<UUID>>> playerPermanents = new LinkedHashMap<>();
PlayerList playerList = game.getState().getPlayerList(); PlayerList playerList = game.getState().getPlayerList();
while (!playerList.get().equals(source.getControllerId()) && controller.isInGame()) { while (!playerList.get().equals(source.getControllerId()) && controller.isInGame()) {

View file

@ -124,7 +124,7 @@ class ActivatedAbilityTarget extends TargetObject {
@Override @Override
public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) { public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
Set<UUID> possibleTargets = new HashSet<UUID>(); Set<UUID> possibleTargets = new HashSet<>();
for (StackObject stackObject : game.getStack()) { for (StackObject stackObject : game.getStack()) {
if (stackObject.getStackAbility() != null && (stackObject.getStackAbility() instanceof ActivatedAbility) && game.getPlayer(sourceControllerId).getInRange().contains(stackObject.getStackAbility().getControllerId())) { if (stackObject.getStackAbility() != null && (stackObject.getStackAbility() instanceof ActivatedAbility) && game.getPlayer(sourceControllerId).getInRange().contains(stackObject.getStackAbility().getControllerId())) {
possibleTargets.add(stackObject.getStackAbility().getId()); possibleTargets.add(stackObject.getStackAbility().getId());

View file

@ -118,7 +118,7 @@ class AllianceOfArmsEffect extends OneShotEffect {
protected static int playerPaysXGenericMana(Player player, Ability source, Game game) { protected static int playerPaysXGenericMana(Player player, Ability source, Game game) {
int xValue = 0; int xValue = 0;
boolean payed = false; boolean payed = false;
while (!payed) { while (player.isInGame() && !payed) {
xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source); xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source);
if (xValue > 0) { if (xValue > 0) {
Cost cost = new GenericManaCost(xValue); Cost cost = new GenericManaCost(xValue);

View file

@ -127,7 +127,7 @@ class CollectiveVoyageEffect extends OneShotEffect {
protected static int playerPaysXGenericMana(Player player, Ability source, Game game) { protected static int playerPaysXGenericMana(Player player, Ability source, Game game) {
int xValue = 0; int xValue = 0;
boolean payed = false; boolean payed = false;
while (!payed) { while (player.isInGame() && !payed) {
xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source); xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source);
if (xValue > 0) { if (xValue > 0) {
Cost cost = new GenericManaCost(xValue); Cost cost = new GenericManaCost(xValue);

View file

@ -116,7 +116,7 @@ class MindsAglowEffect extends OneShotEffect {
protected static int playerPaysXGenericMana(Player player, Ability source, Game game) { protected static int playerPaysXGenericMana(Player player, Ability source, Game game) {
int xValue = 0; int xValue = 0;
boolean payed = false; boolean payed = false;
while (!payed) { while (player.isInGame() && !payed) {
xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source); xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source);
if (xValue > 0) { if (xValue > 0) {
Cost cost = new GenericManaCost(xValue); Cost cost = new GenericManaCost(xValue);

View file

@ -117,7 +117,7 @@ class SharedTraumaEffect extends OneShotEffect {
protected static int playerPaysXGenericMana(Player player, Ability source, Game game) { protected static int playerPaysXGenericMana(Player player, Ability source, Game game) {
int xValue = 0; int xValue = 0;
boolean payed = false; boolean payed = false;
while (!payed) { while (player.isInGame() && !payed) {
xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source); xValue = player.announceXMana(0, Integer.MAX_VALUE, "How much mana will you pay?", game, source);
if (xValue > 0) { if (xValue > 0) {
Cost cost = new GenericManaCost(xValue); Cost cost = new GenericManaCost(xValue);

View file

@ -105,7 +105,7 @@ class EyeOfDoomEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
List<Permanent> permanents = new ArrayList<Permanent>(); List<Permanent> permanents = new ArrayList<>();
Target target = new TargetNonlandPermanent(); Target target = new TargetNonlandPermanent();
target.setRequired(true); target.setRequired(true);
target.setNotTarget(false); target.setNotTarget(false);

View file

@ -116,7 +116,7 @@ class LimDulsVaultEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard(doAgain ? textBottom : textTop)); TargetCard target = new TargetCard(Zone.PICK, new FilterCard(doAgain ? textBottom : textTop));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -97,7 +97,7 @@ class OrderOfSuccessionEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
Map<UUID, UUID> playerCreature = new HashMap<UUID,UUID>(); Map<UUID, UUID> playerCreature = new HashMap<>();
boolean left = source.getChoices().get(0).getChoice().equals("Left"); boolean left = source.getChoices().get(0).getChoice().equals("Left");
PlayerList playerList = game.getState().getPlayerList(); PlayerList playerList = game.getState().getPlayerList();
while (!playerList.get().equals(source.getControllerId()) && controller.isInGame()) { while (!playerList.get().equals(source.getControllerId()) && controller.isInGame()) {

View file

@ -110,7 +110,7 @@ class MaelstromArchangelCastEffect extends OneShotEffect {
controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", game)) { controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", game)) {
Card cardToCast = null; Card cardToCast = null;
boolean cancel = false; boolean cancel = false;
while (!cancel) { while (controller.isInGame() && !cancel) {
if (controller.chooseTarget(outcome, target, source, game)) { if (controller.chooseTarget(outcome, target, source, game)) {
cardToCast = game.getCard(target.getFirstTarget()); cardToCast = game.getCard(target.getFirstTarget());
if (cardToCast != null && cardToCast.getSpellAbility().canChooseTarget(game)) { if (cardToCast != null && cardToCast.getSpellAbility().canChooseTarget(game)) {

View file

@ -92,7 +92,7 @@ public class ArchdemonOfGreed extends CardImpl {
public ArchdemonOfGreedEffect() { public ArchdemonOfGreedEffect() {
super(Outcome.Damage); super(Outcome.Damage);
this.staticText = "Sacrifice a Human. If you can't, tap Archdemon of Greed and it deals 9 damage to you."; this.staticText = "Sacrifice a Human. If you can't, tap {this} and it deals 9 damage to you.";
} }
public ArchdemonOfGreedEffect(final ArchdemonOfGreedEffect effect) { public ArchdemonOfGreedEffect(final ArchdemonOfGreedEffect effect) {
@ -113,24 +113,24 @@ public class ArchdemonOfGreed extends CardImpl {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { if (player != null) {
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false);
target.setRequired(true);
// if they can pay the cost, then they must pay // if they can pay the cost, then they must pay
if (target.canChoose(player.getId(), game)) { if (target.canChoose(player.getId(), game)) {
while (!target.isChosen() && target.canChoose(player.getId(), game)) { player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
}
Permanent humanSacrifice = game.getPermanent(target.getFirstTarget()); Permanent humanSacrifice = game.getPermanent(target.getFirstTarget());
if (permanent != null) { if (humanSacrifice != null) {
// sacrifice the chosen card // sacrifice the chosen card
return humanSacrifice.sacrifice(source.getId(), game); return humanSacrifice.sacrifice(source.getSourceId(), game);
} }
} }
else { else {
permanent.tap(game); permanent.tap(game);
player.damage(9, source.getId(), game, false, true); player.damage(9, source.getSourceId(), game, false, true);
} }
} }
return true;
} }
return true; return false;
} }
} }
} }

View file

@ -156,7 +156,7 @@ class CallToTheKindredEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -153,7 +153,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
target5.setNotTarget(false); target5.setNotTarget(false);
if (target1.canChoose(player.getId(), game)) { if (target1.canChoose(player.getId(), game)) {
while (!target1.isChosen() && target1.canChoose(player.getId(), game)) { while (player.isInGame() && !target1.isChosen() && target1.canChoose(player.getId(), game)) {
player.chooseTarget(Outcome.Benefit, target1, source, game); player.chooseTarget(Outcome.Benefit, target1, source, game);
} }
Permanent artifact = game.getPermanent(target1.getFirstTarget()); Permanent artifact = game.getPermanent(target1.getFirstTarget());
@ -164,7 +164,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
} }
if (target2.canChoose(player.getId(), game)) { if (target2.canChoose(player.getId(), game)) {
while (!target2.isChosen() && target2.canChoose(player.getId(), game)) { while (player.isInGame() && !target2.isChosen() && target2.canChoose(player.getId(), game)) {
player.chooseTarget(Outcome.Benefit, target2, source, game); player.chooseTarget(Outcome.Benefit, target2, source, game);
} }
Permanent creature = game.getPermanent(target2.getFirstTarget()); Permanent creature = game.getPermanent(target2.getFirstTarget());
@ -175,7 +175,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
} }
if (target3.canChoose(player.getId(), game)) { if (target3.canChoose(player.getId(), game)) {
while (!target3.isChosen() && target3.canChoose(player.getId(), game)) { while (player.isInGame() && !target3.isChosen() && target3.canChoose(player.getId(), game)) {
player.chooseTarget(Outcome.Benefit, target3, source, game); player.chooseTarget(Outcome.Benefit, target3, source, game);
} }
Permanent enchantment = game.getPermanent(target3.getFirstTarget()); Permanent enchantment = game.getPermanent(target3.getFirstTarget());
@ -186,7 +186,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
} }
if (target4.canChoose(player.getId(), game)) { if (target4.canChoose(player.getId(), game)) {
while (!target4.isChosen() && target4.canChoose(player.getId(), game)) { while (player.isInGame() && !target4.isChosen() && target4.canChoose(player.getId(), game)) {
player.chooseTarget(Outcome.Benefit, target4, source, game); player.chooseTarget(Outcome.Benefit, target4, source, game);
} }
Permanent land = game.getPermanent(target4.getFirstTarget()); Permanent land = game.getPermanent(target4.getFirstTarget());
@ -197,7 +197,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
} }
if (target5.canChoose(player.getId(), game)) { if (target5.canChoose(player.getId(), game)) {
while (!target5.isChosen() && target5.canChoose(player.getId(), game)) { while (player.isInGame() && !target5.isChosen() && target5.canChoose(player.getId(), game)) {
player.chooseTarget(Outcome.Benefit, target5, source, game); player.chooseTarget(Outcome.Benefit, target5, source, game);
} }
Permanent planeswalker = game.getPermanent(target5.getFirstTarget()); Permanent planeswalker = game.getPermanent(target5.getFirstTarget());

View file

@ -124,7 +124,7 @@ class EvershrikeEffect extends OneShotEffect {
filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId())); filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId()));
filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xAmount)); filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xAmount));
int count = you.getHand().count(filterAuraCard, game); int count = you.getHand().count(filterAuraCard, game);
while (count > 0 && you.chooseUse(Outcome.Benefit, "Do you wish to put an Aura card from your hand onto Evershrike", game)) { while (you.isInGame() && count > 0 && you.chooseUse(Outcome.Benefit, "Do you wish to put an Aura card from your hand onto Evershrike", game)) {
TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (you.choose(Outcome.Benefit, you.getHand(), targetAura, game)) { if (you.choose(Outcome.Benefit, you.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());

View file

@ -101,7 +101,7 @@ class CataclysmEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
List<Card> chosen = new ArrayList<Card>(); List<Card> chosen = new ArrayList<>();
for (UUID playerId : game.getPlayerList()) { for (UUID playerId : game.getPlayerList()) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
@ -122,7 +122,7 @@ class CataclysmEffect extends OneShotEffect {
target4.setNotTarget(true); target4.setNotTarget(true);
if (target1.canChoose(player.getId(), game)) { if (target1.canChoose(player.getId(), game)) {
while (!target1.isChosen() && target1.canChoose(player.getId(), game)) { while (player.isInGame() && !target1.isChosen() && target1.canChoose(player.getId(), game)) {
player.choose(Outcome.Benefit, target1, source.getSourceId(), game); player.choose(Outcome.Benefit, target1, source.getSourceId(), game);
} }
Permanent artifact = game.getPermanent(target1.getFirstTarget()); Permanent artifact = game.getPermanent(target1.getFirstTarget());
@ -133,7 +133,7 @@ class CataclysmEffect extends OneShotEffect {
} }
if (target2.canChoose(player.getId(), game)) { if (target2.canChoose(player.getId(), game)) {
while (!target2.isChosen() && target2.canChoose(player.getId(), game)) { while (player.isInGame() && !target2.isChosen() && target2.canChoose(player.getId(), game)) {
player.choose(Outcome.Benefit, target2, source.getSourceId(), game); player.choose(Outcome.Benefit, target2, source.getSourceId(), game);
} }
Permanent creature = game.getPermanent(target2.getFirstTarget()); Permanent creature = game.getPermanent(target2.getFirstTarget());
@ -144,7 +144,7 @@ class CataclysmEffect extends OneShotEffect {
} }
if (target3.canChoose(player.getId(), game)) { if (target3.canChoose(player.getId(), game)) {
while (!target3.isChosen() && target3.canChoose(player.getId(), game)) { while (player.isInGame() && !target3.isChosen() && target3.canChoose(player.getId(), game)) {
player.choose(Outcome.Benefit, target3, source.getSourceId(), game); player.choose(Outcome.Benefit, target3, source.getSourceId(), game);
} }
Permanent enchantment = game.getPermanent(target3.getFirstTarget()); Permanent enchantment = game.getPermanent(target3.getFirstTarget());
@ -155,7 +155,7 @@ class CataclysmEffect extends OneShotEffect {
} }
if (target4.canChoose(player.getId(), game)) { if (target4.canChoose(player.getId(), game)) {
while (!target4.isChosen() && target4.canChoose(player.getId(), game)) { while (player.isInGame() && !target4.isChosen() && target4.canChoose(player.getId(), game)) {
player.choose(Outcome.Benefit, target4, source.getSourceId(), game); player.choose(Outcome.Benefit, target4, source.getSourceId(), game);
} }
Permanent land = game.getPermanent(target4.getFirstTarget()); Permanent land = game.getPermanent(target4.getFirstTarget());

View file

@ -138,10 +138,7 @@ class DawnsReflectionManaEffect extends ManaEffect {
Mana mana = new Mana(); Mana mana = new Mana();
for(int i = 0; i < x; i++){ for(int i = 0; i < x; i++){
ChoiceColor choiceColor = new ChoiceColor(); ChoiceColor choiceColor = new ChoiceColor();
while (!controller.choose(Outcome.Benefit, choiceColor, game)) { while (controller.isInGame() && !controller.choose(Outcome.Benefit, choiceColor, game)) {
if (!controller.isInGame()) {
return false;
}
} }
if (choiceColor.getColor().isBlack()) { if (choiceColor.getColor().isBlack()) {

View file

@ -136,7 +136,7 @@ class SylvanLibraryEffect extends OneShotEffect {
if (numberOfCardsToPutBack > 1) { if (numberOfCardsToPutBack > 1) {
TargetCard target2 = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of your library (last chosen will be on top)")); TargetCard target2 = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of your library (last chosen will be on top)"));
target2.setRequired(true); target2.setRequired(true);
while (cardsPutBack.size() > 1) { while (controller.isInGame() && cardsPutBack.size() > 1) {
controller.choose(Outcome.Benefit, cardsPutBack, target2, game); controller.choose(Outcome.Benefit, cardsPutBack, target2, game);
Card card = cardsPutBack.get(target2.getFirstTarget(), game); Card card = cardsPutBack.get(target2.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -106,7 +106,7 @@ class DevourFleshSacrificeEffect extends OneShotEffect {
if (realCount > 0) { if (realCount > 0) {
Target target = new TargetControlledPermanent(1, 1, filter, true); Target target = new TargetControlledPermanent(1, 1, filter, true);
target.setRequired(true); target.setRequired(true);
while (!target.isChosen() && target.canChoose(player.getId(), game)) { while (player.isInGame() && !target.isChosen() && target.canChoose(player.getId(), game)) {
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
} }
Permanent permanent = game.getPermanent(target.getFirstTarget()); Permanent permanent = game.getPermanent(target.getFirstTarget());

View file

@ -123,7 +123,7 @@ class SacrificeControllerEffect extends OneShotEffect{
//had, if thats the case this ability should fizzle. //had, if thats the case this ability should fizzle.
if (amount > 0 && target.canChoose(source.getSourceId(), player.getId(), game)) { if (amount > 0 && target.canChoose(source.getSourceId(), player.getId(), game)) {
boolean abilityApplied = false; boolean abilityApplied = false;
while (!target.isChosen() && target.canChoose(player.getId(), game)) { while (player.isInGame() && !target.isChosen() && target.canChoose(player.getId(), game)) {
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
} }

View file

@ -94,7 +94,8 @@ class CreepingRenaissanceEffect extends OneShotEffect {
typeChoice.getChoices().add(CardType.LAND.toString()); typeChoice.getChoices().add(CardType.LAND.toString());
typeChoice.getChoices().add(CardType.PLANESWALKER.toString()); typeChoice.getChoices().add(CardType.PLANESWALKER.toString());
while (!controller.choose(Outcome.ReturnToHand, typeChoice, game)); while (controller.isInGame() && !controller.choose(Outcome.ReturnToHand, typeChoice, game)) {
}
String typeName = typeChoice.getChoice(); String typeName = typeChoice.getChoice();
CardType chosenType = null; CardType chosenType = null;

View file

@ -106,7 +106,7 @@ class DivineReckoningEffect extends OneShotEffect {
Target target = new TargetControlledPermanent(1, 1, filter, false); Target target = new TargetControlledPermanent(1, 1, filter, false);
target.setRequired(true); target.setRequired(true);
if (target.canChoose(player.getId(), game)) { if (target.canChoose(player.getId(), game)) {
while (!target.isChosen() && target.canChoose(player.getId(), game)) { while (player.isInGame() && !target.isChosen() && target.canChoose(player.getId(), game)) {
player.choose(Outcome.Benefit, target, source.getSourceId(), game); player.choose(Outcome.Benefit, target, source.getSourceId(), game);
} }
Permanent permanent = game.getPermanent(target.getFirstTarget()); Permanent permanent = game.getPermanent(target.getFirstTarget());

View file

@ -159,7 +159,7 @@ class GarrukTheVeilCursedEffect extends OneShotEffect {
Target target = new TargetControlledPermanent(1, 1, filterCreature, false); Target target = new TargetControlledPermanent(1, 1, filterCreature, false);
boolean sacrificed = false; boolean sacrificed = false;
if (target.canChoose(player.getId(), game)) { if (target.canChoose(player.getId(), game)) {
while (!target.isChosen() && target.canChoose(player.getId(), game)) { while (player.isInGame() && !target.isChosen() && target.canChoose(player.getId(), game)) {
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
} }

View file

@ -115,14 +115,14 @@ class TrepanationBladeDiscardEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
cards.add(card); cards.add(card);
card.moveToZone(Zone.GRAVEYARD, source.getId(), game, false); player.moveCardToGraveyardWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
if (card.getCardType().contains(CardType.LAND)) { if (card.getCardType().contains(CardType.LAND)) {
landFound = true; landFound = true;
} }
} }
} }
if (creature != null && !cards.isEmpty()) { if (!cards.isEmpty()) {
player.revealCards("Trepanation Blade", cards, game); player.revealCards("Trepanation Blade", cards, game);
game.getState().setValue(source.getSourceId().toString() + "_TrepanationBlade", cards.size()); game.getState().setValue(source.getSourceId().toString() + "_TrepanationBlade", cards.size());
return true; return true;

View file

@ -102,11 +102,11 @@ class OptEffect extends OneShotEffect {
} }
TargetCard target1 = new TargetCard(Zone.PICK, filter1); TargetCard target1 = new TargetCard(Zone.PICK, filter1);
// move cards to the bottom of the library // move cards to the bottom of the library
while (cards.size() > 0 && player.choose(Outcome.Detriment, cards, target1, game)) { while (cards.size() > 0 && player.isInGame() && player.choose(Outcome.Detriment, cards, target1, game)) {
Card card = cards.get(target1.getFirstTarget(), game); Card card = cards.get(target1.getFirstTarget(), game);
if (card != null) { if (card != null) {
cards.remove(card); cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getId(), game, false); card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
} }
target1.clearChosen(); target1.clearChosen();
} }

View file

@ -135,7 +135,7 @@ class NessianGameWardenEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -143,7 +143,7 @@ class FlashOfInsightEffect extends OneShotEffect {
.append(" card").append(cards.size() > 1 ? "s":"") .append(" card").append(cards.size() > 1 ? "s":"")
.append(" on the bottom of his or her library").toString()); .append(" on the bottom of his or her library").toString());
} }
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -110,7 +110,7 @@ class NaturalSelectionEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of target player's library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of target player's library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
you.choose(Outcome.Neutral, cards, target, game); you.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -115,7 +115,7 @@ class MirrorOfFateEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on top of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on top of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -91,20 +91,20 @@ class WarpWorldEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Map<UUID, List<Permanent>> permanentsOwned = new HashMap<UUID, List<Permanent>>(); Map<UUID, List<Permanent>> permanentsOwned = new HashMap<>();
Collection<Permanent> permanents = game.getBattlefield().getAllPermanents(); Collection<Permanent> permanents = game.getBattlefield().getAllPermanents();
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
List<Permanent> list = permanentsOwned.get(permanent.getOwnerId()); List<Permanent> list = permanentsOwned.get(permanent.getOwnerId());
if (list == null) { if (list == null) {
list = new ArrayList<Permanent>(); list = new ArrayList<>();
} }
list.add(permanent); list.add(permanent);
permanentsOwned.put(permanent.getOwnerId(), list); permanentsOwned.put(permanent.getOwnerId(), list);
} }
// shuffle permanents into owner's library // shuffle permanents into owner's library
Map<UUID, Integer> permanentsCount = new HashMap<UUID, Integer>(); Map<UUID, Integer> permanentsCount = new HashMap<>();
PlayerList playerList = game.getPlayerList(); PlayerList playerList = game.getPlayerList();
playerList.setCurrent(game.getActivePlayerId()); playerList.setCurrent(game.getActivePlayerId());
Player player = game.getPlayer(game.getActivePlayerId()); Player player = game.getPlayer(game.getActivePlayerId());
@ -127,7 +127,7 @@ class WarpWorldEffect extends OneShotEffect {
} while (!player.getId().equals(game.getActivePlayerId())); } while (!player.getId().equals(game.getActivePlayerId()));
Map<UUID, CardsImpl> cardsRevealed = new HashMap<UUID, CardsImpl>(); Map<UUID, CardsImpl> cardsRevealed = new HashMap<>();
// draw cards and reveal them // draw cards and reveal them
playerList.setCurrent(game.getActivePlayerId()); playerList.setCurrent(game.getActivePlayerId());
@ -155,9 +155,9 @@ class WarpWorldEffect extends OneShotEffect {
do { do {
CardsImpl cards = cardsRevealed.get(player.getId()); CardsImpl cards = cardsRevealed.get(player.getId());
for (Card card : cards.getCards(game)) { for (Card card : cards.getCards(game)) {
if (card != null && card.getCardType().contains(CardType.ARTIFACT) if (card != null && (card.getCardType().contains(CardType.ARTIFACT)
|| card.getCardType().contains(CardType.CREATURE) || card.getCardType().contains(CardType.CREATURE)
|| card.getCardType().contains(CardType.LAND)) { || card.getCardType().contains(CardType.LAND))) {
card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId()); card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId());
cards.remove(card); cards.remove(card);
} }
@ -188,7 +188,7 @@ class WarpWorldEffect extends OneShotEffect {
CardsImpl cards = cardsRevealed.get(player.getId()); CardsImpl cards = cardsRevealed.get(player.getId());
for (Card card : cards.getCards(game)) { for (Card card : cards.getCards(game)) {
if (card != null) { if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getId(), game, false); card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
} }
} }

View file

@ -95,10 +95,11 @@ class MassPolymorphEffect extends OneShotEffect {
while (creatureCards.size() < count && player.getLibrary().size() > 0) { while (creatureCards.size() < count && player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
revealed.add(card); revealed.add(card);
if (card.getCardType().contains(CardType.CREATURE)) if (card.getCardType().contains(CardType.CREATURE)) {
creatureCards.add(card); creatureCards.add(card);
else } else {
nonCreatureCards.add(card); nonCreatureCards.add(card);
}
} }
player.revealCards("Mass Polymorph", revealed, game); player.revealCards("Mass Polymorph", revealed, game);
for (Card creatureCard: creatureCards.getCards(game)) { for (Card creatureCard: creatureCards.getCards(game)) {

View file

@ -136,7 +136,7 @@ class GoblinCharbelcherEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -132,7 +132,7 @@ class MitoticManipulationEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -107,7 +107,7 @@ class PetalsOfInsightEffect extends OneShotEffect {
if (player.chooseUse(outcome, "Put the cards on the bottom of your library in any order?", game)) { if (player.chooseUse(outcome, "Put the cards on the bottom of your library in any order?", game)) {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -146,7 +146,7 @@ class PsychicSurgeryEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on top of his library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on top of his library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -141,7 +141,7 @@ class ShrineOfPiercingVisionEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -96,7 +96,7 @@ class TeferisPuzzleBoxEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -90,8 +90,8 @@ class TaintedPactEffect extends OneShotEffect{
if (player == null || sourceCard == null) { if (player == null || sourceCard == null) {
return false; return false;
} }
Set<String> names = new HashSet<String>(); Set<String> names = new HashSet<>();
while (player.getLibrary().size() > 0) { while (player.isInGame() && player.getLibrary().size() > 0) {
Card card = player.getLibrary().getFromTop(game); Card card = player.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {

View file

@ -103,7 +103,7 @@ class ReturnToHandEffect extends OneShotEffect {
target.setRequired(true); target.setRequired(true);
if (target.canChoose(player.getId(), game)) { if (target.canChoose(player.getId(), game)) {
while (!target.isChosen() && target.canChoose(player.getId(), game)) { while (player.isInGame() && !target.isChosen() && target.canChoose(player.getId(), game)) {
player.chooseTarget(Outcome.ReturnToHand, target, source, game); player.chooseTarget(Outcome.ReturnToHand, target, source, game);
} }

View file

@ -93,7 +93,7 @@ class MindmoilEffect extends OneShotEffect {
} }
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (you.isInGame() && cards.size() > 1) {
you.choose(Outcome.Neutral, cards, target, game); you.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -306,7 +306,7 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
TargetCard targetCard = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard targetCard = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
targetCard.setRequired(true); targetCard.setRequired(true);
while (cardsToLibrary.size() > 1) { while (player.isInGame() && cardsToLibrary.size() > 1) {
player.choose(Outcome.Neutral, cardsToLibrary, targetCard, game); player.choose(Outcome.Neutral, cardsToLibrary, targetCard, game);
Card card = cardsToLibrary.get(targetCard.getFirstTarget(), game); Card card = cardsToLibrary.get(targetCard.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -114,7 +114,7 @@ class HellcarverDemonEffect extends OneShotEffect {
} }
} }
while (player != null && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with Hellcarver Demon without paying that card's mana cost?", game)) { while (player != null && player.isInGame() && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with Hellcarver Demon without paying that card's mana cost?", game)) {
TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId()); TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId());
while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(source.getSourceId()), target, game)) { while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(source.getSourceId()), target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());

View file

@ -100,15 +100,16 @@ class JaddiLifestriderEffect extends OneShotEffect {
TargetCreaturePermanent target = new TargetCreaturePermanent(filter); TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
while (true) { while (true) {
target.clearChosen(); target.clearChosen();
if (target.canChoose(source.getControllerId(), game) && target.choose(Outcome.Tap, source.getControllerId(), source.getId(), game)) { if (target.canChoose(source.getControllerId(), game) && target.choose(Outcome.Tap, source.getControllerId(), source.getSourceId(), game)) {
UUID creature = target.getFirstTarget(); UUID creature = target.getFirstTarget();
if (creature != null) { if (creature != null) {
game.getPermanent(creature).tap(game); game.getPermanent(creature).tap(game);
tappedAmount++; tappedAmount++;
} }
} }
else else {
break; break;
}
} }
if (tappedAmount > 0) { if (tappedAmount > 0) {
you.gainLife(tappedAmount * 2, game); you.gainLife(tappedAmount * 2, game);

View file

@ -126,7 +126,7 @@ class CloneShellEffect extends OneShotEffect {
if (cards.size() > 0) { if (cards.size() > 0) {
TargetCard target2 = new TargetCard(Zone.PICK, filter2); TargetCard target2 = new TargetCard(Zone.PICK, filter2);
target2.setRequired(true); target2.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Benefit, cards, target2, game); player.choose(Outcome.Benefit, cards, target2, game);
Card card = cards.get(target2.getFirstTarget(), game); Card card = cards.get(target2.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -106,10 +106,11 @@ public class ShapeAnew extends CardImpl {
while (artifactCard == null && player.getLibrary().size() > 0) { while (artifactCard == null && player.getLibrary().size() > 0) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);
revealed.add(card); revealed.add(card);
if (card.getCardType().contains(CardType.ARTIFACT)) if (card.getCardType().contains(CardType.ARTIFACT)) {
artifactCard = card; artifactCard = card;
else } else {
nonArtifactCards.add(card); nonArtifactCards.add(card);
}
} }
player.revealCards("Shape Anew", revealed, game); player.revealCards("Shape Anew", revealed, game);
if (artifactCard != null) { if (artifactCard != null) {

View file

@ -143,7 +143,7 @@ class GiftOfTheGargantuanEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -90,9 +90,10 @@ class ScrollRackEffect extends OneShotEffect {
FilterCard filter = new FilterCard("card in your hand to exile"); FilterCard filter = new FilterCard("card in your hand to exile");
FilterCard filter2 = new FilterCard("card exiled by Scroll Rack to put on top of library"); FilterCard filter2 = new FilterCard("card exiled by Scroll Rack to put on top of library");
Player you = game.getPlayer(source.getControllerId()); Player you = game.getPlayer(source.getControllerId());
TargetCardInHand target = new TargetCardInHand(0, you.getHand().size(), filter);
int amountExiled = 0;
if (you != null) { if (you != null) {
TargetCardInHand target = new TargetCardInHand(0, you.getHand().size(), filter);
int amountExiled = 0;
if (target.canChoose(source.getControllerId(), game) && target.choose(Outcome.Neutral, source.getControllerId(), source.getId(), game)) { if (target.canChoose(source.getControllerId(), game) && target.choose(Outcome.Neutral, source.getControllerId(), source.getId(), game)) {
if (!target.getTargets().isEmpty()) { if (!target.getTargets().isEmpty()) {
List<UUID> targets = target.getTargets(); List<UUID> targets = target.getTargets();
@ -121,10 +122,8 @@ class ScrollRackEffect extends OneShotEffect {
ExileZone scrollRackExileZone = game.getExile().getExileZone(source.getSourceId()); ExileZone scrollRackExileZone = game.getExile().getExileZone(source.getSourceId());
target2.setRequired(true); target2.setRequired(true);
if (scrollRackExileZone != null) { if (scrollRackExileZone != null) {
while (scrollRackExileZone.count(filter, game) > 1) { while (you.isInGame() && scrollRackExileZone.count(filter, game) > 1) {
if (you != null) { you.lookAtCards("exiled cards with " + game.getCard(source.getSourceId()).getName(), scrollRackExileZone, game);
you.lookAtCards("exiled cards with " + game.getCard(source.getSourceId()).getName(), scrollRackExileZone, game);
}
you.choose(Outcome.Neutral, scrollRackExileZone, target2, game); you.choose(Outcome.Neutral, scrollRackExileZone, target2, game);
Card card = game.getCard(target2.getFirstTarget()); Card card = game.getCard(target2.getFirstTarget());
if (card != null) { if (card != null) {

View file

@ -95,7 +95,7 @@ class ScalpelexisEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(targetPointer.getFirst(game, source));
List<String> namesFiltered = new ArrayList<String>(); List<String> namesFiltered = new ArrayList<>();
boolean doneOnce = false; boolean doneOnce = false;
while (checkDuplicatedNames(namesFiltered) || !doneOnce) { while (checkDuplicatedNames(namesFiltered) || !doneOnce) {
@ -114,16 +114,18 @@ class ScalpelexisEffect extends OneShotEffect {
} }
public boolean checkDuplicatedNames(List<String> string) { public boolean checkDuplicatedNames(List<String> string) {
for (int i = 0; i < string.size()-1; i++) { for (int i = 0; i < string.size() - 1; i++) {
String stringToCheck = string.get(i); String stringToCheck = string.get(i);
if(stringToCheck == null) continue; //empty ignore if (stringToCheck == null) {
for (int j = i+1; j < string.size(); j++) { continue; //empty ignore
String stringToCompare = string.get(j); }
if (stringToCheck.equals(stringToCompare)){ for (int j = i + 1; j < string.size(); j++) {
return true; String stringToCompare = string.get(j);
} if (stringToCheck.equals(stringToCompare)) {
return true;
} }
} }
return false; }
return false;
} }
} }

View file

@ -153,7 +153,7 @@ class PutCardsFromGraveyardToLibraryEffect extends OneShotEffect {
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("on bottom of your library (last chosen will be on bottom)")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("on bottom of your library (last chosen will be on bottom)"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -118,7 +118,7 @@ class HarmonicConvergenceEffect extends OneShotEffect {
for (Permanent permanent : list) { for (Permanent permanent : list) {
cards.add(permanent); cards.add(permanent);
} }
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Permanent permanent = game.getPermanent(target.getFirstTarget()); Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) { if (permanent != null) {

View file

@ -126,7 +126,7 @@ public class RavenFamiliar extends CardImpl {
target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -122,7 +122,7 @@ class GoblinRecruiterEffect extends OneShotEffect {
if (cards.size() > 1) { if (cards.size() > 1) {
TargetCard targetCard = new TargetCard(Zone.LIBRARY, putOnTopOfLibraryFilter); TargetCard targetCard = new TargetCard(Zone.LIBRARY, putOnTopOfLibraryFilter);
targetCard.setRequired(true); targetCard.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Benefit, cards, targetCard, game); player.choose(Outcome.Benefit, cards, targetCard, game);
Card card = cards.get(targetCard.getFirstTarget(), game); Card card = cards.get(targetCard.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -118,7 +118,7 @@ class MerfolkWayfinderEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true); target.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game); player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {

View file

@ -198,7 +198,7 @@ class SummoningTrapEffect extends OneShotEffect {
new FilterCard( new FilterCard(
"card to put on the bottom of your library")); "card to put on the bottom of your library"));
target2.setRequired(true); target2.setRequired(true);
while (cards.size() > 1) { while (player.isInGame() && cards.size() > 1) {
player.choose(Outcome.Benefit, cards, target2, player.choose(Outcome.Benefit, cards, target2,
game); game);
Card card = cards.get(target2.getFirstTarget(), game); Card card = cards.get(target2.getFirstTarget(), game);

View file

@ -86,7 +86,7 @@ public class WorldQueller extends CardImpl {
class WorldQuellerEffect extends OneShotEffect { class WorldQuellerEffect extends OneShotEffect {
private static final HashSet<String> choice = new LinkedHashSet<String>(); private static final HashSet<String> choice = new LinkedHashSet<>();
static { static {
choice.add(CardType.ARTIFACT.toString()); choice.add(CardType.ARTIFACT.toString());
@ -115,13 +115,13 @@ class WorldQuellerEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
List<Card> chosen = new ArrayList<Card>(); List<Card> chosen = new ArrayList<>();
Player you = game.getPlayer(source.getControllerId()); Player you = game.getPlayer(source.getControllerId());
Permanent sourceCreature = game.getPermanent(source.getSourceId()); Permanent sourceCreature = game.getPermanent(source.getSourceId());
if (you != null && sourceCreature != null) { if (you != null && sourceCreature != null) {
Choice choiceImpl = new ChoiceImpl(); Choice choiceImpl = new ChoiceImpl();
choiceImpl.setChoices(choice); choiceImpl.setChoices(choice);
while (!you.choose(Outcome.Neutral, choiceImpl, game)) {}; while (you.isInGame() && !you.choose(Outcome.Neutral, choiceImpl, game)) {}
CardType type = null; CardType type = null;
String choosenType = choiceImpl.getChoice(); String choosenType = choiceImpl.getChoice();
@ -142,51 +142,52 @@ class WorldQuellerEffect extends OneShotEffect {
} else if (choosenType.equals(CardType.TRIBAL.toString())) { } else if (choosenType.equals(CardType.TRIBAL.toString())) {
type = CardType.TRIBAL; type = CardType.TRIBAL;
} }
if (type != null) {
FilterPermanent filter = new FilterControlledPermanent(new StringBuilder("permanent you control of type ").append(type.toString()).toString());
filter.add(new CardTypePredicate(type));
FilterPermanent filter = new FilterControlledPermanent(new StringBuilder("permanent you control of type ").append(type.toString()).toString()); TargetPermanent target = new TargetControlledPermanent(1, 1, filter, false);
filter.add(new CardTypePredicate(type)); target.setRequired(true);
target.setNotTarget(true);
TargetPermanent target = new TargetControlledPermanent(1, 1, filter, false); // you always go first
target.setRequired(true); if (target.canChoose(you.getId(), game)) {
target.setNotTarget(true); while (you.isInGame() && !target.isChosen() && target.canChoose(you.getId(), game)) {
you.choose(Outcome.Sacrifice, target, source.getId(), game);
// you always go first }
if (target.canChoose(you.getId(), game)) { Permanent permanent = game.getPermanent(target.getFirstTarget());
while (!target.isChosen() && target.canChoose(you.getId(), game)) { if (permanent != null) {
you.choose(Outcome.Sacrifice, target, source.getId(), game); chosen.add(permanent);
}
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
chosen.add(permanent);
}
}
target.clearChosen();
// opponents follow
for (UUID playerId : game.getPlayerList()) {
if (playerId != you.getId()) {
Player player = game.getPlayer(playerId);
if (target.canChoose(playerId, game)) {
while (!target.isChosen() && target.canChoose(playerId, game)) {
player.choose(Outcome.Sacrifice, target, source.getId(), game);
}
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
chosen.add(permanent);
}
target.clearChosen();
} }
} }
}
// all chosen permanents are sacrificed together target.clearChosen();
for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
if (chosen.contains(permanent)) { // opponents follow
permanent.sacrifice(source.getId(), game); for (UUID playerId : game.getPlayerList()) {
if (playerId != you.getId()) {
Player player = game.getPlayer(playerId);
if (target.canChoose(playerId, game)) {
while (!target.isChosen() && target.canChoose(playerId, game)) {
player.choose(Outcome.Sacrifice, target, source.getId(), game);
}
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
chosen.add(permanent);
}
target.clearChosen();
}
}
} }
// all chosen permanents are sacrificed together
for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
if (chosen.contains(permanent)) {
permanent.sacrifice(source.getId(), game);
}
}
return true;
} }
return true;
} }
return false; return false;
} }

View file

@ -2254,10 +2254,17 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName) { public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName) {
boolean result = false; boolean result = false;
if (card.moveToZone(Zone.LIBRARY, sourceId, game, toTop)) { if (card.moveToZone(Zone.LIBRARY, sourceId, game, toTop)) {
game.informPlayers(new StringBuilder(this.getName()) StringBuilder sb = new StringBuilder(this.getName())
.append(" puts ").append(withName ? card.getName():"a card").append(" ") .append(" puts ").append(withName ? card.getName():"a card").append(" ");
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"") if (fromZone != null) {
.append("to the ").append(toTop ? "top":"bottom").append(" of his or her library").toString()); if (fromZone.equals(Zone.PICK)) {
sb.append("a picked card ");
} else {
sb.append("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ");
}
}
sb.append("to the ").append(toTop ? "top":"bottom").append(" of his or her library");
game.informPlayers(sb.toString());
result = true; result = true;
} }
return result; return result;