diff --git a/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java b/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java index 28f10fe6888..dbc3cf21087 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java +++ b/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java @@ -1,26 +1,20 @@ package mage.cards.g; import mage.MageInt; -import mage.Mana; import mage.abilities.Ability; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.mana.ManaEffect; +import mage.abilities.effects.mana.AddManaInAnyCombinationEffect; import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; -import mage.constants.Outcome; +import mage.constants.ColoredManaSymbol; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetControlledPermanent; -import java.util.*; +import java.util.UUID; /** * @author BursegSardaukar @@ -41,7 +35,9 @@ public final class GoblinClearcutter extends CardImpl { this.toughness = new MageInt(3); // {T}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}. - Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new GoblinClearCutterManaEffect(), new TapSourceCost()); + Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaInAnyCombinationEffect( + 3, ColoredManaSymbol.R, ColoredManaSymbol.G + ), new TapSourceCost()); ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } @@ -55,63 +51,3 @@ public final class GoblinClearcutter extends CardImpl { return new GoblinClearcutter(this); } } - -class GoblinClearCutterManaEffect extends ManaEffect { - - private final List netMana = new ArrayList<>(); - - public GoblinClearCutterManaEffect() { - super(); - this.staticText = "Add three mana in any combination of {R} and/or {G}"; - netMana.add(new Mana(0, 0, 0, 0, 3, 0, 0, 0)); - netMana.add(new Mana(0, 0, 0, 1, 2, 0, 0, 0)); - netMana.add(new Mana(0, 0, 0, 2, 1, 0, 0, 0)); - netMana.add(new Mana(0, 0, 0, 3, 0, 0, 0, 0)); - } - - private GoblinClearCutterManaEffect(final GoblinClearCutterManaEffect effect) { - super(effect); - netMana.addAll(effect.netMana); - } - - @Override - public GoblinClearCutterManaEffect copy() { - return new GoblinClearCutterManaEffect(this); - } - - @Override - public List getNetMana(Game game, Ability source) { - return new ArrayList<>(netMana); - } - - @Override - public Mana produceMana(Game game, Ability source) { - Mana mana = new Mana(); - if (game == null) { - return mana; - } - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Choice manaChoice = new ChoiceImpl(false); - Set choices = new LinkedHashSet<>(); - choices.add("Red"); - choices.add("Green"); - manaChoice.setChoices(choices); - manaChoice.setMessage("Select color of mana to add"); - for (int i = 0; i < 3; i++) { - if (!player.choose(Outcome.Benefit, manaChoice, game)) { - return mana; - } - switch (manaChoice.getChoice()) { - case "Green": - mana.increaseGreen(); - break; - case "Red": - mana.increaseRed(); - break; - } - } - } - return mana; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java b/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java index 6153a95fe92..8ff143a584a 100644 --- a/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java +++ b/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java @@ -1,32 +1,20 @@ - package mage.cards.g; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; -import mage.MageObjectReference; import mage.Mana; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.constants.SubType; -import mage.constants.SuperType; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.WatcherScope; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.watchers.Watcher; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; /** * @@ -47,7 +35,9 @@ public final class GrandWarlordRadha extends CardImpl { this.addAbility(HasteAbility.getInstance()); // Whenever one or more creatures you control attack, add that much mana in any combination of {R} and/or {G}. Until end of turn, you don't lose this mana as steps and phases end. - this.addAbility(new GrandWarlordRadhaTriggeredAbility(), new CreaturesAttackedWatcher()); + this.addAbility(new AttacksWithCreaturesTriggeredAbility( + new GrandWarlordRadhaEffect(), 1 + ).setTriggerPhrase("Whenever one or more creatures you control attack, ")); } private GrandWarlordRadha(final GrandWarlordRadha card) { @@ -60,68 +50,10 @@ public final class GrandWarlordRadha extends CardImpl { } } -class CreaturesAttackedWatcher extends Watcher { - - private final Set attackedThisTurnCreatures = new HashSet<>(); - - public CreaturesAttackedWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.BEGIN_COMBAT_STEP_PRE) { - this.attackedThisTurnCreatures.clear(); - } - if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) { - this.attackedThisTurnCreatures.add(new MageObjectReference(event.getSourceId(), game)); - } - } - - public Set getAttackedThisTurnCreatures() { - return this.attackedThisTurnCreatures; - } -} - -class GrandWarlordRadhaTriggeredAbility extends TriggeredAbilityImpl { - - public GrandWarlordRadhaTriggeredAbility() { - super(Zone.BATTLEFIELD, new GrandWarlordRadhaEffect(), false); - setTriggerPhrase("Whenever one or more creatures you control attack, "); - } - - private GrandWarlordRadhaTriggeredAbility(final GrandWarlordRadhaTriggeredAbility ability) { - super(ability); - } - - @Override - public GrandWarlordRadhaTriggeredAbility copy() { - return new GrandWarlordRadhaTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - for (UUID attacker : game.getCombat().getAttackers()) { - Permanent creature = game.getPermanent(attacker); - if (creature != null - && creature.getControllerId() != null - && creature.isControlledBy(this.getControllerId())) { - return true; - } - } - return false; - } -} - class GrandWarlordRadhaEffect extends OneShotEffect { GrandWarlordRadhaEffect() { - super(Outcome.Benefit); + super(Outcome.PutManaInPool); this.staticText = "add that much mana in any combination of {R} and/or {G}. Until end of turn, you don't lose this mana as steps and phases end"; } @@ -137,46 +69,17 @@ class GrandWarlordRadhaEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - CreaturesAttackedWatcher watcher = game.getState().getWatcher(CreaturesAttackedWatcher.class); - if (watcher != null) { - int attackingCreatures = 0; - for (MageObjectReference attacker : watcher.getAttackedThisTurnCreatures()) { - if (attacker.getPermanentOrLKIBattlefield(game).isControlledBy(controller.getId())) { - attackingCreatures++; - } - } - if (attackingCreatures > 0) { - Choice manaChoice = new ChoiceImpl(false); - Set choices = new LinkedHashSet<>(); - choices.add("Red"); - choices.add("Green"); - manaChoice.setChoices(choices); - manaChoice.setMessage("Select color of mana to add"); - - for (int i = 0; i < attackingCreatures; i++) { - Mana mana = new Mana(); - if (!controller.choose(Outcome.Benefit, manaChoice, game)) { - return false; - } - if (manaChoice.getChoice() == null) { // can happen if player leaves game - return false; - } - switch (manaChoice.getChoice()) { - case "Green": - mana.increaseGreen(); - break; - case "Red": - mana.increaseRed(); - break; - } - controller.getManaPool().addMana(mana, game, source, true); - } - return true; - } - return true; - } + int amount = (Integer) getValue(AttacksWithCreaturesTriggeredAbility.VALUEKEY_NUMBER_ATTACKERS); + if (controller == null || amount < 1) { + return false; } - return false; + List manaList = controller.getMultiAmount(this.outcome, Arrays.asList("R", "G"), 0, amount, MultiAmountType.MANA, game); + + Mana mana = new Mana(); + mana.add(new Mana(ColoredManaSymbol.R, manaList.get(0))); + mana.add(new Mana(ColoredManaSymbol.G, manaList.get(1))); + + controller.getManaPool().addMana(mana, game, source, true); + return true; } } diff --git a/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java b/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java index 791f9a64ec6..a5b0fcd439b 100644 --- a/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java +++ b/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java @@ -1,26 +1,20 @@ package mage.cards.o; import mage.MageInt; -import mage.Mana; import mage.abilities.Ability; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.mana.ManaEffect; +import mage.abilities.effects.mana.AddManaInAnyCombinationEffect; import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; -import mage.constants.Outcome; +import mage.constants.ColoredManaSymbol; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetControlledPermanent; -import java.util.*; +import java.util.UUID; /** * @author LevelX2 @@ -41,7 +35,9 @@ public final class OrcishLumberjack extends CardImpl { this.toughness = new MageInt(1); // {tap}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}. - Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new OrcishLumberjackManaEffect(), new TapSourceCost()); + Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaInAnyCombinationEffect( + 3, ColoredManaSymbol.R, ColoredManaSymbol.G + ), new TapSourceCost()); ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); @@ -56,64 +52,3 @@ public final class OrcishLumberjack extends CardImpl { return new OrcishLumberjack(this); } } - -class OrcishLumberjackManaEffect extends ManaEffect { - - private List netMana = new ArrayList<>(); - - public OrcishLumberjackManaEffect() { - super(); - this.staticText = "Add three mana in any combination of {R} and/or {G}"; - netMana.add(new Mana(0, 0, 0, 0, 3, 0, 0, 0)); - netMana.add(new Mana(0, 0, 0, 1, 2, 0, 0, 0)); - netMana.add(new Mana(0, 0, 0, 2, 1, 0, 0, 0)); - netMana.add(new Mana(0, 0, 0, 3, 0, 0, 0, 0)); - } - - private OrcishLumberjackManaEffect(final OrcishLumberjackManaEffect effect) { - super(effect); - netMana.addAll(effect.netMana); - } - - @Override - public OrcishLumberjackManaEffect copy() { - return new OrcishLumberjackManaEffect(this); - } - - @Override - public List getNetMana(Game game, Ability source) { - return netMana; - } - - @Override - public Mana produceMana(Game game, Ability source) { - Mana mana = new Mana(); - if (game == null) { - return mana; - } - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Choice manaChoice = new ChoiceImpl(false); - Set choices = new LinkedHashSet<>(); - choices.add("Red"); - choices.add("Green"); - manaChoice.setChoices(choices); - manaChoice.setMessage("Select color of mana to add"); - for (int i = 0; i < 3; i++) { - if (!player.choose(Outcome.Benefit, manaChoice, game)) { - return mana; - } - switch (manaChoice.getChoice()) { - case "Green": - mana.increaseGreen(); - break; - case "Red": - mana.increaseRed(); - break; - } - } - } - return mana; - } - -} diff --git a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java index dfb72849756..88b669ed3e7 100644 --- a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java +++ b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java @@ -1,29 +1,21 @@ - package mage.cards.s; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.UUID; -import mage.Mana; -import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.FilterCard; -import mage.game.Game; import mage.game.permanent.token.DragonToken; -import mage.players.Player; import mage.target.common.TargetCardInLibrary; +import java.util.UUID; + /** * * @author JRHerlehy @@ -44,7 +36,9 @@ public final class SarkhanUnbroken extends CardImpl { this.setStartingLoyalty(4); // +1: Draw a card, then add one mana of any color. - this.addAbility(new LoyaltyAbility(new SarkhanUnbrokenAbility1(), 1)); + LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1); + loyaltyAbility.addEffect(new AddManaOfAnyColorEffect().concatBy(", then")); + this.addAbility(loyaltyAbility); // -2: Create a 4/4 red Dragon creature token with flying. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new DragonToken(), 1), -2)); // -8: Search your library for any number of Dragon creature cards and put them onto the battlefield. Then shuffle your library. @@ -60,68 +54,3 @@ public final class SarkhanUnbroken extends CardImpl { return new SarkhanUnbroken(this); } } - -class SarkhanUnbrokenAbility1 extends OneShotEffect { - - public SarkhanUnbrokenAbility1() { - super(Outcome.Benefit); - this.staticText = "Draw a card, then add one mana of any color."; - } - - private SarkhanUnbrokenAbility1(final SarkhanUnbrokenAbility1 effect) { - super(effect); - } - - @Override - public SarkhanUnbrokenAbility1 copy() { - return new SarkhanUnbrokenAbility1(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - controller.drawCards(1, source, game); - - game.fireUpdatePlayersEvent(); - - Choice manaChoice = new ChoiceImpl(false); - Set choices = new LinkedHashSet<>(); - choices.add("White"); - choices.add("Blue"); - choices.add("Black"); - choices.add("Red"); - choices.add("Green"); - - manaChoice.setChoices(choices); - manaChoice.setMessage("Select color of mana to add"); - - Mana mana = new Mana(); - if (!controller.choose(Outcome.Benefit, manaChoice, game)) { - return false; - } - switch (manaChoice.getChoice()) { - case "White": - mana.increaseWhite(); - break; - case "Blue": - mana.increaseBlue(); - break; - case "Black": - mana.increaseBlack(); - break; - case "Red": - mana.increaseRed(); - break; - case "Green": - mana.increaseGreen(); - break; - } - - controller.getManaPool().addMana(mana, game, source); - - return true; - } - return false; - } -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/AddManaAnyCombinationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/AddManaAnyCombinationTest.java new file mode 100644 index 00000000000..856d634b869 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/AddManaAnyCombinationTest.java @@ -0,0 +1,31 @@ +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; + +public class AddManaAnyCombinationTest extends CardTestPlayerBase { + + @Test + public void testOrcishLumberjack() { + String ability = "{T}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}."; + + addCard(Zone.BATTLEFIELD, playerA, "Orcish Lumberjack"); + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + addCard(Zone.HAND, playerA, "Living Twister"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, ability); + setChoice(playerA, "Forest"); // to sac + setChoiceAmount(playerA, 2, 1); // RRG + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Living Twister"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, "Living Twister", 2, 5); + assertGraveyardCount(playerA, "Forest", 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/dom/GrandWarlordRadhaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/dom/GrandWarlordRadhaTest.java new file mode 100644 index 00000000000..67e91ac4b73 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/dom/GrandWarlordRadhaTest.java @@ -0,0 +1,31 @@ +package org.mage.test.cards.single.dom; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class GrandWarlordRadhaTest extends CardTestPlayerBase { + + @Test + public void testMana() { + addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin"); + addCard(Zone.BATTLEFIELD, playerA, "Lightning Elemental"); + addCard(Zone.BATTLEFIELD, playerA, "Grand Warlord Radha"); + addCard(Zone.HAND, playerA, "Living Twister"); + + attack(1, playerA, "Raging Goblin"); + attack(1, playerA, "Lightning Elemental"); + attack(1, playerA, "Grand Warlord Radha"); + setChoiceAmount(playerA, 2, 1); // RRG + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Living Twister"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPowerToughness(playerA, "Living Twister", 2, 5); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/mana/AddManaInAnyCombinationEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/AddManaInAnyCombinationEffect.java index 1377f7f949d..ad63976b497 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/AddManaInAnyCombinationEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/AddManaInAnyCombinationEffect.java @@ -19,7 +19,7 @@ import java.util.*; */ public class AddManaInAnyCombinationEffect extends ManaEffect { - private ArrayList manaSymbols = new ArrayList<>(); + private List manaSymbols = new ArrayList<>(); private final DynamicValue amount; private final DynamicValue netAmount; @@ -45,21 +45,6 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { this.netAmount = netAmount; } - public AddManaInAnyCombinationEffect(int amount, String text) { - this(amount); - this.staticText = text; - } - - public AddManaInAnyCombinationEffect(int amount, String text, ColoredManaSymbol... coloredManaSymbols) { - this(amount, coloredManaSymbols); - this.staticText = text; - } - - public AddManaInAnyCombinationEffect(DynamicValue amount, DynamicValue netAmount, String text, ColoredManaSymbol... coloredManaSymbols) { - this(amount, netAmount, coloredManaSymbols); - this.staticText = text; - } - protected AddManaInAnyCombinationEffect(final AddManaInAnyCombinationEffect effect) { super(effect); this.manaSymbols = effect.manaSymbols; diff --git a/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java index b1e5f54b203..c6a92f003ae 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java @@ -19,7 +19,7 @@ import java.util.Set; */ public abstract class ManaEffect extends OneShotEffect { - public ManaEffect() { + protected ManaEffect() { super(Outcome.PutManaInPool); }