mirror of
https://github.com/correl/mage.git
synced 2025-03-07 20:53:18 -10:00
fixed and refactored balance effect (#6595)
* fixed and refactored balance effect * inversed logic in balance effect - now players choose cards to keep instead to sacrifice/discard
This commit is contained in:
parent
642cdea2f8
commit
e68a20c5fb
2 changed files with 116 additions and 91 deletions
|
@ -0,0 +1,41 @@
|
|||
package org.mage.test.cards.single;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class BalanceTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testBalance() {
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Runeclaw Bear", 3);
|
||||
addCard(Zone.HAND, playerA, "Plains", 1);
|
||||
addCard(Zone.HAND, playerA, "Balance");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Runeclaw Bear", 2);
|
||||
addCard(Zone.HAND, playerB, "Swamp", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balance");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Plains", 2);
|
||||
assertPermanentCount(playerA, "Runeclaw Bear", 2);
|
||||
assertHandCount(playerA, "Plains", 1);
|
||||
assertHandCount(playerA, "Balance", 0);
|
||||
assertGraveyardCount(playerA, "Runeclaw Bear", 1);
|
||||
assertGraveyardCount(playerA, "Balance", 1);
|
||||
|
||||
assertPermanentCount(playerB, "Swamp", 2);
|
||||
assertPermanentCount(playerB, "Runeclaw Bear", 2);
|
||||
assertHandCount(playerB, "Swamp", 1);
|
||||
assertGraveyardCount(playerB, "Swamp", 2); //1 from hand, 1 from battlefield
|
||||
|
||||
}
|
||||
}
|
|
@ -17,19 +17,14 @@ import mage.players.Player;
|
|||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author emerald000
|
||||
*/
|
||||
public class BalanceEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent("lands to keep");
|
||||
private static final FilterControlledPermanent filter2 = new FilterControlledCreaturePermanent("creatures to keep");
|
||||
private static final FilterCard filter3 = new FilterCard("cards to keep");
|
||||
|
||||
public BalanceEffect() {
|
||||
super(Outcome.Sacrifice);
|
||||
staticText = "each player chooses a number of lands they control "
|
||||
|
@ -53,108 +48,45 @@ public class BalanceEffect extends OneShotEffect {
|
|||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
//Lands
|
||||
int minLand = Integer.MAX_VALUE;
|
||||
Cards landsToSacrifice = new CardsImpl();
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
int count = game.getBattlefield().countAll(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, player.getId(), game);
|
||||
if (count < minLand) {
|
||||
minLand = count;
|
||||
}
|
||||
}
|
||||
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(minLand, minLand, filter, true);
|
||||
if (!target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) {
|
||||
continue;
|
||||
}
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, player.getId(), source.getSourceId(), game)) {
|
||||
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
|
||||
landsToSacrifice.add(permanent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (UUID cardId : landsToSacrifice) {
|
||||
Permanent permanent = game.getPermanent(cardId);
|
||||
if (permanent != null) {
|
||||
permanent.sacrifice(source.getSourceId(), game);
|
||||
}
|
||||
}
|
||||
|
||||
//Creatures
|
||||
int minCreature = Integer.MAX_VALUE;
|
||||
Cards creaturesToSacrifice = new CardsImpl();
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
}
|
||||
int count = game.getBattlefield().countAll(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, player.getId(), game);
|
||||
if (count < minCreature) {
|
||||
minCreature = count;
|
||||
}
|
||||
}
|
||||
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(minCreature, minCreature, filter2, true);
|
||||
if (!target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) {
|
||||
continue;
|
||||
}
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source.getSourceId(), game)) {
|
||||
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
|
||||
creaturesToSacrifice.add(permanent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (UUID cardId : creaturesToSacrifice) {
|
||||
Permanent permanent = game.getPermanent(cardId);
|
||||
if (permanent != null) {
|
||||
permanent.sacrifice(source.getSourceId(), game);
|
||||
}
|
||||
}
|
||||
choosePermanentsToKeep(game, source, controller, StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, new FilterControlledLandPermanent("lands to keep"));
|
||||
choosePermanentsToKeep(game, source, controller, StaticFilters.FILTER_CONTROLLED_CREATURE, new FilterControlledCreaturePermanent("creatures to keep"));
|
||||
|
||||
//Cards in hand
|
||||
int minCard = Integer.MAX_VALUE;
|
||||
Map<UUID, Cards> cardsToDiscard = new HashMap<>(2);
|
||||
int lowestHandSize = Integer.MAX_VALUE;
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
int count = player.getHand().size();
|
||||
if (count < minCard) {
|
||||
minCard = count;
|
||||
}
|
||||
|
||||
lowestHandSize = Math.min(lowestHandSize, player.getHand().size());
|
||||
}
|
||||
|
||||
Map<UUID, Cards> cardsToDiscard = new HashMap<>();
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
Cards cards = new CardsImpl();
|
||||
TargetCardInHand target = new TargetCardInHand(minCard, filter3);
|
||||
if (!target.choose(Outcome.Discard, player.getId(), source.getSourceId(), game)) {
|
||||
|
||||
TargetCardInHand target = new TargetCardInHand(lowestHandSize, new FilterCard("cards to keep"));
|
||||
if (!target.choose(Outcome.Protect, player.getId(), source.getSourceId(), game)) {
|
||||
continue;
|
||||
}
|
||||
for (Card card : player.getHand().getCards(game)) {
|
||||
if (card != null && !target.getTargets().contains(card.getId())) {
|
||||
cards.add(card);
|
||||
|
||||
Set<Card> allCardsInHand = player.getHand().getCards(game);
|
||||
Set<Card> cardsToKeep = new LinkedHashSet<>();
|
||||
|
||||
for (Card card : allCardsInHand) {
|
||||
if (card != null && target.getTargets().contains(card.getId())) {
|
||||
cardsToKeep.add(card);
|
||||
}
|
||||
}
|
||||
cardsToDiscard.put(playerId, cards);
|
||||
|
||||
cardsToDiscard.put(playerId, allCardsInHand.stream()
|
||||
.filter(e -> !cardsToKeep.contains(e))
|
||||
.collect(CardsImpl::new, CardsImpl::add, CardsImpl::addAll));
|
||||
}
|
||||
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
|
@ -163,6 +95,58 @@ public class BalanceEffect extends OneShotEffect {
|
|||
player.discard(cardsToDiscard.get(playerId), source, game);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void choosePermanentsToKeep(Game game, Ability source, Player controller,
|
||||
FilterControlledPermanent filterPermanent, FilterControlledPermanent filterPermanentDialog) {
|
||||
int lowestPermanentsCount = Integer.MAX_VALUE;
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lowestPermanentsCount = Math.min(lowestPermanentsCount,
|
||||
game.getBattlefield().countAll(filterPermanent, player.getId(), game));
|
||||
}
|
||||
|
||||
List<Permanent> permanentsToSacrifice = new ArrayList<>();
|
||||
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
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> permanentsToKeep = new ArrayList<>();
|
||||
|
||||
for (Permanent permanent : allPermanentsOfType) {
|
||||
if (permanent != null && target.getTargets().contains(permanent.getId())) {
|
||||
permanentsToKeep.add(permanent);
|
||||
}
|
||||
}
|
||||
|
||||
List<Permanent> playerPermanentsToSacrifice = allPermanentsOfType.stream().filter(e -> !permanentsToKeep.contains(e)).collect(Collectors.toList());
|
||||
permanentsToSacrifice.addAll(playerPermanentsToSacrifice);
|
||||
|
||||
if (playerPermanentsToSacrifice.isEmpty()) {
|
||||
game.informPlayers(player.getLogName() + " chose permanents to be sacrificed: "
|
||||
+ playerPermanentsToSacrifice.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
|
||||
}
|
||||
}
|
||||
|
||||
for (Permanent permanent : permanentsToSacrifice) {
|
||||
if (permanent != null) {
|
||||
permanent.sacrifice(source.getSourceId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue