BalanceEffect - Fixed effect when a player has 0 permanents/cards (fixes #7950)

This commit is contained in:
Daniel Bomar 2021-10-19 21:53:25 -05:00
parent 90aa65168b
commit aa4397dee5
No known key found for this signature in database
GPG key ID: C86C8658F4023918

View file

@ -7,7 +7,6 @@ import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
@ -25,6 +24,10 @@ import java.util.stream.Collectors;
*/ */
public class BalanceEffect extends OneShotEffect { public class BalanceEffect extends OneShotEffect {
private static final FilterControlledLandPermanent filterLand = new FilterControlledLandPermanent("lands to keep");
private static final FilterControlledCreaturePermanent filterCreature = new FilterControlledCreaturePermanent("creatures to keep");
private static final FilterCard filterCardHand = new FilterCard("cards to keep");
public BalanceEffect() { public BalanceEffect() {
super(Outcome.Sacrifice); super(Outcome.Sacrifice);
staticText = "each player chooses a number of lands they control " staticText = "each player chooses a number of lands they control "
@ -49,8 +52,8 @@ public class BalanceEffect extends OneShotEffect {
return false; return false;
} }
choosePermanentsToKeep(game, source, controller, StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, new FilterControlledLandPermanent("lands to keep")); choosePermanentsToKeep(game, source, controller, filterLand);
choosePermanentsToKeep(game, source, controller, StaticFilters.FILTER_CONTROLLED_CREATURE, new FilterControlledCreaturePermanent("creatures to keep")); choosePermanentsToKeep(game, source, controller, filterCreature);
//Cards in hand //Cards in hand
int lowestHandSize = Integer.MAX_VALUE; int lowestHandSize = Integer.MAX_VALUE;
@ -70,17 +73,30 @@ public class BalanceEffect extends OneShotEffect {
continue; continue;
} }
TargetCardInHand target = new TargetCardInHand(lowestHandSize, new FilterCard("cards to keep"));
if (!target.choose(Outcome.Protect, player.getId(), source.getSourceId(), game)) {
continue;
}
Set<Card> allCardsInHand = player.getHand().getCards(game); Set<Card> allCardsInHand = player.getHand().getCards(game);
Set<Card> cardsToKeep = new LinkedHashSet<>(); Set<Card> cardsToKeep = new LinkedHashSet<>();
for (Card card : allCardsInHand) { if (lowestHandSize > 0) {
if (card != null && target.getTargets().contains(card.getId())) { TargetCardInHand target = new TargetCardInHand(lowestHandSize, filterCardHand);
cardsToKeep.add(card); if (target.choose(Outcome.Protect, player.getId(), source.getSourceId(), game)) {
for (Card card : allCardsInHand) {
if (card != null && target.getTargets().contains(card.getId())) {
cardsToKeep.add(card);
}
}
// Prevent possible cheat by disconnecting. If no targets are chosen, just pick the first in the list.
// https://github.com/magefree/mage/issues/4263
} else {
int numCards = 0;
for (Card card : allCardsInHand) {
if (numCards >= lowestHandSize) {
break;
}
if (card != null) {
cardsToKeep.add(card);
numCards++;
}
}
} }
} }
@ -100,7 +116,7 @@ public class BalanceEffect extends OneShotEffect {
} }
private void choosePermanentsToKeep(Game game, Ability source, Player controller, private void choosePermanentsToKeep(Game game, Ability source, Player controller,
FilterControlledPermanent filterPermanent, FilterControlledPermanent filterPermanentDialog) { FilterControlledPermanent filterPermanent) {
int lowestPermanentsCount = Integer.MAX_VALUE; int lowestPermanentsCount = Integer.MAX_VALUE;
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
@ -120,24 +136,37 @@ public class BalanceEffect extends OneShotEffect {
continue; continue;
} }
TargetControlledPermanent target = new TargetControlledPermanent(lowestPermanentsCount, lowestPermanentsCount, filterPermanentDialog, true);
if (!target.choose(Outcome.Protect, player.getId(), source.getSourceId(), game)) {
continue;
}
List<Permanent> allPermanentsOfType = game.getBattlefield().getActivePermanents(filterPermanent, player.getId(), source.getSourceId(), game); List<Permanent> allPermanentsOfType = game.getBattlefield().getActivePermanents(filterPermanent, player.getId(), source.getSourceId(), game);
List<Permanent> permanentsToKeep = new ArrayList<>(); List<Permanent> permanentsToKeep = new ArrayList<>();
for (Permanent permanent : allPermanentsOfType) { if (lowestPermanentsCount > 0) {
if (permanent != null && target.getTargets().contains(permanent.getId())) { TargetControlledPermanent target = new TargetControlledPermanent(lowestPermanentsCount, lowestPermanentsCount, filterPermanent, true);
permanentsToKeep.add(permanent); if (target.choose(Outcome.Protect, player.getId(), source.getSourceId(), game)) {
for (Permanent permanent : allPermanentsOfType) {
if (permanent != null && target.getTargets().contains(permanent.getId())) {
permanentsToKeep.add(permanent);
}
}
// Prevent possible cheat by disconnecting. If no targets are chosen, just pick the first in the list.
// https://github.com/magefree/mage/issues/4263
} else {
int numPermanents = 0;
for (Permanent permanent : allPermanentsOfType) {
if (numPermanents >= lowestPermanentsCount) {
break;
}
if (permanent != null) {
permanentsToKeep.add(permanent);
numPermanents++;
}
}
} }
} }
List<Permanent> playerPermanentsToSacrifice = allPermanentsOfType.stream().filter(e -> !permanentsToKeep.contains(e)).collect(Collectors.toList()); List<Permanent> playerPermanentsToSacrifice = allPermanentsOfType.stream().filter(e -> !permanentsToKeep.contains(e)).collect(Collectors.toList());
permanentsToSacrifice.addAll(playerPermanentsToSacrifice); permanentsToSacrifice.addAll(playerPermanentsToSacrifice);
if (playerPermanentsToSacrifice.isEmpty()) { if (!playerPermanentsToSacrifice.isEmpty()) {
game.informPlayers(player.getLogName() + " chose permanents to be sacrificed: " game.informPlayers(player.getLogName() + " chose permanents to be sacrificed: "
+ playerPermanentsToSacrifice.stream().map(Permanent::getLogName).collect(Collectors.joining(", "))); + playerPermanentsToSacrifice.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
} }