* Fixed calcultion of available mana for Goblin Clearcutter, Seton Krosan Protector, Urza, Lord High Artificer, Heritage Druid, Birchlore Ranger and Grand architect.

This commit is contained in:
LevelX2 2020-07-11 16:43:38 +02:00
parent 587f05dea4
commit 81e5650972
9 changed files with 283 additions and 51 deletions

View file

@ -1,19 +1,26 @@
package mage.cards.b;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.keyword.MorphAbility;
import mage.abilities.mana.AnyColorManaAbility;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.target.common.TargetControlledCreaturePermanent;
/**
@ -22,22 +29,22 @@ import mage.target.common.TargetControlledCreaturePermanent;
*/
public final class BirchloreRangers extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped Elves you control");
static {
filter.add(Predicates.not(TappedPredicate.instance));
filter.add(SubType.ELF.getPredicate());
}
public BirchloreRangers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
this.subtype.add(SubType.ELF, SubType.DRUID);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Tap two untapped Elves you control: Add one mana of any color.
this.addAbility(new AnyColorManaAbility(new TapTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, false))));
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped Elves you control");
filter.add(Predicates.not(TappedPredicate.instance));
filter.add(SubType.ELF.getPredicate());
this.addAbility(new SimpleManaAbility(
Zone.BATTLEFIELD,
new BirchloreRangersManaEffect(filter),
new TapTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, false))));
// Morph {G}
this.addAbility(new MorphAbility(this, new ManaCostsImpl("{G}")));
}
@ -51,3 +58,35 @@ public final class BirchloreRangers extends CardImpl {
return new BirchloreRangers(this);
}
}
class BirchloreRangersManaEffect extends AddManaOfAnyColorEffect {
private final FilterPermanent filter;
public BirchloreRangersManaEffect(FilterPermanent filter) {
super(1);
this.filter = filter;
}
public BirchloreRangersManaEffect(final BirchloreRangersManaEffect effect) {
super(effect);
this.filter = effect.filter.copy();
}
@Override
public BirchloreRangersManaEffect copy() {
return new BirchloreRangersManaEffect(this);
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
if (game.inCheckPlayableState()) {
int count = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) / 2;
List<Mana> netManaCalculated = new ArrayList<>();
netManaCalculated.add(new Mana(0, 0, 0, 0, 0, 0, count * 2, 0));
return netManaCalculated;
}
return super.getNetMana(game, source);
}
}

View file

