mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
* Fixed a bug that created a endless loop if mana producer were involved, that create mana of any type lands of players could produce (fixes ##3374).
This commit is contained in:
parent
c87e992e1d
commit
a9e2303f7e
4 changed files with 52 additions and 370 deletions
|
@ -27,29 +27,13 @@
|
|||
*/
|
||||
package mage.cards.n;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.abilities.mana.AnyColorLandsProduceManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -66,7 +50,7 @@ public class NagaVitalist extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// {T}: Add to your mana pool one mana of any type that a land you control could produce.
|
||||
this.addAbility(new NagaVitalistManaAbility());
|
||||
this.addAbility(new AnyColorLandsProduceManaAbility(TargetController.YOU));
|
||||
}
|
||||
|
||||
public NagaVitalist(final NagaVitalist card) {
|
||||
|
@ -78,166 +62,3 @@ public class NagaVitalist extends CardImpl {
|
|||
return new NagaVitalist(this);
|
||||
}
|
||||
}
|
||||
|
||||
class NagaVitalistManaAbility extends ActivatedManaAbilityImpl {
|
||||
|
||||
public NagaVitalistManaAbility() {
|
||||
super(Zone.BATTLEFIELD, new NagaVitalistEffect(), new TapSourceCost());
|
||||
}
|
||||
|
||||
public NagaVitalistManaAbility(final NagaVitalistManaAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NagaVitalistManaAbility copy() {
|
||||
return new NagaVitalistManaAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
return ((NagaVitalistEffect) getEffects().get(0)).getNetMana(game, this);
|
||||
}
|
||||
}
|
||||
|
||||
class NagaVitalistEffect extends ManaEffect {
|
||||
|
||||
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
|
||||
|
||||
public NagaVitalistEffect() {
|
||||
super();
|
||||
staticText = "Add to your mana pool one mana of any type that a land you control could produce";
|
||||
}
|
||||
|
||||
public NagaVitalistEffect(final NagaVitalistEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Mana types = getManaTypes(game, source);
|
||||
Choice choice = new ChoiceColor(true);
|
||||
choice.getChoices().clear();
|
||||
choice.setMessage("Pick a mana color");
|
||||
if (types.getBlack() > 0) {
|
||||
choice.getChoices().add("Black");
|
||||
}
|
||||
if (types.getRed() > 0) {
|
||||
choice.getChoices().add("Red");
|
||||
}
|
||||
if (types.getBlue() > 0) {
|
||||
choice.getChoices().add("Blue");
|
||||
}
|
||||
if (types.getGreen() > 0) {
|
||||
choice.getChoices().add("Green");
|
||||
}
|
||||
if (types.getWhite() > 0) {
|
||||
choice.getChoices().add("White");
|
||||
}
|
||||
if (types.getColorless() > 0) {
|
||||
choice.getChoices().add("Colorless");
|
||||
}
|
||||
if (types.getAny() > 0) {
|
||||
choice.getChoices().add("Black");
|
||||
choice.getChoices().add("Red");
|
||||
choice.getChoices().add("Blue");
|
||||
choice.getChoices().add("Green");
|
||||
choice.getChoices().add("White");
|
||||
choice.getChoices().add("Colorless");
|
||||
}
|
||||
if (!choice.getChoices().isEmpty()) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (choice.getChoices().size() == 1) {
|
||||
choice.setChoice(choice.getChoices().iterator().next());
|
||||
} else {
|
||||
player.choose(outcome, choice, game);
|
||||
}
|
||||
if (choice.getChoice() != null) {
|
||||
Mana mana = new Mana();
|
||||
switch (choice.getChoice()) {
|
||||
case "Black":
|
||||
mana.setBlack(1);
|
||||
break;
|
||||
case "Blue":
|
||||
mana.setBlue(1);
|
||||
break;
|
||||
case "Red":
|
||||
mana.setRed(1);
|
||||
break;
|
||||
case "Green":
|
||||
mana.setGreen(1);
|
||||
break;
|
||||
case "White":
|
||||
mana.setWhite(1);
|
||||
break;
|
||||
case "Colorless":
|
||||
mana.setColorless(1);
|
||||
break;
|
||||
}
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
List<Mana> netManas = new ArrayList<>();
|
||||
Mana types = getManaTypes(game, source);
|
||||
if (types.getAny() > 0) {
|
||||
netManas.add(new Mana(0, 0, 0, 0, 0, 0, 1, 0));
|
||||
return netManas;
|
||||
}
|
||||
if (types.getBlack() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.B));
|
||||
}
|
||||
if (types.getRed() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.R));
|
||||
}
|
||||
if (types.getBlue() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.U));
|
||||
}
|
||||
if (types.getGreen() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.G));
|
||||
}
|
||||
if (types.getWhite() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.W));
|
||||
}
|
||||
if (types.getColorless() > 0) {
|
||||
netManas.add(Mana.ColorlessMana(1));
|
||||
}
|
||||
return netManas;
|
||||
}
|
||||
|
||||
private Mana getManaTypes(Game game, Ability source) {
|
||||
List<Permanent> lands = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game);
|
||||
Mana types = new Mana();
|
||||
for (Permanent land : lands) {
|
||||
Abilities<Ability> manaAbilities = land.getAbilities(game).getManaAbilities(Zone.BATTLEFIELD);
|
||||
for (Ability basicAbility : manaAbilities) {
|
||||
ManaAbility ability = (ManaAbility) basicAbility;
|
||||
if (!ability.equals(source) && ability.definesMana(game)) {
|
||||
for (Mana netMana : ability.getNetMana(game)) {
|
||||
types.add(netMana);
|
||||
if (netMana.getAny() > 0) {
|
||||
return types;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NagaVitalistEffect copy() {
|
||||
return new NagaVitalistEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,28 +27,12 @@
|
|||
*/
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.abilities.mana.AnyColorLandsProduceManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -60,7 +44,7 @@ public class ReflectingPool extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// {T}: Add to your mana pool one mana of any type that a land you control could produce.
|
||||
this.addAbility(new ReflectingPoolManaAbility());
|
||||
this.addAbility(new AnyColorLandsProduceManaAbility(TargetController.YOU));
|
||||
}
|
||||
|
||||
public ReflectingPool(final ReflectingPool card) {
|
||||
|
@ -72,170 +56,3 @@ public class ReflectingPool extends CardImpl {
|
|||
return new ReflectingPool(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ReflectingPoolManaAbility extends ActivatedManaAbilityImpl {
|
||||
|
||||
public ReflectingPoolManaAbility() {
|
||||
super(Zone.BATTLEFIELD, new ReflectingPoolEffect(), new TapSourceCost());
|
||||
}
|
||||
|
||||
public ReflectingPoolManaAbility(final ReflectingPoolManaAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReflectingPoolManaAbility copy() {
|
||||
return new ReflectingPoolManaAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
return ((ReflectingPoolEffect) getEffects().get(0)).getNetMana(game, this);
|
||||
}
|
||||
}
|
||||
|
||||
class ReflectingPoolEffect extends ManaEffect {
|
||||
|
||||
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
|
||||
|
||||
public ReflectingPoolEffect() {
|
||||
super();
|
||||
staticText = "Add to your mana pool one mana of any type that a land you control could produce";
|
||||
}
|
||||
|
||||
public ReflectingPoolEffect(final ReflectingPoolEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Mana types = getManaTypes(game, source);
|
||||
Choice choice = new ChoiceColor(true);
|
||||
choice.getChoices().clear();
|
||||
choice.setMessage("Pick a mana color");
|
||||
if (types.getBlack() > 0) {
|
||||
choice.getChoices().add("Black");
|
||||
}
|
||||
if (types.getRed() > 0) {
|
||||
choice.getChoices().add("Red");
|
||||
}
|
||||
if (types.getBlue() > 0) {
|
||||
choice.getChoices().add("Blue");
|
||||
}
|
||||
if (types.getGreen() > 0) {
|
||||
choice.getChoices().add("Green");
|
||||
}
|
||||
if (types.getWhite() > 0) {
|
||||
choice.getChoices().add("White");
|
||||
}
|
||||
if (types.getColorless() > 0) {
|
||||
choice.getChoices().add("Colorless");
|
||||
}
|
||||
if (types.getAny() > 0) {
|
||||
choice.getChoices().add("Black");
|
||||
choice.getChoices().add("Red");
|
||||
choice.getChoices().add("Blue");
|
||||
choice.getChoices().add("Green");
|
||||
choice.getChoices().add("White");
|
||||
choice.getChoices().add("Colorless");
|
||||
}
|
||||
if (!choice.getChoices().isEmpty()) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (choice.getChoices().size() == 1) {
|
||||
choice.setChoice(choice.getChoices().iterator().next());
|
||||
} else {
|
||||
player.choose(outcome, choice, game);
|
||||
}
|
||||
if (choice.getChoice() != null) {
|
||||
Mana mana = new Mana();
|
||||
switch (choice.getChoice()) {
|
||||
case "Black":
|
||||
mana.setBlack(1);
|
||||
break;
|
||||
case "Blue":
|
||||
mana.setBlue(1);
|
||||
break;
|
||||
case "Red":
|
||||
mana.setRed(1);
|
||||
break;
|
||||
case "Green":
|
||||
mana.setGreen(1);
|
||||
break;
|
||||
case "White":
|
||||
mana.setWhite(1);
|
||||
break;
|
||||
case "Colorless":
|
||||
mana.setColorless(1);
|
||||
break;
|
||||
}
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
List<Mana> netManas = new ArrayList<>();
|
||||
Mana types = getManaTypes(game, source);
|
||||
if (types.getAny() > 0) {
|
||||
netManas.add(new Mana(0, 0, 0, 0, 0, 0, 1, 0));
|
||||
return netManas;
|
||||
}
|
||||
if (types.getBlack() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.B));
|
||||
}
|
||||
if (types.getRed() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.R));
|
||||
}
|
||||
if (types.getBlue() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.U));
|
||||
}
|
||||
if (types.getGreen() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.G));
|
||||
}
|
||||
if (types.getWhite() > 0) {
|
||||
netManas.add(new Mana(ColoredManaSymbol.W));
|
||||
}
|
||||
if (types.getColorless() > 0) {
|
||||
netManas.add(Mana.ColorlessMana(1));
|
||||
}
|
||||
return netManas;
|
||||
}
|
||||
|
||||
private Mana getManaTypes(Game game, Ability source) {
|
||||
Mana types = new Mana();
|
||||
if (game == null || game.getPhase() == null) {
|
||||
return types;
|
||||
}
|
||||
List<Permanent> lands = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
|
||||
for (Permanent land : lands) {
|
||||
Abilities<Ability> manaAbilities = land.getAbilities().getManaAbilities(Zone.BATTLEFIELD);
|
||||
for (Ability basicAbility : manaAbilities) {
|
||||
ManaAbility ability = (ManaAbility) basicAbility;
|
||||
if (!(ability instanceof ReflectingPoolManaAbility) // can't get types from own ability class
|
||||
&& ability.definesMana(game)) {
|
||||
for (Mana netMana : ability.getNetMana(game)) {
|
||||
types.add(netMana);
|
||||
if (netMana.getAny() > 0) {
|
||||
return types;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReflectingPoolEffect copy() {
|
||||
return new ReflectingPoolEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,4 +150,39 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
|
|||
Assert.assertEquals("Player should be able to create 2 red mana", "{G}{G}", options.get(0).toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflecting Pool does not see Gaea's Cradle or Serra's Sanctum as
|
||||
* producing mana
|
||||
*/
|
||||
@Test
|
||||
public void testWithDifferentLands() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||
|
||||
// {T}: Add to your mana pool one mana of any type that a land you control could produce.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
|
||||
// {T}: Add to your mana pool one mana of any color that a land an opponent controls could produce.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Exotic Orchard", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
// {T}: Add to your mana pool one mana of any color that a land an opponent controls could produce.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Exotic Orchard", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 1);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("Player A should be able to create the ", "{G}{G}{G}", options.get(0).toString());
|
||||
Assert.assertEquals("Player A should be able to create the ", "{G}{G}{W}", options.get(1).toString());
|
||||
Assert.assertEquals("Player A should be able to create the ", "{G}{G}{W}", options.get(2).toString()); // ManaOption type optimzing seems not optimal yet
|
||||
Assert.assertEquals("Player A should be able to create the ", "{G}{W}{W}", options.get(3).toString());
|
||||
Assert.assertEquals("Player A should be able to create only 3 different mana options", 4, options.size());
|
||||
|
||||
options = playerB.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("Player B should be able to create the ", "{G}{W}", options.get(0).toString());
|
||||
Assert.assertEquals("Player B should be able to create the ", "{W}{W}", options.get(1).toString());
|
||||
Assert.assertEquals("Player B should be able to create only 3 different mana options", 2, options.size());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
* Copyright 20 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
|
@ -80,6 +80,7 @@ public class AnyColorLandsProduceManaAbility extends ActivatedManaAbilityImpl {
|
|||
class AnyColorLandsProduceManaEffect extends ManaEffect {
|
||||
|
||||
private final FilterPermanent filter;
|
||||
private boolean inManaTypeCalculation = false;
|
||||
|
||||
public AnyColorLandsProduceManaEffect(TargetController targetController) {
|
||||
super();
|
||||
|
@ -161,9 +162,16 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
|
|||
}
|
||||
|
||||
private Mana getManaTypes(Game game, Ability source) {
|
||||
Mana types = new Mana();
|
||||
if (game == null || game.getPhase() == null) {
|
||||
return types;
|
||||
}
|
||||
if (inManaTypeCalculation) {
|
||||
return types;
|
||||
}
|
||||
inManaTypeCalculation = true;
|
||||
// Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "needed to identify endless loop causing cards: {0}", source.getSourceObject(game).getName());
|
||||
List<Permanent> lands = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
|
||||
Mana types = new Mana();
|
||||
for (Permanent land : lands) {
|
||||
Abilities<ActivatedManaAbilityImpl> mana = land.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD);
|
||||
for (ActivatedManaAbilityImpl ability : mana) {
|
||||
|
@ -174,6 +182,7 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
inManaTypeCalculation = false;
|
||||
return types;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue