mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
* Mage-Ring Network - Fixed calculation of available mana.
This commit is contained in:
parent
363915075c
commit
b169e7e6c7
8 changed files with 110 additions and 31 deletions
|
@ -34,6 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.dynamicvalue.common.CountersCount;
|
||||||
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
|
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.mana.ColorlessManaAbility;
|
import mage.abilities.mana.ColorlessManaAbility;
|
||||||
|
@ -47,7 +48,7 @@ import mage.counters.CounterType;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author LoneFox
|
* @author LoneFox
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class MageRingNetwork extends CardImpl {
|
public class MageRingNetwork extends CardImpl {
|
||||||
|
|
||||||
|
@ -55,17 +56,22 @@ public class MageRingNetwork extends CardImpl {
|
||||||
super(ownerId, 249, "Mage-Ring Network", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
|
super(ownerId, 249, "Mage-Ring Network", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, "");
|
||||||
this.expansionSetCode = "ORI";
|
this.expansionSetCode = "ORI";
|
||||||
|
|
||||||
// {t}: Add {1} to your mana pool.
|
// {T}: Add {1} to your mana pool.
|
||||||
this.addAbility(new ColorlessManaAbility());
|
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()),
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance()),
|
||||||
new ManaCostsImpl("{1}"));
|
new ManaCostsImpl("{1}"));
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
// {t}, Remove X storage counters from Mage-Ring Network: 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(), "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(),
|
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(),
|
||||||
"Remove X storage counters from {this}"));
|
"Remove X storage counters from {this}"));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ package org.mage.test.utils;
|
||||||
import mage.abilities.mana.ManaOptions;
|
import mage.abilities.mana.ManaOptions;
|
||||||
import mage.constants.PhaseStep;
|
import mage.constants.PhaseStep;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -290,6 +291,43 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
Assert.assertEquals("{B}{B}{B}", getManaOption(1, manaOptions));
|
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
|
@Test
|
||||||
@Ignore // TriggeredManaAbilities not supported yet for getAvailableMana
|
@Ignore // TriggeredManaAbilities not supported yet for getAvailableMana
|
||||||
public void testCryptGhast() {
|
public void testCryptGhast() {
|
||||||
|
|
|
@ -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
|
* Returns the mana that is more colored or has a greater amount but does
|
||||||
* in any color but colorless if you call with {1}{W}{R} and {G}{W}{R} you
|
* not contain one less mana in any color but colorless if you call with
|
||||||
* get back {G}{W}{R} if you call with {G}{W}{R} and {G}{W}{R} you get back
|
* {1}{W}{R} and {G}{W}{R} you get back {G}{W}{R} if you call with {G}{W}{R}
|
||||||
* {G}{W}{R} if you call with {G}{W}{B} and {G}{W}{R} you get back null
|
* 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 mana1
|
||||||
* @param mana2
|
* @param mana2
|
||||||
|
@ -609,7 +610,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
public static Mana getMoreValuableMana(Mana mana1, Mana mana2) {
|
public static Mana getMoreValuableMana(Mana mana1, Mana mana2) {
|
||||||
Mana moreMana;
|
Mana moreMana;
|
||||||
Mana lessMana;
|
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;
|
moreMana = mana2;
|
||||||
lessMana = mana1;
|
lessMana = mana1;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package mage.abilities.dynamicvalue.common;
|
package mage.abilities.dynamicvalue.common;
|
||||||
|
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.dynamicvalue.DynamicValue;
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
public class CountersCount implements DynamicValue {
|
public class CountersCount implements DynamicValue {
|
||||||
|
|
||||||
private final CounterType counter;
|
private final CounterType counter;
|
||||||
|
|
||||||
public CountersCount(CounterType counter) {
|
public CountersCount(CounterType counter) {
|
||||||
|
|
|
@ -44,32 +44,39 @@ public class DynamicManaEffect extends BasicManaEffect {
|
||||||
|
|
||||||
private final Mana computedMana;
|
private final Mana computedMana;
|
||||||
private final DynamicValue amount;
|
private final DynamicValue amount;
|
||||||
|
private final DynamicValue netAmount;
|
||||||
private String text = null;
|
private String text = null;
|
||||||
private boolean oneChoice;
|
private boolean oneChoice;
|
||||||
|
|
||||||
public DynamicManaEffect(Mana mana, DynamicValue amount) {
|
public DynamicManaEffect(Mana mana, DynamicValue amount) {
|
||||||
super(mana);
|
this(mana, amount, null);
|
||||||
this.amount = amount;
|
|
||||||
computedMana = new Mana();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicManaEffect(Mana mana, DynamicValue amount, String text) {
|
public DynamicManaEffect(Mana mana, DynamicValue amount, String text) {
|
||||||
this(mana, amount, text, false);
|
this(mana, amount, text, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DynamicManaEffect(Mana mana, DynamicValue amount, String text, boolean oneChoice) {
|
||||||
|
this(mana, amount, text, oneChoice, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param mana
|
* @param mana
|
||||||
* @param amount
|
* @param amount
|
||||||
* @param text
|
* @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);
|
super(mana);
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
computedMana = new Mana();
|
computedMana = new Mana();
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.oneChoice = oneChoice;
|
this.oneChoice = oneChoice;
|
||||||
|
this.netAmount = netAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicManaEffect(final DynamicManaEffect effect) {
|
public DynamicManaEffect(final DynamicManaEffect effect) {
|
||||||
|
@ -78,6 +85,11 @@ public class DynamicManaEffect extends BasicManaEffect {
|
||||||
this.amount = effect.amount.copy();
|
this.amount = effect.amount.copy();
|
||||||
this.text = effect.text;
|
this.text = effect.text;
|
||||||
this.oneChoice = effect.oneChoice;
|
this.oneChoice = effect.oneChoice;
|
||||||
|
if (effect.netAmount != null) {
|
||||||
|
this.netAmount = effect.netAmount.copy();
|
||||||
|
} else {
|
||||||
|
this.netAmount = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,9 +118,16 @@ public class DynamicManaEffect extends BasicManaEffect {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mana computeMana(boolean netMana ,Game game, Ability source){
|
public Mana computeMana(boolean netMana, Game game, Ability source) {
|
||||||
this.computedMana.clear();
|
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) {
|
if (mana.getBlack() > 0) {
|
||||||
computedMana.setBlack(count);
|
computedMana.setBlack(count);
|
||||||
} else if (mana.getBlue() > 0) {
|
} else if (mana.getBlue() > 0) {
|
||||||
|
@ -126,7 +145,7 @@ public class DynamicManaEffect extends BasicManaEffect {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
ChoiceColor choiceColor = new ChoiceColor();
|
ChoiceColor choiceColor = new ChoiceColor();
|
||||||
for(int i = 0; i < count; i++){
|
for (int i = 0; i < count; i++) {
|
||||||
if (!choiceColor.isChosen()) {
|
if (!choiceColor.isChosen()) {
|
||||||
while (!controller.choose(Outcome.Benefit, choiceColor, game)) {
|
while (!controller.choose(Outcome.Benefit, choiceColor, game)) {
|
||||||
if (!controller.isInGame()) {
|
if (!controller.isInGame()) {
|
||||||
|
@ -150,7 +169,7 @@ public class DynamicManaEffect extends BasicManaEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
computedMana.setColorless(count);
|
computedMana.setColorless(count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ public class DynamicManaAbility extends ManaAbility {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TapSourceCost added by default
|
* TapSourceCost added by default
|
||||||
|
*
|
||||||
* @param mana
|
* @param mana
|
||||||
* @param amount
|
* @param amount
|
||||||
*/
|
*/
|
||||||
|
@ -74,10 +75,24 @@ public class DynamicManaAbility extends ManaAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicManaAbility(Mana mana, DynamicValue amount, Cost cost, String text, boolean oneChoice) {
|
public DynamicManaAbility(Mana mana, DynamicValue amount, Cost cost, String text, boolean oneChoice) {
|
||||||
super(Zone.BATTLEFIELD, new DynamicManaEffect(mana, amount, text, oneChoice), cost);
|
this(mana, amount, cost, text, oneChoice, null);
|
||||||
manaEffect = (DynamicManaEffect) this.getEffects().get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @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) {
|
public DynamicManaAbility(final DynamicManaAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
|
@ -95,8 +110,9 @@ public class DynamicManaAbility extends ManaAbility {
|
||||||
List<Mana> newNetMana = new ArrayList<>();
|
List<Mana> newNetMana = new ArrayList<>();
|
||||||
if (game != null) {
|
if (game != null) {
|
||||||
// TODO: effects from replacement effects like Mana Reflection are not considered yet
|
// 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));
|
newNetMana.add(manaEffect.computeMana(true, game, this));
|
||||||
}
|
}
|
||||||
return newNetMana;
|
return newNetMana;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana);
|
Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana);
|
||||||
if (moreValuable != null) {
|
if (moreValuable != null) {
|
||||||
// only keep the more valuable mana
|
// only keep the more valuable mana
|
||||||
existingMana.setToMana(newMana);
|
existingMana.setToMana(moreValuable);
|
||||||
continue SkipAddMana;
|
continue SkipAddMana;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2164,7 +2164,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
public ManaOptions getManaAvailable(Game game) {
|
public ManaOptions getManaAvailable(Game game) {
|
||||||
ManaOptions available = new ManaOptions();
|
ManaOptions available = new ManaOptions();
|
||||||
|
|
||||||
List<Abilities<ManaAbility>> sourceWithoutCosts = new ArrayList<>();
|
List<Abilities<ManaAbility>> sourceWithoutManaCosts = new ArrayList<>();
|
||||||
List<Abilities<ManaAbility>> sourceWithCosts = new ArrayList<>();
|
List<Abilities<ManaAbility>> sourceWithCosts = new ArrayList<>();
|
||||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
|
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||||
boolean canAdd = false;
|
boolean canAdd = false;
|
||||||
|
@ -2183,12 +2183,12 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
if (withCost) {
|
if (withCost) {
|
||||||
sourceWithCosts.add(manaAbilities);
|
sourceWithCosts.add(manaAbilities);
|
||||||
} else {
|
} else {
|
||||||
sourceWithoutCosts.add(manaAbilities);
|
sourceWithoutManaCosts.add(manaAbilities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Abilities<ManaAbility> manaAbilities : sourceWithoutCosts) {
|
for (Abilities<ManaAbility> manaAbilities : sourceWithoutManaCosts) {
|
||||||
available.addMana(manaAbilities, game);
|
available.addMana(manaAbilities, game);
|
||||||
}
|
}
|
||||||
for (Abilities<ManaAbility> manaAbilities : sourceWithCosts) {
|
for (Abilities<ManaAbility> manaAbilities : sourceWithCosts) {
|
||||||
|
|
Loading…
Reference in a new issue