@ -56,10 +56,9 @@ public final class GoblinClearcutter extends CardImpl {
}
}
// TODO: replace by mana effect to use with mana reflection
class GoblinClearCutterManaEffect extends ManaEffect {
private List<Mana> netMana = new ArrayList<>();
private final List<Mana> netMana = new ArrayList<>();
public GoblinClearCutterManaEffect() {
super();

View file

@ -1,5 +1,7 @@
package mage.cards.g;
import java.util.ArrayList;
import java.util.List;
import mage.*;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -25,6 +27,7 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
import mage.filter.FilterPermanent;
/**
* @author BetaSteward_at_googlemail.com, nantuko
@ -56,7 +59,10 @@ public final class GrandArchitect extends CardImpl {
this.addAbility(ability);
// Tap an untapped blue creature you control: Add {C}{C}. Spend this mana only to cast artifact spells or activate abilities of artifacts.
this.addAbility(new GrandArchitectManaAbility());
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped blue creature");
filter.add(new ColorPredicate(ObjectColor.BLUE));
filter.add(Predicates.not(TappedPredicate.instance));
this.addAbility(new GrandArchitectManaAbility(filter));
}
public GrandArchitect(final GrandArchitect card) {
@ -104,20 +110,31 @@ class GrandArchitectEffect extends ContinuousEffectImpl {
class GrandArchitectManaAbility extends ActivatedManaAbilityImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped blue creature");
private final FilterPermanent filter;
static {
filter.add(new ColorPredicate(ObjectColor.BLUE));
filter.add(Predicates.not(TappedPredicate.instance));
}
GrandArchitectManaAbility() {
super(Zone.BATTLEFIELD, new BasicManaEffect(new GrandArchitectConditionalMana()), new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)));
this.netMana.add(Mana.ColorlessMana(2));
GrandArchitectManaAbility(FilterControlledCreaturePermanent filter) {
super(Zone.BATTLEFIELD, new BasicManaEffect(new GrandArchitectConditionalMana()),
new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)));
this.netMana.add(new GrandArchitectConditionalMana());
this.filter = filter;
}
GrandArchitectManaAbility(GrandArchitectManaAbility ability) {
super(ability);
this.filter = ability.filter.copy();
}
@Override
public List<Mana> getNetMana(Game game) {
if (game.inCheckPlayableState()) {
int count = game.getBattlefield().count(filter, getSourceId(), getControllerId(), game);
List<Mana> netManaCalculated = new ArrayList<>();
ConditionalMana mana = new GrandArchitectConditionalMana();
mana.setColorless(count * 2);
netManaCalculated.add(mana);
return netManaCalculated;
}
return super.getNetMana(game);
}
@Override

View file

@ -1,19 +1,24 @@
package mage.cards.h;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.target.common.TargetControlledPermanent;
/**
@ -21,15 +26,8 @@ import mage.target.common.TargetControlledPermanent;
*/
public final class HeritageDruid extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("untapped Elves you control");
static {
filter.add(Predicates.not(TappedPredicate.instance));
filter.add(SubType.ELF.getPredicate());
}
public HeritageDruid(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.DRUID);
@ -37,7 +35,13 @@ public final class HeritageDruid extends CardImpl {
this.toughness = new MageInt(1);
// Tap three untapped Elves you control: Add {G}{G}{G}.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(3), new TapTargetCost(new TargetControlledPermanent(3, 3, filter, true))));
FilterControlledPermanent filter = new FilterControlledPermanent("untapped Elves you control");
filter.add(Predicates.not(TappedPredicate.instance));
filter.add(SubType.ELF.getPredicate());
this.addAbility(new SimpleManaAbility(
Zone.BATTLEFIELD,
new HeritageDruidManaEffect(filter),
new TapTargetCost(new TargetControlledPermanent(3, 3, filter, true))));
}
public HeritageDruid(final HeritageDruid card) {
@ -49,3 +53,35 @@ public final class HeritageDruid extends CardImpl {
return new HeritageDruid(this);
}
}
class HeritageDruidManaEffect extends BasicManaEffect {
private final FilterPermanent filter;
public HeritageDruidManaEffect(FilterPermanent filter) {
super(Mana.GreenMana(3));
this.filter = filter;
}
public HeritageDruidManaEffect(final HeritageDruidManaEffect effect) {
super(effect);
this.filter = effect.filter.copy();
}
@Override
public HeritageDruidManaEffect copy() {
return new HeritageDruidManaEffect(this);
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
if (game.inCheckPlayableState()) {
int count = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) / 3;
List<Mana> netMana = new ArrayList<>();
netMana.add(new Mana(0, count * 3, 0, 0, 0, 0, 0, 0));
return netMana;
}
return super.getNetMana(game, source);
}
}

View file

@ -1,10 +1,14 @@
package mage.cards.s;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -12,9 +16,11 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.target.common.TargetControlledCreaturePermanent;
/**
@ -23,13 +29,6 @@ import mage.target.common.TargetControlledCreaturePermanent;
*/
public final class SetonKrosanProtector extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped Druid you control");
static {
filter.add(Predicates.not(TappedPredicate.instance));
filter.add(SubType.DRUID.getPredicate());
}
public SetonKrosanProtector(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}{G}{G}");
addSuperType(SuperType.LEGENDARY);
@ -40,7 +39,12 @@ public final class SetonKrosanProtector extends CardImpl {
this.toughness = new MageInt(2);
// Tap an untapped Druid you control: Add {G}.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(1),
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped Druid you control");
filter.add(Predicates.not(TappedPredicate.instance));
filter.add(SubType.DRUID.getPredicate());
this.addAbility(new SimpleManaAbility(
Zone.BATTLEFIELD,
new SetonKrosanProtectorManaEffect(filter),
new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))));
}
@ -53,3 +57,37 @@ public final class SetonKrosanProtector extends CardImpl {
return new SetonKrosanProtector(this);
}
}
class SetonKrosanProtectorManaEffect extends BasicManaEffect {
private final FilterPermanent filter;
public SetonKrosanProtectorManaEffect(FilterPermanent filter) {
super(Mana.GreenMana(1));
this.filter = filter;
}
public SetonKrosanProtectorManaEffect(final SetonKrosanProtectorManaEffect effect) {
super(effect);
this.filter = effect.filter.copy();
}
@Override
public SetonKrosanProtectorManaEffect copy() {
return new SetonKrosanProtectorManaEffect(this);
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
if (game.inCheckPlayableState()) {
// Because the ability can be used multiple times, multiply with untapped druids
int count = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
List<Mana> netMana = new ArrayList<>();
netMana.add(new Mana(0, count, 0,0,0,0,0,0));
return netMana;
}
return super.getNetMana(game, source);
}
}

View file

