From d069bbd544b4c0ca2dc9d82bac0be0778e141adb Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 19 Jun 2020 13:24:52 +0400 Subject: [PATCH] Code cleanup and test fixes --- .../src/mage/cards/d/DigThroughTime.java | 10 +- .../src/mage/cards/i/IllusionistsBracers.java | 23 ++- .../src/mage/cards/s/StokeTheFlames.java | 10 +- .../cards/copy/CleverImpersonatorTest.java | 18 +- .../triggers/damage/SyrCarahTheBoldTest.java | 31 ++-- .../serverside/base/MageTestPlayerBase.java | 11 +- .../base/impl/CardTestPlayerAPIImpl.java | 171 +++++++++--------- Mage/src/main/java/mage/game/GameImpl.java | 25 +-- Mage/src/main/java/mage/util/ManaUtil.java | 7 +- 9 files changed, 160 insertions(+), 146 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DigThroughTime.java b/Mage.Sets/src/mage/cards/d/DigThroughTime.java index fbc8168103a..5a652e5ceba 100644 --- a/Mage.Sets/src/mage/cards/d/DigThroughTime.java +++ b/Mage.Sets/src/mage/cards/d/DigThroughTime.java @@ -1,7 +1,5 @@ - package mage.cards.d; -import java.util.UUID; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.keyword.DelveAbility; @@ -11,19 +9,19 @@ import mage.constants.CardType; import mage.constants.Zone; import mage.filter.FilterCard; +import java.util.UUID; + /** - * * @author emerald000 */ public final class DigThroughTime extends CardImpl { public DigThroughTime(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{6}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{6}{U}{U}"); // Delve this.addAbility(new DelveAbility()); - + // Look at the top seven cards of your library. Put two of them into your hand and the rest on the bottom of your library in any order. this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(StaticValue.get(7), false, StaticValue.get(2), new FilterCard(), Zone.LIBRARY, false, false)); } diff --git a/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java b/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java index 257ca55ff20..6b98993ed81 100644 --- a/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java +++ b/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java @@ -1,7 +1,5 @@ - package mage.cards.i; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.costs.mana.GenericManaCost; @@ -12,8 +10,8 @@ import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -22,18 +20,19 @@ import mage.game.permanent.Permanent; import mage.game.stack.StackAbility; import mage.players.Player; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class IllusionistsBracers extends CardImpl { public IllusionistsBracers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); this.subtype.add(SubType.EQUIPMENT); // Whenever an ability of equipped creature is activated, if it isn't a mana ability, copy that ability. You may choose new targets for the copy. - this.addAbility(new AbilityActivatedTriggeredAbility()); + this.addAbility(new IllusionistsBracersTriggeredAbility()); // Equip 3 this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(3))); @@ -49,19 +48,19 @@ public final class IllusionistsBracers extends CardImpl { } } -class AbilityActivatedTriggeredAbility extends TriggeredAbilityImpl { +class IllusionistsBracersTriggeredAbility extends TriggeredAbilityImpl { - AbilityActivatedTriggeredAbility() { + IllusionistsBracersTriggeredAbility() { super(Zone.BATTLEFIELD, new CopyActivatedAbilityEffect()); } - AbilityActivatedTriggeredAbility(final AbilityActivatedTriggeredAbility ability) { + IllusionistsBracersTriggeredAbility(final IllusionistsBracersTriggeredAbility ability) { super(ability); } @Override - public AbilityActivatedTriggeredAbility copy() { - return new AbilityActivatedTriggeredAbility(this); + public IllusionistsBracersTriggeredAbility copy() { + return new IllusionistsBracersTriggeredAbility(this); } @Override @@ -72,7 +71,7 @@ class AbilityActivatedTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent equipment = game.getPermanent(this.getSourceId()); - if (equipment != null && equipment.isAttachedTo(event.getSourceId())) { + if (equipment != null && equipment.isAttachedTo(event.getSourceId())) { StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); if (!(stackAbility.getStackAbility() instanceof ActivatedManaAbilityImpl)) { Effect effect = this.getEffects().get(0); diff --git a/Mage.Sets/src/mage/cards/s/StokeTheFlames.java b/Mage.Sets/src/mage/cards/s/StokeTheFlames.java index 39cd33c84c9..bffdfd33b85 100644 --- a/Mage.Sets/src/mage/cards/s/StokeTheFlames.java +++ b/Mage.Sets/src/mage/cards/s/StokeTheFlames.java @@ -1,7 +1,5 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.ConvokeAbility; import mage.cards.CardImpl; @@ -9,19 +7,19 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.target.common.TargetAnyTarget; +import java.util.UUID; + /** - * * @author Quercitron */ public final class StokeTheFlames extends CardImpl { public StokeTheFlames(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}{R}"); // Convoke this.addAbility(new ConvokeAbility()); - + // Stoke the Flames deals 4 damage to any target. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); this.getSpellAbility().addTarget(new TargetAnyTarget()); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java index 1cb16170ab4..e6b6eb16efc 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java @@ -1,4 +1,3 @@ - package org.mage.test.cards.copy; import mage.constants.CardType; @@ -9,7 +8,6 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * * @author LevelX2 */ public class CleverImpersonatorTest extends CardTestPlayerBase { @@ -54,22 +52,29 @@ public class CleverImpersonatorTest extends CardTestPlayerBase { */ @Test public void testCopyPlaneswalker() { - addCard(Zone.BATTLEFIELD, playerA, "Island", 4); - // You may have Clever Impersonator enter the battlefield as a copy of any nonland permanent on the battlefield. addCard(Zone.HAND, playerA, "Clever Impersonator", 1); // {2}{U}{U} + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); // +2: Each player discards a card. // -X: Return target nonlegendary creature with converted mana cost X from your graveyard to the battlefield. // -8: You get an emblem with "Whenever a creature dies, return it to the battlefield under your control at the beginning of the next end step."; addCard(Zone.BATTLEFIELD, playerB, "Liliana, Defiant Necromancer", 1); + // + addCard(Zone.HAND, playerA, "Balduvian Bears", 1); + addCard(Zone.HAND, playerB, "Balduvian Bears", 1); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Clever Impersonator"); - setChoice(playerA, "Liliana, Defiant Necromancer"); + setChoice(playerA, "Yes"); // make copy + setChoice(playerA, "Liliana, Defiant Necromancer"); // copy target activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: Each player discards a card"); + addTarget(playerA, "Balduvian Bears"); // discard + addTarget(playerB, "Balduvian Bears"); // discard + setStrictChooseMode(true); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, "Clever Impersonator", 0); assertCounterCount(playerB, "Liliana, Defiant Necromancer", CounterType.LOYALTY, 3); // 3 @@ -157,8 +162,7 @@ public class CleverImpersonatorTest extends CardTestPlayerBase { * Reported bug: could not use Clever Impersonator to copy Dawn's Reflection */ @Test - public void dawnsReflectionCopiedByImpersonator() - { + public void dawnsReflectionCopiedByImpersonator() { String impersonator = "Clever Impersonator"; String dReflection = "Dawn's Reflection"; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/SyrCarahTheBoldTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/SyrCarahTheBoldTest.java index a8d5eb50e5c..5962c91cc23 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/SyrCarahTheBoldTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/SyrCarahTheBoldTest.java @@ -55,32 +55,31 @@ public class SyrCarahTheBoldTest extends CardTestPlayerBase { public void test_DamageWithCopyAbility() { removeAllCardsFromLibrary(playerA); removeAllCardsFromHand(playerA); + // When Syr Carah, the Bold or an instant or sorcery spell you control deals damage to a player, exile the top card of your library. You may play that card this turn. // {T}: Syr Carah deals 1 damage to any target. addCard(Zone.BATTLEFIELD, playerA, "Syr Carah, the Bold", 1); - // - addCard(Zone.LIBRARY, playerA, "Swamp", 5); - // - // {T}: Embermage Goblin deals 1 damage to any target. - addCard(Zone.BATTLEFIELD, playerB, "Embermage Goblin", 1); + addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 2); // // Whenever an ability of equipped creature is activated, if it isn't a mana ability, copy that ability. You may choose new targets for the copy. // Equip 3 - addCard(Zone.BATTLEFIELD, playerB, "Illusionist's Bracers", 1); - addCard(Zone.BATTLEFIELD, playerB, "Island", 3); + addCard(Zone.BATTLEFIELD, playerA, "Illusionist's Bracers", 1); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); - // equip to copy abilities - // showAvaileableAbilities("abils", 2, PhaseStep.PRECOMBAT_MAIN, playerB); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Equip {3}", "Embermage Goblin"); - setChoice(playerB, "No"); // no new target + // prepare equip + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {3}", "Syr Carah, the Bold"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + checkExileCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0); - // 3 - 2x damage (copy), but no trigger - // java.lang.ClassCastException: mage.game.stack.StackAbility cannot be cast to mage.game.stack.Spell - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: {source} deals", playerA); - checkLife("damage 3", 2, PhaseStep.END_TURN, playerA, 20 - 1 - 1); + // activate damage - 2x damage with copy + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); + setChoice(playerA, "No"); // no new target for copy + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + checkLife("damage 2", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 1 - 1); + checkExileCount("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 2); setStrictChooseMode(true); - setStopAt(3, PhaseStep.END_TURN); + setStopAt(1, PhaseStep.END_TURN); execute(); assertAllCommandsUsed(); } diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java index 5b5b758af49..4efe7837f29 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java @@ -351,6 +351,13 @@ public abstract class MageTestPlayerBase { return new TestPlayer(new TestComputerPlayer(name, rangeOfInfluence)); } + /** + * Raise error on any miss choices/targets setup in tests (if AI try to make decision itself instead of user defined actions) + * If you want to disable mana auto-payment (e.g. to simulate user clicks on mana pool or special mana) then call + * disableManaAutoPayment() + * + * @param enable + */ protected void setStrictChooseMode(boolean enable) { if (playerA != null) playerA.setChooseStrictMode(enable); if (playerB != null) playerB.setChooseStrictMode(enable); @@ -403,8 +410,8 @@ public abstract class MageTestPlayerBase { // custom card with global abilities list to init (can contains abilities per card name) class CustomTestCard extends CardImpl { - static private Map> abilitiesList = new HashMap<>(); // card name -> abilities - static private Map spellAbilitiesList = new HashMap<>(); // card name -> spell ability + static private final Map> abilitiesList = new HashMap<>(); // card name -> abilities + static private final Map spellAbilitiesList = new HashMap<>(); // card name -> spell ability static void addCustomAbility(String cardName, SpellAbility spellAbility, Ability ability) { if (!abilitiesList.containsKey(cardName)) { diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 57a4c26ac6e..b23d039a1c2 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -1,13 +1,5 @@ package org.mage.test.serverside.base.impl; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; import mage.MageObject; import mage.Mana; import mage.ObjectColor; @@ -43,6 +35,15 @@ import org.mage.test.player.TestPlayer; import org.mage.test.serverside.base.CardTestAPI; import org.mage.test.serverside.base.MageTestPlayerBase; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + /** * API for test initialization and asserting the test results. * @@ -273,7 +274,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } } Assert.assertFalse("Wrong stop command on " + this.stopOnTurn + " / " + this.stopAtStep + " (" + this.stopAtStep.getIndex() + ")" - + " (found actions after stop on " + maxTurn + " / " + maxPhase + ")", + + " (found actions after stop on " + maxTurn + " / " + maxPhase + ")", (maxTurn > this.stopOnTurn) || (maxTurn == this.stopOnTurn && maxPhase > this.stopAtStep.getIndex())); for (Player player : currentGame.getPlayers().values()) { @@ -506,8 +507,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Add a card to specified zone of specified player. * * @param gameZone {@link mage.constants.Zone} to add cards to. - * @param player {@link Player} to add cards for. Use either playerA or - * playerB. + * @param player {@link Player} to add cards for. Use either playerA or + * playerB. * @param cardName Card name in string format. */ @Override @@ -519,10 +520,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Add any amount of cards to specified zone of specified player. * * @param gameZone {@link mage.constants.Zone} to add cards to. - * @param player {@link Player} to add cards for. Use either playerA or - * playerB. + * @param player {@link Player} to add cards for. Use either playerA or + * playerB. * @param cardName Card name in string format. - * @param count Amount of cards to be added. + * @param count Amount of cards to be added. */ @Override public void addCard(Zone gameZone, TestPlayer player, String cardName, int count) { @@ -533,13 +534,13 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Add any amount of cards to specified zone of specified player. * * @param gameZone {@link mage.constants.Zone} to add cards to. - * @param player {@link Player} to add cards for. Use either playerA or - * playerB. + * @param player {@link Player} to add cards for. Use either playerA or + * playerB. * @param cardName Card name in string format. - * @param count Amount of cards to be added. - * @param tapped In case gameZone is Battlefield, determines whether - * permanent should be tapped. In case gameZone is other than Battlefield, - * {@link IllegalArgumentException} is thrown + * @param count Amount of cards to be added. + * @param tapped In case gameZone is Battlefield, determines whether + * permanent should be tapped. In case gameZone is other than Battlefield, + * {@link IllegalArgumentException} is thrown */ @Override public void addCard(Zone gameZone, TestPlayer player, String cardName, int count, boolean tapped) { @@ -620,7 +621,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Set player's initial life count. * * @param player {@link Player} to set life count for. - * @param life Life count to set. + * @param life Life count to set. */ @Override public void setLife(TestPlayer player, int life) { @@ -697,7 +698,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert player's life count after test execution. * * @param player {@link Player} to get life for comparison. - * @param life Expected player's life to compare with. + * @param life Expected player's life to compare with. */ @Override public void assertLife(Player player, int life) throws AssertionError { @@ -714,14 +715,14 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * params 3b. all: there is at least one creature with the cardName with the * different p\t params * - * @param player {@link Player} to get creatures for comparison. - * @param cardName Card name to compare with. - * @param power Expected power to compare with. + * @param player {@link Player} to get creatures for comparison. + * @param cardName Card name to compare with. + * @param power Expected power to compare with. * @param toughness Expected toughness to compare with. - * @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you - * want "at least one creature with given name should have specified p\t" - * Use ALL, if you want "all creature with gived name should have specified - * p\t" + * @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you + * want "at least one creature with given name should have specified p\t" + * Use ALL, if you want "all creature with gived name should have specified + * p\t" */ @Override public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope) @@ -811,8 +812,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param cardName * @param ability * @param mustHave true if creature should contain ability, false if it - * should NOT contain it instead - * @param count number of permanents with that ability + * should NOT contain it instead + * @param count number of permanents with that ability * @throws AssertionError */ public void assertAbility(Player player, String cardName, Ability ability, boolean mustHave, int count) throws AssertionError { @@ -845,7 +846,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert permanent count under player's control. * * @param player {@link Player} which permanents should be counted. - * @param count Expected count. + * @param count Expected count. */ @Override public void assertPermanentCount(Player player, int count) throws AssertionError { @@ -861,9 +862,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert permanent count under player's control. * - * @param player {@link Player} which permanents should be counted. + * @param player {@link Player} which permanents should be counted. * @param cardName Name of the cards that should be counted. - * @param count Expected count. + * @param count Expected count. */ @Override public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError { @@ -913,8 +914,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert counter count on a permanent * * @param cardName Name of the cards that should be counted. - * @param type Type of the counter that should be counted. - * @param count Expected count. + * @param type Type of the counter that should be counted. + * @param count Expected count. */ public void assertCounterCount(String cardName, CounterType type, int count) throws AssertionError { this.assertCounterCount(null, cardName, type, count); @@ -937,8 +938,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert counter count on a card in exile * * @param cardName Name of the cards that should be counted. - * @param type Type of the counter that should be counted. - * @param count Expected count. + * @param type Type of the counter that should be counted. + * @param count Expected count. */ public void assertCounterOnExiledCardCount(String cardName, CounterType type, int count) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -961,8 +962,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert counter count on a player * * @param player The player whos counters should be counted. - * @param type Type of the counter that should be counted. - * @param count Expected count. + * @param type Type of the counter that should be counted. + * @param count Expected count. */ public void assertCounterCount(Player player, CounterType type, int count) throws AssertionError { Assert.assertEquals("(Battlefield) Counter counts are not equal (" + player.getName() + ':' + type + ')', count, player.getCounters().getCount(type)); @@ -972,7 +973,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert whether a permanent is a specified type or not * * @param cardName Name of the permanent that should be checked. - * @param type A type to test for + * @param type A type to test for * @param mustHave true if creature should have type, false if it should not */ public void assertType(String cardName, CardType type, boolean mustHave) throws AssertionError { @@ -997,8 +998,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert whether a permanent is a specified type * * @param cardName Name of the permanent that should be checked. - * @param type A type to test for - * @param subType a subtype to test for + * @param type A type to test for + * @param subType a subtype to test for */ public void assertType(String cardName, CardType type, SubType subType) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1013,7 +1014,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert whether a permanent is not a specified type * * @param cardName Name of the permanent that should be checked. - * @param type A type to test for + * @param type A type to test for */ public void assertNotType(String cardName, CardType type) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1025,7 +1026,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert whether a permanent is not a specified subtype * * @param cardName Name of the permanent that should be checked. - * @param subType a subtype to test for + * @param subType a subtype to test for */ public void assertNotSubtype(String cardName, SubType subType) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1038,10 +1039,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert permanent color * - * @param player player to check - * @param cardName card name on battlefield from player + * @param player player to check + * @param cardName card name on battlefield from player * @param searchColors colors list with searchable values - * @param mustHave must or not must have that colors + * @param mustHave must or not must have that colors */ public void assertColor(Player player, String cardName, ObjectColor searchColors, boolean mustHave) { //Assert.assertNotEquals("", cardName); @@ -1076,7 +1077,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert whether a permanent is tapped or not * * @param cardName Name of the permanent that should be checked. - * @param tapped Whether the permanent is tapped or not + * @param tapped Whether the permanent is tapped or not */ public void assertTapped(String cardName, boolean tapped) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1103,8 +1104,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert whether X permanents of the same name are tapped or not. * * @param cardName Name of the permanent that should be checked. - * @param tapped Whether the permanent is tapped or not - * @param count The amount of this permanents that should be tapped + * @param tapped Whether the permanent is tapped or not + * @param count The amount of this permanents that should be tapped */ public void assertTappedCount(String cardName, boolean tapped, int count) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1126,7 +1127,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert whether a permanent is attacking or not * - * @param cardName Name of the permanent that should be checked. + * @param cardName Name of the permanent that should be checked. * @param attacking Whether the permanent is attacking or not */ public void assertAttacking(String cardName, boolean attacking) throws AssertionError { @@ -1148,7 +1149,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert card count in player's hand. * * @param player {@link Player} who's hand should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertHandCount(Player player, int count) throws AssertionError { int actual = currentGame.getPlayer(player.getId()).getHand().size(); @@ -1158,9 +1159,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert card count in player's hand. * - * @param player {@link Player} who's hand should be counted. + * @param player {@link Player} who's hand should be counted. * @param cardName Name of the cards that should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertHandCount(Player player, String cardName, int count) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1208,7 +1209,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert card count in player's graveyard. * * @param player {@link Player} who's graveyard should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertGraveyardCount(Player player, int count) throws AssertionError { int actual = currentGame.getPlayer(player.getId()).getGraveyard().size(); @@ -1219,7 +1220,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert card count in exile. * * @param cardName Name of the cards that should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertExileCount(String cardName, int count) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1257,9 +1258,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert card count in player's exile. * - * @param owner {@link Player} who's exile should be counted. + * @param owner {@link Player} who's exile should be counted. * @param cardName Name of the cards that should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertExileCount(Player owner, String cardName, int count) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1278,9 +1279,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert card count in player's graveyard. * - * @param player {@link Player} who's graveyard should be counted. + * @param player {@link Player} who's graveyard should be counted. * @param cardName Name of the cards that should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertGraveyardCount(Player player, String cardName, int count) throws AssertionError { assertAliaseSupportInActivateCommand(cardName, true); @@ -1299,7 +1300,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * Assert library card count. * * @param player {@link Player} who's library should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertLibraryCount(Player player, int count) throws AssertionError { List libraryList = player.getLibrary().getCards(currentGame); @@ -1310,9 +1311,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert specific card count in player's library. * - * @param player {@link Player} who's library should be counted. + * @param player {@link Player} who's library should be counted. * @param cardName Name of the cards that should be counted. - * @param count Expected count. + * @param count Expected count. */ public void assertLibraryCount(Player player, String cardName, int count) throws AssertionError { //Assert.assertNotEquals("", cardName); @@ -1350,6 +1351,12 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement Assert.assertEquals("(Targets of " + player.getName() + ") Count are not equal (found " + player.getTargets() + ")", count, player.getTargets().size()); } + /** + * Raise error on any unused commands, choices or targets + * If you want to test that ability can't be activated then use call checkPlayableAbility() + * + * @throws AssertionError + */ public void assertAllCommandsUsed() throws AssertionError { for (Player player : currentGame.getPlayers().values()) { TestPlayer testPlayer = (TestPlayer) player; @@ -1493,8 +1500,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param player * @param cardName * @param targetName for modes you can add "mode=3" before target name, - * multiple targets can be seperated by ^, not target marks as - * TestPlayer.NO_TARGET + * multiple targets can be seperated by ^, not target marks as + * TestPlayer.NO_TARGET */ public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) { //Assert.assertNotEquals("", cardName); @@ -1517,8 +1524,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param step * @param player * @param cardName - * @param targetName for modal spells add the mode to the name e.g. - * "mode=2SilvercoatLion^mode3=PillarfieldOx" + * @param targetName for modal spells add the mode to the name e.g. + * "mode=2SilvercoatLion^mode3=PillarfieldOx" * @param spellOnStack */ public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack) { @@ -1605,7 +1612,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param step * @param player * @param ability - * @param targetName use NO_TARGET if there is no target to set + * @param targetName use NO_TARGET if there is no target to set * @param spellOnStack */ public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) { @@ -1618,8 +1625,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param step * @param player * @param ability - * @param targetName if not target has to be defined use the constant - * NO_TARGET + * @param targetName if not target has to be defined use the constant + * NO_TARGET * @param spellOnStack * @param clause */ @@ -1705,10 +1712,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * * @param player * @param choice starting with "1" for mode 1, "2" for mode 2 and so on (to - * set multiple modes call the command multiple times). If a spell mode can - * be used only once like Demonic Pact, the value has to be set to the - * number of the remaining modes (e.g. if only 2 are left the number need to - * be 1 or 2). + * set multiple modes call the command multiple times). If a spell mode can + * be used only once like Demonic Pact, the value has to be set to the + * number of the remaining modes (e.g. if only 2 are left the number need to + * be 1 or 2). */ public void setModeChoice(TestPlayer player, String choice) { player.addModeChoice(choice); @@ -1719,12 +1726,12 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * * @param player * @param target you can add multiple targets by separating them by the "^" - * character e.g. "creatureName1^creatureName2" you can qualify the target - * additional by setcode e.g. "creatureName-M15" you can add [no copy] to - * the end of the target name to prohibit targets that are copied you can - * add [only copy] to the end of the target name to allow only targets that - * are copies. For modal spells use a prefix with the mode number: - * mode=1Lightning Bolt^mode=2Silvercoat Lion + * character e.g. "creatureName1^creatureName2" you can qualify the target + * additional by setcode e.g. "creatureName-M15" you can add [no copy] to + * the end of the target name to prohibit targets that are copied you can + * add [only copy] to the end of the target name to allow only targets that + * are copies. For modal spells use a prefix with the mode number: + * mode=1Lightning Bolt^mode=2Silvercoat Lion */ // TODO: mode options doesn't work here (see BrutalExpulsionTest) public void addTarget(TestPlayer player, String target) { @@ -1744,7 +1751,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * @param player * @param target use TestPlayer.TARGET_SKIP to 0 targets selects or to stop - * "up two xxx" selection + * "up two xxx" selection * @param amount */ public void addTargetAmount(TestPlayer player, String target, int amount) { diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index a7cdb25fdd1..435772ef44f 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -1,9 +1,5 @@ package mage.game; -import java.io.IOException; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; import mage.MageException; import mage.MageObject; import mage.abilities.*; @@ -71,6 +67,11 @@ import mage.util.functions.ApplyToPermanent; import mage.watchers.common.*; import org.apache.log4j.Logger; +import java.io.IOException; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; + public abstract class GameImpl implements Game, Serializable { private static final int ROLLBACK_TURNS_MAX = 4; @@ -1548,7 +1549,7 @@ public abstract class GameImpl implements Game, Serializable { /** * @param emblem * @param sourceObject - * @param toPlayerId controller and owner of the emblem + * @param toPlayerId controller and owner of the emblem */ @Override public void addEmblem(Emblem emblem, MageObject sourceObject, UUID toPlayerId) { @@ -1566,8 +1567,8 @@ public abstract class GameImpl implements Game, Serializable { /** * @param plane * @param sourceObject - * @param toPlayerId controller and owner of the plane (may only be one per - * game..) + * @param toPlayerId controller and owner of the plane (may only be one per + * game..) * @return boolean - whether the plane was added successfully or not */ @Override @@ -1803,7 +1804,7 @@ public abstract class GameImpl implements Game, Serializable { break; } // triggered abilities that don't use the stack have to be executed first (e.g. Banisher Priest Return exiled creature - for (Iterator it = abilities.iterator(); it.hasNext();) { + for (Iterator it = abilities.iterator(); it.hasNext(); ) { TriggeredAbility triggeredAbility = it.next(); if (!triggeredAbility.isUsesStack()) { state.removeTriggeredAbility(triggeredAbility); @@ -2594,7 +2595,7 @@ public abstract class GameImpl implements Game, Serializable { } //20100423 - 800.4a Set toOutside = new HashSet<>(); - for (Iterator it = getBattlefield().getAllPermanents().iterator(); it.hasNext();) { + for (Iterator it = getBattlefield().getAllPermanents().iterator(); it.hasNext(); ) { Permanent perm = it.next(); if (perm.isOwnedBy(playerId)) { if (perm.getAttachedTo() != null) { @@ -2639,7 +2640,7 @@ public abstract class GameImpl implements Game, Serializable { player.moveCards(toOutside, Zone.OUTSIDE, null, this); // triggered abilities that don't use the stack have to be executed List abilities = state.getTriggered(player.getId()); - for (Iterator it = abilities.iterator(); it.hasNext();) { + for (Iterator it = abilities.iterator(); it.hasNext(); ) { TriggeredAbility triggeredAbility = it.next(); if (!triggeredAbility.isUsesStack()) { state.removeTriggeredAbility(triggeredAbility); @@ -2659,7 +2660,7 @@ public abstract class GameImpl implements Game, Serializable { // Remove cards from the player in all exile zones for (ExileZone exile : this.getExile().getExileZones()) { - for (Iterator it = exile.iterator(); it.hasNext();) { + for (Iterator it = exile.iterator(); it.hasNext(); ) { Card card = this.getCard(it.next()); if (card != null && card.isOwnedBy(playerId)) { it.remove(); @@ -2669,7 +2670,7 @@ public abstract class GameImpl implements Game, Serializable { //Remove all commander/emblems/plane the player controls boolean addPlaneAgain = false; - for (Iterator it = this.getState().getCommand().iterator(); it.hasNext();) { + for (Iterator it = this.getState().getCommand().iterator(); it.hasNext(); ) { CommandObject obj = it.next(); if (obj.isControlledBy(playerId)) { if (obj instanceof Emblem) { diff --git a/Mage/src/main/java/mage/util/ManaUtil.java b/Mage/src/main/java/mage/util/ManaUtil.java index ef24b04b437..44689f497e7 100644 --- a/Mage/src/main/java/mage/util/ManaUtil.java +++ b/Mage/src/main/java/mage/util/ManaUtil.java @@ -1,6 +1,5 @@ package mage.util; -import java.util.*; import mage.MageObject; import mage.Mana; import mage.ManaSymbol; @@ -19,6 +18,8 @@ import mage.filter.FilterMana; import mage.game.Game; import mage.players.Player; +import java.util.*; + /** * @author noxx */ @@ -46,7 +47,7 @@ public final class ManaUtil { * In case we can't auto choose we'll simply return the useableAbilities map * back to caller without any modification. * - * @param unpaid Mana we need to pay. Can be null (it is for X costs now). + * @param unpaid Mana we need to pay. Can be null (it is for X costs now). * @param useableAbilities List of mana abilities permanent may produce * @return List of mana abilities permanent may produce and are reasonable * for unpaid mana @@ -403,7 +404,7 @@ public final class ManaUtil { } /** - * This activates the special button inthe feedback panel of the client if + * This activates the special button in the feedback panel of the client if * there exists special ways to pay the mana (e.g. Delve, Convoke) * * @param source ability the mana costs have to be paid for