mirror of
https://github.com/correl/mage.git
synced 2025-01-11 19:13:02 +00:00
* Fixed available mana generation for Caged Sun and storage lands (e.g. Calciform Pools) related to #6698.
This commit is contained in:
parent
08d1eb5319
commit
7ad7d5f03d
13 changed files with 383 additions and 157 deletions
|
@ -1,5 +1,8 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -18,8 +21,6 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author BetaSteward
|
||||
*/
|
||||
|
@ -135,6 +136,19 @@ class CagedSunEffect extends ManaEffect {
|
|||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
if (game != null && game.inCheckPlayableState()) {
|
||||
ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color");
|
||||
if (color != null) {
|
||||
List<Mana> availableNetMana = new ArrayList<>();
|
||||
availableNetMana.add(new Mana(ColoredManaSymbol.lookup(color.toString().charAt(0))));
|
||||
return availableNetMana;
|
||||
}
|
||||
}
|
||||
return super.getNetMana(game, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(Game game, Ability source) {
|
||||
if (game != null) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -7,9 +6,10 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -26,17 +26,18 @@ import mage.counters.CounterType;
|
|||
public final class CalciformPools extends CardImpl {
|
||||
|
||||
public CalciformPools(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// {tap}: Add {C}.
|
||||
// {T}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
// {1}, {tap}: Put a storage counter on Calciform Pools.
|
||||
// {1}, {T}: Put a storage counter on Calciform Pools.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance()), new GenericManaCost(1));
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
// {1}, Remove X storage counters from Calciform Pools: Add X mana in any combination of {W} and/or {U}.
|
||||
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.W, ColoredManaSymbol.U),
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance,
|
||||
new CountersSourceCount(CounterType.STORAGE), ColoredManaSymbol.W, ColoredManaSymbol.U),
|
||||
new GenericManaCost(1));
|
||||
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
|
||||
this.addAbility(ability);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -7,9 +6,10 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -26,7 +26,7 @@ import mage.counters.CounterType;
|
|||
public final class DreadshipReef extends CardImpl {
|
||||
|
||||
public DreadshipReef(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// {tap}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
|
@ -36,7 +36,8 @@ public final class DreadshipReef extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
// {1}, Remove X storage counters from Dreadship Reef: Add X mana in any combination of {U} and/or {B}.
|
||||
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.U, ColoredManaSymbol.B),
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance,
|
||||
new CountersSourceCount(CounterType.STORAGE), ColoredManaSymbol.U, ColoredManaSymbol.B),
|
||||
new GenericManaCost(1));
|
||||
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
|
||||
this.addAbility(ability);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.f;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -7,9 +6,10 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -26,7 +26,7 @@ import mage.counters.CounterType;
|
|||
public final class FungalReaches extends CardImpl {
|
||||
|
||||
public FungalReaches(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// {tap}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
|
@ -38,7 +38,8 @@ public final class FungalReaches extends CardImpl {
|
|||
|
||||
// {1}, Remove X storage counters from Fungal Reaches: Add X mana in any combination of {R} and/or {G}.
|
||||
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.R, ColoredManaSymbol.G),
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance,
|
||||
new CountersSourceCount(CounterType.STORAGE), ColoredManaSymbol.R, ColoredManaSymbol.G),
|
||||
new GenericManaCost(1));
|
||||
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
|
||||
this.addAbility(ability);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -7,9 +6,10 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -26,7 +26,7 @@ import mage.counters.CounterType;
|
|||
public final class MoltenSlagheap extends CardImpl {
|
||||
|
||||
public MoltenSlagheap(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// {tap}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
|
@ -36,7 +36,8 @@ public final class MoltenSlagheap extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
// {1}, Remove X storage counters from Molten Slagheap: Add X mana in any combination of {B} and/or {R}.
|
||||
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.B, ColoredManaSymbol.R),
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance,
|
||||
new CountersSourceCount(CounterType.STORAGE), ColoredManaSymbol.B, ColoredManaSymbol.R),
|
||||
new GenericManaCost(1));
|
||||
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
|
||||
this.addAbility(ability);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -7,9 +6,10 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -26,7 +26,7 @@ import mage.counters.CounterType;
|
|||
public final class SaltcrustedSteppe extends CardImpl {
|
||||
|
||||
public SaltcrustedSteppe(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// {tap}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
|
@ -36,7 +36,8 @@ public final class SaltcrustedSteppe extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
// {1}, Remove X storage counters from Saltcrusted Steppe: Add X mana in any combination of {G} and/or {W}.
|
||||
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.G, ColoredManaSymbol.W),
|
||||
new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance,
|
||||
new CountersSourceCount(CounterType.STORAGE), ColoredManaSymbol.G, ColoredManaSymbol.W),
|
||||
new GenericManaCost(1));
|
||||
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
|
||||
this.addAbility(ability);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -51,7 +50,7 @@ public final class SelvalaHeartOfTheWilds extends CardImpl {
|
|||
|
||||
// {G}, {T}: Add X mana in any combination of colors, where X is the greatest power among creatures you control.
|
||||
ManaEffect manaEffect = new AddManaInAnyCombinationEffect(
|
||||
GreatestPowerAmongControlledCreaturesValue.instance, rule2,
|
||||
GreatestPowerAmongControlledCreaturesValue.instance, GreatestPowerAmongControlledCreaturesValue.instance, rule2,
|
||||
ColoredManaSymbol.B, ColoredManaSymbol.U, ColoredManaSymbol.R, ColoredManaSymbol.W, ColoredManaSymbol.G);
|
||||
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, manaEffect, new ManaCostsImpl("{G}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
|
@ -130,4 +129,4 @@ class GreatestPowerPredicate implements Predicate<Permanent> {
|
|||
public String toString() {
|
||||
return "Greatest Power";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.mana;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -35,7 +34,6 @@ public class ManaSourceTest extends CardTestPlayerBase {
|
|||
|
||||
assertPermanentCount(playerB, "Myr Superion", 0);
|
||||
assertHandCount(playerB, "Myr Superion", 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.mage.test.cards.mana;
|
|||
import mage.abilities.mana.ManaOptions;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
@ -90,4 +91,112 @@ public class TappedForManaRelatedTest extends CardTestPlayerBase {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCalciformPools() {
|
||||
// {T}: Add {C}.
|
||||
// {1}, {T}: Put a storage counter on Calciform Pools.
|
||||
// {1}, Remove X storage counters from Calciform Pools: Add X mana in any combination of {W} and/or {U}.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Calciform Pools", 1);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||
assertManaOptions("{C}", manaOptions);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCalciformPools2Counter() {
|
||||
// {T}: Add {C}.
|
||||
// {1}, {T}: Put a storage counter on Calciform Pools.
|
||||
// {1}, Remove X storage counters from Calciform Pools: Add X mana in any combination of {W} and/or {U}.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Calciform Pools", 1);
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Calciform Pools", CounterType.STORAGE, 2);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertCounterCount("Calciform Pools", CounterType.STORAGE, 2);
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||
assertManaOptions("{W}{W}", manaOptions);
|
||||
assertManaOptions("{W}{U}", manaOptions);
|
||||
assertManaOptions("{U}{U}", manaOptions);
|
||||
assertManaOptions("{C}", manaOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCalciformPools2CounterAndTrigger() {
|
||||
setStrictChooseMode(true);
|
||||
// {T}: Add {C}.
|
||||
// {1}, {T}: Put a storage counter on Calciform Pools.
|
||||
// {1}, Remove X storage counters from Calciform Pools: Add X mana in any combination of {W} and/or {U}.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Calciform Pools", 1);
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Calciform Pools", CounterType.STORAGE, 2);
|
||||
|
||||
// As Caged Sun enters the battlefield, choose a color.
|
||||
// Creatures you control of the chosen color get +1/+1.
|
||||
// Whenever a land's ability adds one or more mana of the chosen color, add one additional mana of that color.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Caged Sun", 1);
|
||||
setChoice(playerA, "White");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertCounterCount("Calciform Pools", CounterType.STORAGE, 2);
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||
assertManaOptions("{W}{W}{W}", manaOptions);
|
||||
assertManaOptions("{W}{W}{U}", manaOptions);
|
||||
assertManaOptions("{U}{U}", manaOptions);
|
||||
assertManaOptions("{C}", manaOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCastleSengir() {
|
||||
setStrictChooseMode(true);
|
||||
// {T}: Add Colorless.
|
||||
// {1}, {T}: Add Black.
|
||||
// {2}, {T}: Add Blue or Red.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Castle Sengir", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
||||
assertManaOptions("{C}{R}", manaOptions);
|
||||
assertManaOptions("{B}", manaOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCastleSengir2() {
|
||||
setStrictChooseMode(true);
|
||||
// {T}: Add {C}.
|
||||
// {1}, {T}: Add {B}.
|
||||
// {2}, {T}: Add {U} or {R}.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Castle Sengir", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||
assertManaOptions("{C}{W}{W}", manaOptions);
|
||||
assertManaOptions("{W}{B}", manaOptions);
|
||||
assertManaOptions("{U}", manaOptions);
|
||||
assertManaOptions("{R}", manaOptions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,13 +43,13 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
* Creates a {@link Mana} object with the passed in values. Values can not
|
||||
* be less than 0. Any values less than 0 will be logged and set to 0.
|
||||
*
|
||||
* @param red total Red mana to have.
|
||||
* @param green total Green mana to have.
|
||||
* @param blue total Blue mana to have.
|
||||
* @param white total White mana to have.
|
||||
* @param black total Black mana to have.
|
||||
* @param generic total Generic mana to have.
|
||||
* @param any total Any mana to have.
|
||||
* @param red total Red mana to have.
|
||||
* @param green total Green mana to have.
|
||||
* @param blue total Blue mana to have.
|
||||
* @param white total White mana to have.
|
||||
* @param black total Black mana to have.
|
||||
* @param generic total Generic mana to have.
|
||||
* @param any total Any mana to have.
|
||||
* @param colorless total Colorless mana to have.
|
||||
*/
|
||||
public Mana(final int red, final int green, final int blue, final int white, final int black, final int generic, final int any, final int colorless) {
|
||||
|
@ -142,6 +142,35 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
}
|
||||
}
|
||||
|
||||
public Mana(final ManaType manaType, int num) {
|
||||
Objects.requireNonNull(manaType, "The passed in ManaType can not be null");
|
||||
switch (manaType) {
|
||||
case GREEN:
|
||||
green = num;
|
||||
break;
|
||||
case RED:
|
||||
red = num;
|
||||
break;
|
||||
case BLACK:
|
||||
black = num;
|
||||
break;
|
||||
case BLUE:
|
||||
blue = num;
|
||||
break;
|
||||
case WHITE:
|
||||
white = num;
|
||||
break;
|
||||
case COLORLESS:
|
||||
colorless = num;
|
||||
break;
|
||||
case GENERIC:
|
||||
generic = num;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown manaType: " + manaType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Mana} object with the passed in {@code num} of Red mana.
|
||||
* {@code num} can not be a negative value. Negative values will be logged
|
||||
|
@ -161,7 +190,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param num value of Green mana to create.
|
||||
* @return a {@link Mana} object with the passed in {@code num} of Green
|
||||
* mana.
|
||||
* mana.
|
||||
*/
|
||||
public static Mana GreenMana(int num) {
|
||||
return new Mana(0, notNegative(num, "Green"), 0, 0, 0, 0, 0, 0);
|
||||
|
@ -174,7 +203,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param num value of Blue mana to create.
|
||||
* @return a {@link Mana} object with the passed in {@code num} of Blue
|
||||
* mana.
|
||||
* mana.
|
||||
*/
|
||||
public static Mana BlueMana(int num) {
|
||||
return new Mana(0, 0, notNegative(num, "Blue"), 0, 0, 0, 0, 0);
|
||||
|
@ -187,7 +216,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param num value of White mana to create.
|
||||
* @return a {@link Mana} object with the passed in {@code num} of White
|
||||
* mana.
|
||||
* mana.
|
||||
*/
|
||||
public static Mana WhiteMana(int num) {
|
||||
return new Mana(0, 0, 0, notNegative(num, "White"), 0, 0, 0, 0);
|
||||
|
@ -200,7 +229,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param num value of Black mana to create.
|
||||
* @return a {@link Mana} object with the passed in {@code num} of Black
|
||||
* mana.
|
||||
* mana.
|
||||
*/
|
||||
public static Mana BlackMana(int num) {
|
||||
return new Mana(0, 0, 0, 0, notNegative(num, "Black"), 0, 0, 0);
|
||||
|
@ -213,7 +242,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param num value of Generic mana to create.
|
||||
* @return a {@link Mana} object with the passed in {@code num} of Generic
|
||||
* mana.
|
||||
* mana.
|
||||
*/
|
||||
public static Mana GenericMana(int num) {
|
||||
return new Mana(0, 0, 0, 0, 0, notNegative(num, "Generic"), 0, 0);
|
||||
|
@ -226,7 +255,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param num value of Colorless mana to create.
|
||||
* @return a {@link Mana} object with the passed in {@code num} of Colorless
|
||||
* mana.
|
||||
* mana.
|
||||
*/
|
||||
public static Mana ColorlessMana(int num) {
|
||||
return new Mana(0, 0, 0, 0, 0, 0, 0, notNegative(num, "Colorless"));
|
||||
|
@ -444,7 +473,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param filter the colors of mana to return the count for.
|
||||
* @return the count of filtered mana provided by the passed in
|
||||
* {@link FilterMana}.
|
||||
* {@link FilterMana}.
|
||||
*/
|
||||
public int count(final FilterMana filter) {
|
||||
if (filter == null) {
|
||||
|
@ -898,10 +927,10 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
* Returns if this objects mana contains any coloured mana the same as the
|
||||
* passed in {@link Mana}'s mana.
|
||||
*
|
||||
* @param mana the mana to check for
|
||||
* @param mana the mana to check for
|
||||
* @param includeColorless also check for colorless
|
||||
* @return true if this contains any of the same type of coloured mana that
|
||||
* this has
|
||||
* this has
|
||||
*/
|
||||
public boolean containsAny(final Mana mana, boolean includeColorless) {
|
||||
if (mana.black > 0 && this.black > 0) {
|
||||
|
@ -929,7 +958,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param color the color to return the count for.
|
||||
* @return the total count of mana in this object as specified by the passed
|
||||
* in {@link ColoredManaSymbol}.
|
||||
* in {@link ColoredManaSymbol}.
|
||||
*/
|
||||
public int getColor(final ColoredManaSymbol color) {
|
||||
if (color == ColoredManaSymbol.G) {
|
||||
|
@ -956,7 +985,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param manaType the type to return the count for.
|
||||
* @return the total count of mana in this object as specified by the passed
|
||||
* in {@link ManaType}.
|
||||
* in {@link ManaType}.
|
||||
*/
|
||||
public int get(final ManaType manaType) {
|
||||
switch (manaType) {
|
||||
|
@ -981,7 +1010,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
* {@code amount} .
|
||||
*
|
||||
* @param manaType the color of the mana to set
|
||||
* @param amount the value to set the mana too
|
||||
* @param amount the value to set the mana too
|
||||
*/
|
||||
public void set(final ManaType manaType, final int amount) {
|
||||
switch (manaType) {
|
||||
|
@ -1056,7 +1085,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
*
|
||||
* @param mana the mana to compare with
|
||||
* @return if this object has more than or equal mana to the passed in
|
||||
* {@link Mana}.
|
||||
* {@link Mana}.
|
||||
*/
|
||||
public boolean includesMana(Mana mana) {
|
||||
return this.green >= mana.green
|
||||
|
@ -1217,10 +1246,10 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
* is negative, it is logged and 0 is returned.
|
||||
*
|
||||
* @param value the value to check.
|
||||
* @param name the name of the value to check. Used to make logging of the
|
||||
* {@code value} easier
|
||||
* @param name the name of the value to check. Used to make logging of the
|
||||
* {@code value} easier
|
||||
* @return the {@code value} passed in, unless it is minus, in which case 0
|
||||
* is returned.
|
||||
* is returned.
|
||||
*/
|
||||
private static int notNegative(int value, final String name) {
|
||||
if (value < 0) {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package mage.abilities.effects.mana;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
|
@ -10,10 +13,6 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
@ -21,20 +20,22 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
|
|||
|
||||
private ArrayList<ColoredManaSymbol> manaSymbols = new ArrayList<>();
|
||||
private final DynamicValue amount;
|
||||
private final DynamicValue netAmount;
|
||||
|
||||
public AddManaInAnyCombinationEffect(int amount) {
|
||||
this(StaticValue.get(amount), ColoredManaSymbol.B, ColoredManaSymbol.U, ColoredManaSymbol.R, ColoredManaSymbol.W, ColoredManaSymbol.G);
|
||||
this(StaticValue.get(amount), StaticValue.get(amount), ColoredManaSymbol.B, ColoredManaSymbol.U, ColoredManaSymbol.R, ColoredManaSymbol.W, ColoredManaSymbol.G);
|
||||
}
|
||||
|
||||
public AddManaInAnyCombinationEffect(int amount, ColoredManaSymbol... coloredManaSymbols) {
|
||||
this(StaticValue.get(amount), coloredManaSymbols);
|
||||
this(StaticValue.get(amount), StaticValue.get(amount), coloredManaSymbols);
|
||||
}
|
||||
|
||||
public AddManaInAnyCombinationEffect(DynamicValue amount, ColoredManaSymbol... coloredManaSymbols) {
|
||||
public AddManaInAnyCombinationEffect(DynamicValue amount, DynamicValue netAmount, ColoredManaSymbol... coloredManaSymbols) {
|
||||
super();
|
||||
this.manaSymbols.addAll(Arrays.asList(coloredManaSymbols));
|
||||
this.amount = amount;
|
||||
this.staticText = setText();
|
||||
this.netAmount = netAmount;
|
||||
}
|
||||
|
||||
public AddManaInAnyCombinationEffect(int amount, String text) {
|
||||
|
@ -47,8 +48,8 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
|
|||
this.staticText = text;
|
||||
}
|
||||
|
||||
public AddManaInAnyCombinationEffect(DynamicValue amount, String text, ColoredManaSymbol... coloredManaSymbols) {
|
||||
this(amount, coloredManaSymbols);
|
||||
public AddManaInAnyCombinationEffect(DynamicValue amount, DynamicValue netAmount, String text, ColoredManaSymbol... coloredManaSymbols) {
|
||||
this(amount, netAmount, coloredManaSymbols);
|
||||
this.staticText = text;
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,11 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
|
|||
super(effect);
|
||||
this.manaSymbols = effect.manaSymbols;
|
||||
this.amount = effect.amount;
|
||||
if (effect.netAmount != null) {
|
||||
this.netAmount = effect.netAmount.copy();
|
||||
} else {
|
||||
this.netAmount = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,16 +73,51 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
|
|||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
List<Mana> netMana = new ArrayList<>();
|
||||
if (game != null) {
|
||||
int amountOfManaLeft = amount.calculate(game, source, this);
|
||||
if (amountOfManaLeft > 0) {
|
||||
netMana.add(Mana.AnyMana(amountOfManaLeft));
|
||||
if (game.inCheckPlayableState()) {
|
||||
int amountAvailableMana = netAmount.calculate(game, source, this);
|
||||
if (amountAvailableMana > 0) {
|
||||
if (manaSymbols.size() == 5) { // Any color
|
||||
netMana.add(new Mana(0, 0, 0, 0, 0, 0, amountAvailableMana, 0));
|
||||
} else {
|
||||
generatePossibleManaCombinations(netMana, manaSymbols, amountAvailableMana);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int amountOfManaLeft = amount.calculate(game, source, this);
|
||||
if (amountOfManaLeft > 0) {
|
||||
netMana.add(Mana.AnyMana(amountOfManaLeft));
|
||||
}
|
||||
}
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
|
||||
private void generatePossibleManaCombinations(List<Mana> combinations, ArrayList<ColoredManaSymbol> manaSymbols, int amountAvailableMana) {
|
||||
List<Mana> copy = new ArrayList<>();
|
||||
for (int i = 0; i < amountAvailableMana; i++) {
|
||||
for (ColoredManaSymbol colorSymbol : manaSymbols) {
|
||||
if (i == 0) {
|
||||
combinations.add(new Mana(colorSymbol));
|
||||
} else {
|
||||
for (Mana prevMana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(prevMana);
|
||||
newMana.add(new Mana(colorSymbol));
|
||||
combinations.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i + 1 < amountAvailableMana) {
|
||||
copy.clear();
|
||||
copy.addAll(combinations);
|
||||
combinations.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(Game game, Ability source) {
|
||||
public Mana produceMana(Game game, Ability source
|
||||
) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Mana mana = new Mana();
|
||||
|
|
|
@ -45,7 +45,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
//if there is only one mana option available add it to all the existing options
|
||||
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
||||
if (netManas.size() == 1) {
|
||||
checkTappedForManaReplacement(abilities.get(0), game, netManas.get(0));
|
||||
checkManaReplacementAndTriggeredMana(abilities.get(0), game, netManas.get(0));
|
||||
addMana(netManas.get(0));
|
||||
addTriggeredMana(game, abilities.get(0));
|
||||
} else if (netManas.size() > 1) {
|
||||
|
@ -58,7 +58,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
this.clear();
|
||||
for (ActivatedManaAbilityImpl ability : abilities) {
|
||||
for (Mana netMana : ability.getNetMana(game)) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
SkipAddMana:
|
||||
for (Mana mana : copy) {
|
||||
|
@ -91,7 +91,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
for (Mana mana : copy) {
|
||||
if (!hasTapCost(ability) || checkTappedForManaReplacement(ability, game, netMana)) {
|
||||
if (!hasTapCost(ability) || checkManaReplacementAndTriggeredMana(ability, game, netMana)) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
|
@ -111,19 +111,30 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
return newList;
|
||||
}
|
||||
|
||||
private boolean checkTappedForManaReplacement(Ability ability, Game game, Mana mana) {
|
||||
/**
|
||||
* Generates triggered mana and checks replacement of Tapped_For_Mana event.
|
||||
* Also generates triggered mana for MANA_ADDED event.
|
||||
*
|
||||
* @param ability
|
||||
* @param game
|
||||
* @param mana
|
||||
* @return false if mana production was completely replaced
|
||||
*/
|
||||
private boolean checkManaReplacementAndTriggeredMana(Ability ability, Game game, Mana mana) {
|
||||
if (hasTapCost(ability)) {
|
||||
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, ability.getSourceId(), ability.getSourceId(), ability.getControllerId(), mana);
|
||||
if (!game.replaceEvent(event)) {
|
||||
game.fireEvent(event);
|
||||
return true;
|
||||
if (game.replaceEvent(event)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
game.fireEvent(event);
|
||||
}
|
||||
ManaEvent manaEvent = new ManaEvent(GameEvent.EventType.MANA_ADDED, ability.getSourceId(), ability.getSourceId(), ability.getControllerId(), mana);
|
||||
manaEvent.setData(mana.toString());
|
||||
game.fireEvent(manaEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasTapCost(Ability ability) {
|
||||
public boolean hasTapCost(Ability ability) {
|
||||
for (Cost cost : ability.getCosts()) {
|
||||
if (cost instanceof TapSourceCost) {
|
||||
return true;
|
||||
|
@ -135,50 +146,47 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
public void addManaWithCost(List<ActivatedManaAbilityImpl> abilities, Game game) {
|
||||
int replaces = 0;
|
||||
if (isEmpty()) {
|
||||
this.add(new Mana());
|
||||
this.add(new Mana()); // needed if this is the first available mana, otherwise looping over existing options woold not loop
|
||||
}
|
||||
if (!abilities.isEmpty()) {
|
||||
if (abilities.size() == 1) {
|
||||
//if there is only one mana option available add it to all the existing options
|
||||
ActivatedManaAbilityImpl ability = abilities.get(0);
|
||||
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
||||
// no mana costs
|
||||
if (ability.getManaCosts().isEmpty()) {
|
||||
if (netManas.size() == 1) {
|
||||
checkTappedForManaReplacement(ability, game, netManas.get(0));
|
||||
addMana(netManas.get(0));
|
||||
addTriggeredMana(game, ability);
|
||||
} else {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
this.add(newMana);
|
||||
if (netManas.size() > 0) { // ability can produce mana
|
||||
ActivatedManaAbilityImpl ability = abilities.get(0);
|
||||
// The ability has no mana costs
|
||||
if (ability.getManaCosts().isEmpty()) { // No mana costs, so no mana to subtract from available
|
||||
if (netManas.size() == 1) {
|
||||
checkManaReplacementAndTriggeredMana(ability, game, netManas.get(0));
|
||||
addMana(netManas.get(0));
|
||||
addTriggeredMana(game, ability);
|
||||
} else {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else // the ability has mana costs
|
||||
if (netManas.size() == 1) {
|
||||
checkTappedForManaReplacement(ability, game, netManas.get(0));
|
||||
subtractCostAddMana(ability.getManaCosts().getMana(), netManas.get(0), ability.getCosts().isEmpty());
|
||||
addTriggeredMana(game, ability);
|
||||
} else {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
subtractCostAddMana(ability.getManaCosts().getMana(), netMana, ability.getCosts().isEmpty());
|
||||
} else {// The ability has mana costs
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana prevMana : copy) {
|
||||
Mana startingMana = prevMana.copy();
|
||||
if (!subtractCostAddMana(ability.getManaCosts().getMana(), triggeredManaVariation, ability.getCosts().isEmpty(), startingMana)) {
|
||||
// the starting mana includes mana parts that the increased mana does not include, so add starting mana also as an option
|
||||
add(prevMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,7 +199,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
List<Mana> netManas = ability.getNetMana(game);
|
||||
if (ability.getManaCosts().isEmpty()) {
|
||||
for (Mana netMana : netManas) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
|
@ -203,7 +211,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
}
|
||||
} else {
|
||||
for (Mana netMana : netManas) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana previousMana : copy) {
|
||||
CombineWithExisting:
|
||||
|
@ -322,58 +330,68 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
return new ManaOptions(this);
|
||||
}
|
||||
|
||||
public void subtractCostAddMana(Mana cost, Mana addMana, boolean onlyManaCosts) {
|
||||
if (isEmpty()) {
|
||||
this.add(new Mana());
|
||||
}
|
||||
/**
|
||||
* Performs the simulation of a mana ability with costs
|
||||
*
|
||||
* @param cost cost to use the ability
|
||||
* @param manaToAdd one mana variation that can be added by using
|
||||
* this ability
|
||||
* @param onlyManaCosts flag to know if the costs are mana costs only
|
||||
* @param currentMana the mana available before the usage of the
|
||||
* ability
|
||||
* @param oldManaWasReplaced returns the info if the new complete mana does
|
||||
* replace the current mana completely
|
||||
*/
|
||||
private boolean subtractCostAddMana(Mana cost, Mana manaToAdd, boolean onlyManaCosts, Mana currentMana) {
|
||||
boolean oldManaWasReplaced = false; // true if the newly created mana includes all mana possibilities of the old
|
||||
boolean repeatable = false;
|
||||
if (addMana.getAny() == 1 && addMana.count() == 1 && onlyManaCosts) {
|
||||
if (manaToAdd.getAny() == 1 && manaToAdd.count() == 1 && onlyManaCosts) {
|
||||
// deactivated because it does cause loops TODO: Find reason
|
||||
repeatable = true; // only replace to any with mana costs only will be repeated if able
|
||||
}
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana mana : copy) {
|
||||
Mana oldMan = mana.copy();
|
||||
if (mana.includesMana(cost)) { // it can be paid
|
||||
// generic mana costs can be paid with different colored mana, can lead to different color combinations
|
||||
if (cost.getGeneric() > 0 && cost.getGeneric() > (mana.getGeneric() + mana.getColorless())) {
|
||||
Mana coloredCost = cost.copy();
|
||||
coloredCost.setGeneric(0);
|
||||
mana.subtract(coloredCost);
|
||||
boolean oldManaWasReplaced = false;
|
||||
for (Mana payCombination : getPossiblePayCombinations(cost.getGeneric(), mana)) {
|
||||
Mana newMana = mana.copy();
|
||||
newMana.subtract(payCombination);
|
||||
newMana.add(addMana);
|
||||
Mana moreValuable = Mana.getMoreValuableMana(oldMan, newMana);
|
||||
if (!oldMan.equals(moreValuable)) {
|
||||
this.add(newMana);
|
||||
if (moreValuable != null) {
|
||||
oldManaWasReplaced = true; // the new mana includes all possibilities of the old one
|
||||
}
|
||||
Mana prevMana = currentMana.copy();
|
||||
if (currentMana.includesMana(cost)) { // it can be paid
|
||||
// generic mana costs can be paid with different colored mana, can lead to different color combinations
|
||||
if (cost.getGeneric() > 0 && cost.getGeneric() > (currentMana.getGeneric() + currentMana.getColorless())) {
|
||||
Mana coloredCost = cost.copy();
|
||||
coloredCost.setGeneric(0);
|
||||
currentMana.subtract(coloredCost);
|
||||
for (Mana payCombination : getPossiblePayCombinations(cost.getGeneric(), currentMana)) {
|
||||
Mana newMana = currentMana.copy();
|
||||
newMana.subtract(payCombination);
|
||||
newMana.add(manaToAdd);
|
||||
Mana moreValuable = Mana.getMoreValuableMana(prevMana, newMana);
|
||||
if (!prevMana.equals(moreValuable)) {
|
||||
this.add(newMana);
|
||||
if (moreValuable != null) {
|
||||
oldManaWasReplaced = true; // the new mana includes all possibilities of the old one
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!oldManaWasReplaced) {
|
||||
this.add(oldMan);
|
||||
}
|
||||
} else {
|
||||
while (mana.includesMana(cost)) {
|
||||
mana.subtractCost(cost);
|
||||
mana.add(addMana);
|
||||
if (!repeatable) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Don't use mana that only reduce the available mana
|
||||
if (oldMan.contains(mana) && oldMan.count() > mana.count()) {
|
||||
mana.setToMana(oldMan);
|
||||
}
|
||||
this.add(mana);
|
||||
}
|
||||
} else {
|
||||
while (currentMana.includesMana(cost)) { // loop for multiple usage if possible
|
||||
currentMana.subtractCost(cost);
|
||||
currentMana.add(manaToAdd);
|
||||
if (!repeatable) {
|
||||
break; // Stop adding multiple usages of the ability
|
||||
}
|
||||
}
|
||||
// Don't use mana that only reduce the available mana
|
||||
if (prevMana.contains(currentMana) && prevMana.count() > currentMana.count()) {
|
||||
currentMana.setToMana(prevMana);
|
||||
}
|
||||
Mana moreValuable = Mana.getMoreValuableMana(prevMana, currentMana);
|
||||
if (!prevMana.equals(moreValuable)) {
|
||||
this.add(currentMana);
|
||||
if (moreValuable != null) {
|
||||
oldManaWasReplaced = true; // the new mana includes all possibilities of the old one
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return oldManaWasReplaced;
|
||||
}
|
||||
|
||||
private List<Mana> getPossiblePayCombinations(int number, Mana manaAvailable) {
|
||||
|
|
|
@ -2890,11 +2890,24 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
boolean withCost = false;
|
||||
Abilities<ActivatedManaAbilityImpl> manaAbilities
|
||||
= permanent.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game);
|
||||
for (ActivatedManaAbilityImpl ability : manaAbilities) {
|
||||
for (Iterator<ActivatedManaAbilityImpl> it = manaAbilities.iterator(); it.hasNext();) {
|
||||
ActivatedManaAbilityImpl ability = it.next();
|
||||
if (canUse == null) {
|
||||
canUse = permanent.canUseActivatedAbilities(game);
|
||||
}
|
||||
if (canUse && ability.canActivate(playerId, game).canActivate()) {
|
||||
// abilities without Tap costs have to be handled as separate sources, because they can be used also
|
||||
if (!availableMana.hasTapCost(ability)) {
|
||||
it.remove();
|
||||
Abilities<ActivatedManaAbilityImpl> noTapAbilities = new AbilitiesImpl<>(ability);
|
||||
if (ability.getManaCosts().isEmpty()) {
|
||||
sourceWithoutManaCosts.add(noTapAbilities);
|
||||
} else {
|
||||
sourceWithCosts.add(noTapAbilities);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
canAdd = true;
|
||||
if (!ability.getManaCosts().isEmpty()) {
|
||||
withCost = true;
|
||||
|
|
Loading…
Reference in a new issue