@ -1,5 +1,7 @@
package mage.cards.u;
import java.util.ArrayList;
import java.util.List;
import mage.MageInt;
import mage.MageObject;
import mage.Mana;
@ -27,19 +29,14 @@ import mage.players.Player;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.filter.FilterPermanent;
/**
* @author TheElk801
*/
public final class UrzaLordHighArtificer extends CardImpl {
private static final FilterControlledPermanent filter
= new FilterControlledArtifactPermanent("untapped artifact you control");
static {
filter.add(Predicates.not(TappedPredicate.instance));
}
public UrzaLordHighArtificer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
@ -55,9 +52,12 @@ public final class UrzaLordHighArtificer extends CardImpl {
);
// Tap an untapped artifact you control: Add {U}.
FilterControlledPermanent filter = new FilterControlledArtifactPermanent("untapped artifact you control");
filter.add(Predicates.not(TappedPredicate.instance));
this.addAbility(new SimpleManaAbility(
Zone.BATTLEFIELD, Mana.BlueMana(1), new TapTargetCost(new TargetControlledPermanent(filter))
));
Zone.BATTLEFIELD,
new UrzaLordHighArtificerManaEffect(filter),
new TapTargetCost(new TargetControlledPermanent(filter))));
// {5}: Shuffle your library, then exile the top card. Until end of turn, you may play that card without paying its mana cost.
this.addAbility(new SimpleActivatedAbility(new UrzaLordHighArtificerEffect(), new GenericManaCost(5)));
@ -103,3 +103,35 @@ class UrzaLordHighArtificerEffect extends OneShotEffect {
TargetController.YOU, Duration.EndOfTurn, true);
}
}
class UrzaLordHighArtificerManaEffect extends BasicManaEffect {
private final FilterPermanent filter;
public UrzaLordHighArtificerManaEffect(FilterPermanent filter) {
super(Mana.BlueMana(1));
this.filter = filter;
}
public UrzaLordHighArtificerManaEffect(final UrzaLordHighArtificerManaEffect effect) {
super(effect);
this.filter = effect.filter.copy();
}
@Override
public UrzaLordHighArtificerManaEffect copy() {
return new UrzaLordHighArtificerManaEffect(this);
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
if (game.inCheckPlayableState()) {
int count = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
List<Mana> netMana = new ArrayList<>();
netMana.add(new Mana(0, 0, count, 0,0,0,0,0));
return netMana;
}
return super.getNetMana(game, source);
}
}

View file

@ -0,0 +1,45 @@
package org.mage.test.cards.mana;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class MultipleTimesUsableActivatedManaAbilitiesTest extends CardTestPlayerBase {
/**
* Seton, Krosan Protector - only seems to get counted as if it were one
* mana for determining if a spell can be cast, regardless of how many
* druids you have in playF
*/
@Test
public void testCanBeCastWithSetonKrosanProtector() {
// Tap an untapped Druid you control: Add {G}.
addCard(Zone.BATTLEFIELD, playerA, "Seton, Krosan Protector", 1); // Creature {G}{G}{G}
addCard(Zone.BATTLEFIELD, playerA, "Citanul Druid", 3);
addCard(Zone.HAND, playerA, "Leatherback Baloth", 1); // Creature 4/5
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Leatherback Baloth");
setChoice(playerA, "Citanul Druid");
setChoice(playerA, "Citanul Druid");
setChoice(playerA, "Citanul Druid");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
setStrictChooseMode(true);
execute();
assertAllCommandsUsed();
assertTappedCount("Citanul Druid", true, 3);
assertPermanentCount(playerA, "Leatherback Baloth", 1);
}
}

View file

@ -1,11 +1,15 @@
package org.mage.test.cards.replacement;
import mage.abilities.mana.ManaOptions;
import mage.constants.ManaType;
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;
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
public class ManaReflectionTest extends CardTestPlayerBase {
@ -54,4 +58,26 @@ public class ManaReflectionTest extends CardTestPlayerBase {
assertManaPool(playerA, ManaType.GREEN, 2);
}
@Test
public void ManaReflectionWithGoblinClearcutterTest() {
// If you tap a permanent for mana, it produces twice as much of that mana instead.
addCard(Zone.BATTLEFIELD, playerA, "Mana Reflection");
// {T}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}.
addCard(Zone.BATTLEFIELD, playerA, "Goblin Clearcutter");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
assertManaOptions("{R}{R}{R}{R}{R}{R}{G}{G}", manaOptions);
assertManaOptions("{R}{R}{R}{R}{G}{G}{G}{G}", manaOptions);
assertManaOptions("{R}{R}{G}{G}{G}{G}{G}{G}", manaOptions);
assertManaOptions("{G}{G}{G}{G}{G}{G}{G}{G}", manaOptions);
}
}

View file

@ -55,7 +55,7 @@ public class SimpleManaAbility extends ActivatedManaAbilityImpl {
if (predictable) {
return super.getNetMana(game);
}
return new ArrayList<Mana>(netMana);
return new ArrayList<>(netMana);
}
}