mirror of
https://github.com/correl/mage.git
synced 2024-12-24 03:00:14 +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.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,17 +56,22 @@ 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}"));
|
||||
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}"));
|
||||
"Remove X storage counters from {this}"));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
@ -106,9 +118,16 @@ public class DynamicManaEffect extends BasicManaEffect {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Mana computeMana(boolean netMana ,Game game, Ability source){
|
||||
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) {
|
||||
|
@ -126,7 +145,7 @@ public class DynamicManaEffect extends BasicManaEffect {
|
|||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ChoiceColor choiceColor = new ChoiceColor();
|
||||
for(int i = 0; i < count; i++){
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!choiceColor.isChosen()) {
|
||||
while (!controller.choose(Outcome.Benefit, choiceColor, game)) {
|
||||
if (!controller.isInGame()) {
|
||||
|
@ -150,7 +169,7 @@ public class DynamicManaEffect extends BasicManaEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
computedMana.setColorless(count);
|
||||
}
|
||||
|
|
|
@ -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,8 +110,9 @@ 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;
|
||||
}
|
||||
return newNetMana;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue