* Mage-Ring Network - Fixed calculation of available mana.

This commit is contained in:
LevelX2 2015-07-23 12:42:02 +02:00
parent 363915075c
commit b169e7e6c7
8 changed files with 110 additions and 31 deletions

View file

@ -34,6 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.CountersCount;
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.mana.ColorlessManaAbility;
@ -47,7 +48,7 @@ import mage.counters.CounterType;
/**
*
* @author LoneFox
*
*/
public class MageRingNetwork extends CardImpl {
@ -55,15 +56,20 @@ public class MageRingNetwork extends CardImpl {
super(ownerId, 249, "Mage-Ring Network", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
this.expansionSetCode = "ORI";
// {t}: Add {1} to your mana pool.
// {T}: Add {1} to your mana pool.
this.addAbility(new ColorlessManaAbility());
// {1}, {t}: Put a storage counter on Mage-Ring Network.
// {1}, {T}: Put a storage counter on Mage-Ring Network.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance()),
new ManaCostsImpl("{1}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {t}, Remove X storage counters from Mage-Ring Network: Add {x} to your mana pool.
ability = new DynamicManaAbility(Mana.ColorlessMana, new RemovedCountersForCostValue(), "Add {X} to your mana pool");
// {T}, Remove X storage counters from Mage-Ring Network: Add {x} to your mana pool.
ability = new DynamicManaAbility(
Mana.ColorlessMana,
new RemovedCountersForCostValue(),
new TapSourceCost(),
"Add {X} to your mana pool",
true, new CountersCount(CounterType.STORAGE));
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(),
"Remove X storage counters from {this}"));
this.addAbility(ability);

View file

@ -30,6 +30,7 @@ package org.mage.test.utils;
import mage.abilities.mana.ManaOptions;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
@ -290,6 +291,43 @@ public class ManaOptionsTest extends CardTestPlayerBase {
Assert.assertEquals("{B}{B}{B}", getManaOption(1, manaOptions));
}
@Test
public void testMageRingNetwork() {
// {T}: Add {1} to your mana pool.
// {T}, {1} : Put a storage counter on Mage-Ring Network.
// {T}, Remove X storage counters from Mage-Ring Network: Add {X} to your mana pool.
addCard(Zone.BATTLEFIELD, playerA, "Mage-Ring Network", 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
setStopAt(1, PhaseStep.UPKEEP);
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
Assert.assertEquals("{1}{W}{B}", getManaOption(0, manaOptions));
}
@Test
public void testMageRingNetwork2() {
// {T}: Add {1} to your mana pool.
// {T}, {1} : Put a storage counter on Mage-Ring Network.
// {T}, Remove X storage counters from Mage-Ring Network: Add {X} to your mana pool.
addCard(Zone.BATTLEFIELD, playerA, "Mage-Ring Network", 1);
addCounters(1, PhaseStep.UPKEEP, playerA, "Mage-Ring Network", CounterType.STORAGE, 4);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
setStopAt(1, PhaseStep.DRAW);
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
Assert.assertEquals("{4}{W}{B}", getManaOption(0, manaOptions));
}
@Test
@Ignore // TriggeredManaAbilities not supported yet for getAvailableMana
public void testCryptGhast() {

View file

@ -597,10 +597,11 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
}
/**
* Returns the mana that is more colored but does not contain one less mana
* in any color but colorless if you call with {1}{W}{R} and {G}{W}{R} you
* get back {G}{W}{R} if you call with {G}{W}{R} and {G}{W}{R} you get back
* {G}{W}{R} if you call with {G}{W}{B} and {G}{W}{R} you get back null
* Returns the mana that is more colored or has a greater amount but does
* not contain one less mana in any color but colorless if you call with
* {1}{W}{R} and {G}{W}{R} you get back {G}{W}{R} if you call with {G}{W}{R}
* and {G}{W}{R} you get back {G}{W}{R} if you call with {G}{W}{B} and
* {G}{W}{R} you get back null
*
* @param mana1
* @param mana2
@ -609,7 +610,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
public static Mana getMoreValuableMana(Mana mana1, Mana mana2) {
Mana moreMana;
Mana lessMana;
if (mana2.count() > mana1.count() || mana2.getAny() > mana1.getAny() || mana2.getColorless() < mana1.getColorless()) {
if (mana2.countColored() > mana1.countColored() || mana2.getAny() > mana1.getAny() || mana2.count() > mana1.count()) {
moreMana = mana2;
lessMana = mana1;
} else {

View file

@ -1,15 +1,14 @@
package mage.abilities.dynamicvalue.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
public class CountersCount implements DynamicValue {
private final CounterType counter;
public CountersCount(CounterType counter) {

View file

@ -44,32 +44,39 @@ public class DynamicManaEffect extends BasicManaEffect {
private final Mana computedMana;
private final DynamicValue amount;
private final DynamicValue netAmount;
private String text = null;
private boolean oneChoice;
public DynamicManaEffect(Mana mana, DynamicValue amount) {
super(mana);
this.amount = amount;
computedMana = new Mana();
this(mana, amount, null);
}
public DynamicManaEffect(Mana mana, DynamicValue amount, String text) {
this(mana, amount, text, false);
}
public DynamicManaEffect(Mana mana, DynamicValue amount, String text, boolean oneChoice) {
this(mana, amount, text, oneChoice, null);
}
/**
*
* @param mana
* @param amount
* @param text
* @param oneChoice is all mana from the same colour or if false the player can choose different colours
* @param oneChoice is all mana from the same colour or if false the player
* can choose different colours
* @param netAmount a dynamic value that calculates the possible available
* mana (e.g. if you have to pay by removing counters from source)
*/
public DynamicManaEffect(Mana mana, DynamicValue amount, String text, boolean oneChoice) {
public DynamicManaEffect(Mana mana, DynamicValue amount, String text, boolean oneChoice, DynamicValue netAmount) {
super(mana);
this.amount = amount;
computedMana = new Mana();
this.text = text;
this.oneChoice = oneChoice;
this.netAmount = netAmount;
}
public DynamicManaEffect(final DynamicManaEffect effect) {
@ -78,6 +85,11 @@ public class DynamicManaEffect extends BasicManaEffect {
this.amount = effect.amount.copy();
this.text = effect.text;
this.oneChoice = effect.oneChoice;
if (effect.netAmount != null) {
this.netAmount = effect.netAmount.copy();
} else {
this.netAmount = null;
}
}
@Override
@ -108,7 +120,14 @@ public class DynamicManaEffect extends BasicManaEffect {
public Mana computeMana(boolean netMana, Game game, Ability source) {
this.computedMana.clear();
int count = amount.calculate(game, source, this);
int count;
if (netMana && netAmount != null) {
// calculate the maximum available mana
count = netAmount.calculate(game, source, this);
} else {
count = amount.calculate(game, source, this);
}
if (mana.getBlack() > 0) {
computedMana.setBlack(count);
} else if (mana.getBlue() > 0) {

View file

@ -48,6 +48,7 @@ public class DynamicManaAbility extends ManaAbility {
/**
* TapSourceCost added by default
*
* @param mana
* @param amount
*/
@ -74,10 +75,24 @@ public class DynamicManaAbility extends ManaAbility {
}
public DynamicManaAbility(Mana mana, DynamicValue amount, Cost cost, String text, boolean oneChoice) {
super(Zone.BATTLEFIELD, new DynamicManaEffect(mana, amount, text, oneChoice), cost);
manaEffect = (DynamicManaEffect) this.getEffects().get(0);
this(mana, amount, cost, text, oneChoice, null);
}
/**
*
* @param mana
* @param amount
* @param cost
* @param text
* @param oneChoice is all mana from the same colour or if false the player
* can choose different colours
* @param netAmount a dynamic value that calculates the possible available
* mana (e.g. if you have to pay by removing counters from source)
*/
public DynamicManaAbility(Mana mana, DynamicValue amount, Cost cost, String text, boolean oneChoice, DynamicValue netAmount) {
super(Zone.BATTLEFIELD, new DynamicManaEffect(mana, amount, text, oneChoice, netAmount), cost);
manaEffect = (DynamicManaEffect) this.getEffects().get(0);
}
public DynamicManaAbility(final DynamicManaAbility ability) {
super(ability);
@ -95,6 +110,7 @@ public class DynamicManaAbility extends ManaAbility {
List<Mana> newNetMana = new ArrayList<>();
if (game != null) {
// TODO: effects from replacement effects like Mana Reflection are not considered yet
// TODO: effects that need a X payment (e.g. Mage-Ring Network) return always 0
newNetMana.add(manaEffect.computeMana(true, game, this));
}
return newNetMana;

View file

@ -95,7 +95,7 @@ public class ManaOptions extends ArrayList<Mana> {
Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana);
if (moreValuable != null) {
// only keep the more valuable mana
existingMana.setToMana(newMana);
existingMana.setToMana(moreValuable);
continue SkipAddMana;
}
}

View file

@ -2164,7 +2164,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public ManaOptions getManaAvailable(Game game) {
ManaOptions available = new ManaOptions();
List<Abilities<ManaAbility>> sourceWithoutCosts = new ArrayList<>();
List<Abilities<ManaAbility>> sourceWithoutManaCosts = new ArrayList<>();
List<Abilities<ManaAbility>> sourceWithCosts = new ArrayList<>();
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
boolean canAdd = false;
@ -2183,12 +2183,12 @@ public abstract class PlayerImpl implements Player, Serializable {
if (withCost) {
sourceWithCosts.add(manaAbilities);
} else {
sourceWithoutCosts.add(manaAbilities);
sourceWithoutManaCosts.add(manaAbilities);
}
}
}
for (Abilities<ManaAbility> manaAbilities : sourceWithoutCosts) {
for (Abilities<ManaAbility> manaAbilities : sourceWithoutManaCosts) {
available.addMana(manaAbilities, game);
}
for (Abilities<ManaAbility> manaAbilities : sourceWithCosts) {