From c1db04812d42f9280b8c286967707b4ebabf3be3 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Mon, 3 Aug 2015 20:00:36 +0300 Subject: [PATCH 01/24] Text and coding style fixes from review --- .../src/mage/sets/apocalypse/MaskOfIntolerance.java | 2 +- .../src/mage/sets/planeshift/MaliciousAdvice.java | 3 --- Mage.Sets/src/mage/sets/vintagemasters/Addle.java | 2 +- .../abilities/dynamicvalue/common/DomainValue.java | 12 ++++++------ .../common/DamageAttachedControllerEffect.java | 2 +- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/sets/apocalypse/MaskOfIntolerance.java b/Mage.Sets/src/mage/sets/apocalypse/MaskOfIntolerance.java index 5a5cebcb196..c0ac3330e6e 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/MaskOfIntolerance.java +++ b/Mage.Sets/src/mage/sets/apocalypse/MaskOfIntolerance.java @@ -56,7 +56,7 @@ public class MaskOfIntolerance extends CardImpl { // At the beginning of each player's upkeep, if there are four or more basic land types among lands that player controls, Mask of Intolerance deals 3 damage to him or her. TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), TargetController.ANY, false); this.addAbility(new ConditionalTriggeredAbility(ability, new MaskOfIntoleranceCondition(), - "At the beginning of each player's upkeep, if there are four or more basic land types among lands that player controls, Mask of Intolerance deals 3 damage to him or her.")); + "At the beginning of each player's upkeep, if there are four or more basic land types among lands that player controls, {this} deals 3 damage to him or her.")); } public MaskOfIntolerance(final MaskOfIntolerance card) { diff --git a/Mage.Sets/src/mage/sets/planeshift/MaliciousAdvice.java b/Mage.Sets/src/mage/sets/planeshift/MaliciousAdvice.java index 9633c1f4193..a08dc49ceb0 100644 --- a/Mage.Sets/src/mage/sets/planeshift/MaliciousAdvice.java +++ b/Mage.Sets/src/mage/sets/planeshift/MaliciousAdvice.java @@ -67,9 +67,6 @@ public class MaliciousAdvice extends CardImpl { effect.setText("Tap X target artifacts, creatures, and/or lands"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(new ManacostVariableValue())); - // Correct number of targets will be set in adjustTargets - // I'm not sure if/why this needs to be here, but other such cards do have it... - this.getSpellAbility().addTarget(new TargetPermanent(filter)); } @Override diff --git a/Mage.Sets/src/mage/sets/vintagemasters/Addle.java b/Mage.Sets/src/mage/sets/vintagemasters/Addle.java index baa462bbf4e..3ce4e067d53 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/Addle.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/Addle.java @@ -95,7 +95,7 @@ class AddleEffect extends OneShotEffect { controller.choose(outcome, choice, game); ObjectColor color = choice.getColor(); if(color != null) { - game.informPlayers(new StringBuilder(controller.getLogName()).append(" chooses ").append(color).toString()); + game.informPlayers(controller.getLogName() + " chooses " + color + "."); FilterCard filter = new FilterCard(); filter.add(new ColorPredicate(color)); Effect effect = new DiscardCardYouChooseTargetEffect(filter); diff --git a/Mage/src/mage/abilities/dynamicvalue/common/DomainValue.java b/Mage/src/mage/abilities/dynamicvalue/common/DomainValue.java index 9d021891669..06c0efeef47 100644 --- a/Mage/src/mage/abilities/dynamicvalue/common/DomainValue.java +++ b/Mage/src/mage/abilities/dynamicvalue/common/DomainValue.java @@ -15,7 +15,7 @@ public class DomainValue implements DynamicValue { private Integer amount; private boolean countTargetPlayer; - private UUID player; + private UUID playerId; public DomainValue() { this(1); @@ -34,15 +34,15 @@ public class DomainValue implements DynamicValue { this.countTargetPlayer = countTargetPlayer; } - public DomainValue(Integer amount, UUID player) { + public DomainValue(Integer amount, UUID playerId) { this(amount, false); - this.player = player; + this.playerId = playerId; } public DomainValue(final DomainValue dynamicValue) { this.amount = dynamicValue.amount; this.countTargetPlayer = dynamicValue.countTargetPlayer; - this.player = dynamicValue.player; + this.playerId = dynamicValue.playerId; } @Override @@ -53,8 +53,8 @@ public class DomainValue implements DynamicValue { int haveSwamps = 0; int haveForests = 0; UUID targetPlayer; - if(player != null) { - targetPlayer = player; + if(playerId != null) { + targetPlayer = playerId; } else if(countTargetPlayer) { targetPlayer = sourceAbility.getTargets().getFirstTarget(); diff --git a/Mage/src/mage/abilities/effects/common/DamageAttachedControllerEffect.java b/Mage/src/mage/abilities/effects/common/DamageAttachedControllerEffect.java index 59d67607b10..b248481aad9 100644 --- a/Mage/src/mage/abilities/effects/common/DamageAttachedControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/DamageAttachedControllerEffect.java @@ -82,7 +82,7 @@ public class DamageAttachedControllerEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - return "{this} deals " + amount + " to that creature's controller"; + return "{this} deals " + amount + " damage to that creature's controller"; } } From 5e250dca06650a5f3fd09f3abdc0d2cbe779cf46 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 4 Aug 2015 08:26:15 +0200 Subject: [PATCH 02/24] * Release 1.4.2v5 --- Mage.Common/src/mage/utils/MageVersion.java | 2 +- Mage/src/mage/cards/repository/CardRepository.java | 2 +- Utils/release/getting_implemented_cards.txt | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Mage.Common/src/mage/utils/MageVersion.java b/Mage.Common/src/mage/utils/MageVersion.java index cc72ce6562a..59ec03f9cd2 100644 --- a/Mage.Common/src/mage/utils/MageVersion.java +++ b/Mage.Common/src/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 2; - public final static String MAGE_VERSION_MINOR_PATCH = "v4"; + public final static String MAGE_VERSION_MINOR_PATCH = "v5"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java index 019be833338..997e68430ac 100644 --- a/Mage/src/mage/cards/repository/CardRepository.java +++ b/Mage/src/mage/cards/repository/CardRepository.java @@ -60,7 +60,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 41; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 30; + private static final long CARD_CONTENT_VERSION = 31; private final Random random = new Random(); private Dao cardDao; diff --git a/Utils/release/getting_implemented_cards.txt b/Utils/release/getting_implemented_cards.txt index 60049b9bff6..212b6db2e4c 100644 --- a/Utils/release/getting_implemented_cards.txt +++ b/Utils/release/getting_implemented_cards.txt @@ -158,6 +158,9 @@ git log 60c7a2b34b5dd9a64bd415b65424a559294cf52b..HEAD --diff-filter=A --name-st since 1.4.2.v4 git log 193177d9999d56729a687ca3b1a2fc3f3b96d9e2..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt +since 1.4.2.v5 +git log 8dca887fadbbea41fb649ff17c5fe547a82ef23a..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt + 3. Copy added_cards.txt to trunk\Utils folder 4. Run script: > perl extract_in_wiki_format.perl From f0180f4a51104d205796005a82fe3c2435ee302d Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 4 Aug 2015 08:28:56 +0200 Subject: [PATCH 03/24] * Costal Piracy - Fixed import and package statements. --- Mage.Sets/src/mage/sets/eighthedition/CoastalPiracy.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/eighthedition/CoastalPiracy.java b/Mage.Sets/src/mage/sets/eighthedition/CoastalPiracy.java index 3a39041be0b..25ce5da873e 100644 --- a/Mage.Sets/src/mage/sets/eighthedition/CoastalPiracy.java +++ b/Mage.Sets/src/mage/sets/eighthedition/CoastalPiracy.java @@ -25,9 +25,10 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ -package mage.sets.eightediton; +package mage.sets.eighthedition; import java.util.UUID; +import mage.constants.Rarity; /** * @@ -50,4 +51,4 @@ public class CoastalPiracy extends mage.sets.mercadianmasques.CoastalPiracy { public CoastalPiracy copy() { return new CoastalPiracy(this); } -} \ No newline at end of file +} From a644e66b7fc1fe3ab9b92c135f95f294bf303d36 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 4 Aug 2015 17:54:17 +0200 Subject: [PATCH 04/24] * Some rework of card movement. --- .../mage/sets/apocalypse/WildResearch.java | 33 +++---- .../betrayersofkamigawa/QuillmaneBaku.java | 19 ++--- .../sets/bornofthegods/Peregrination.java | 35 ++++---- .../sets/bornofthegods/SatyrWayfinder.java | 8 +- .../src/mage/sets/coldsnap/ScryingSheets.java | 27 +++--- .../mage/sets/commander/DesecratorHag.java | 10 +-- .../src/mage/sets/commander/KodamasReach.java | 34 ++++---- .../mage/sets/commander/WhirlpoolWhelm.java | 9 +- .../mage/sets/commander2014/GraveSifter.java | 15 ++-- .../mage/sets/conflux/SkywardEyeProphets.java | 12 +-- .../mage/sets/darksteel/PulseOfTheFields.java | 10 +-- .../mage/sets/darksteel/PulseOfTheGrid.java | 10 +-- .../sets/darksteel/SwordOfLightAndShadow.java | 9 +- .../src/mage/sets/dissension/RiseFall.java | 18 ++-- .../mage/sets/dragonsmaze/MorgueBurst.java | 8 +- .../sets/dragonsoftarkir/FoulRenewal.java | 4 +- .../dragonsoftarkir/NarsetTranscendent.java | 32 +++---- .../dragonsoftarkir/ProfanerOfTheDead.java | 6 +- .../sets/dragonsoftarkir/VolcanicVision.java | 4 +- .../sets/elspethvstezzeret/EchoingTruth.java | 11 ++- .../fatereforged/RenownedWeaponsmith.java | 6 +- .../sets/fatereforged/SageEyeAvengers.java | 2 +- .../fatereforged/SoulfireGrandMaster.java | 33 +++---- .../sets/fatereforged/SuddenReclamation.java | 16 ++-- .../fatereforged/TasigurTheGoldenFang.java | 2 +- .../sets/fatereforged/TemurSabertooth.java | 8 +- .../src/mage/sets/fifthedition/Recall.java | 37 ++++---- .../sets/futuresight/LinessaZephyrMage.java | 26 +++--- .../sets/futuresight/VenserShaperSavant.java | 19 +++-- .../mage/sets/gatecrash/DinrovaHorror.java | 12 +-- .../src/mage/sets/gatecrash/DomriRade.java | 19 ++--- .../mage/sets/iceage/DemonicConsultation.java | 51 +++++------ .../src/mage/sets/innistrad/CaravanVigil.java | 15 ++-- Mage.Sets/src/mage/sets/invasion/Recoil.java | 17 ++-- .../journeyintonyx/AthreosGodOfPassage.java | 22 ++--- .../mage/sets/journeyintonyx/BrainMaggot.java | 21 ++--- .../src/mage/sets/journeyintonyx/Hubris.java | 16 ++-- .../journeyintonyx/NessianGameWarden.java | 22 ++--- .../sets/journeyintonyx/ScourgeOfFleets.java | 22 +++-- .../src/mage/sets/magic2011/Cultivate.java | 42 ++++----- .../src/mage/sets/magic2015/Quickling.java | 11 +-- .../src/mage/sets/mirage/ForbiddenCrypt.java | 34 ++++---- .../mage/sets/mirrodin/SpoilsOfTheVault.java | 29 +++---- .../sets/modernmasters/PetalsOfInsight.java | 32 +++---- .../sets/modernmasters2015/AllSunsDawn.java | 32 ++++--- .../src/mage/sets/onslaught/ChainOfVapor.java | 25 +++--- .../src/mage/sets/onslaught/WeirdHarvest.java | 28 +++--- .../sets/planeshift/SkyshipWeatherlight.java | 50 ++++++----- .../mage/sets/ravnica/CloudstoneCurio.java | 4 +- .../src/mage/sets/ravnica/DarkConfidant.java | 25 +++--- .../sets/returntoravnica/FaerieImpostor.java | 15 ++-- .../JaceArchitectOfThought.java | 2 +- .../saviorsofkamigawa/ElderPineOfJukai.java | 6 +- .../scarsofmirrodin/CerebralEruption.java | 24 +++--- .../sets/scarsofmirrodin/PsychicMiasma.java | 14 +-- .../sets/shadowmoor/AdviceFromTheFae.java | 21 ++--- .../mage/sets/shardsofalara/AdNauseam.java | 5 +- .../sets/shardsofalara/CruelUltimatum.java | 9 +- .../sets/shardsofalara/TidehollowSculler.java | 16 ++-- .../src/mage/sets/tenthedition/Abundance.java | 27 +++--- .../src/mage/sets/torment/MesmericFiend.java | 17 ++-- .../mage/sets/urzassaga/IllGottenGains.java | 22 ++--- .../sets/urzassaga/NoRestForTheWicked.java | 14 +-- .../src/mage/sets/zendikar/GoblinGuide.java | 23 +++-- .../combat/damage/GravebladeMarauderTest.java | 58 +++++++++++++ .../java/org/mage/test/player/TestPlayer.java | 8 +- .../common/ReturnToHandFromGraveyardCost.java | 18 ++-- .../ReturnToHandTargetPermanentCost.java | 7 +- .../ClashWinReturnToHandSpellEffect.java | 2 +- .../abilities/effects/common/EnvoyEffect.java | 16 ++-- ...ReturnFromGraveyardToHandTargetEffect.java | 31 +++---- ...ReturnSourceFromGraveyardToHandEffect.java | 13 ++- .../ReturnToHandFromBattlefieldAllEffect.java | 11 +-- .../common/ReturnToHandSourceEffect.java | 33 +++---- .../common/ReturnToHandSpellEffect.java | 2 +- .../RevealLibraryPutIntoHandEffect.java | 22 ++--- .../DiscardCardYouChooseTargetEffect.java | 6 +- .../search/SearchLibraryPutInHandEffect.java | 8 +- .../effects/keyword/SweepEffect.java | 10 +-- .../abilities/keyword/AuraSwapAbility.java | 85 +++++++++---------- .../abilities/keyword/TransmuteAbility.java | 51 ++++++----- Mage/src/mage/players/Player.java | 6 +- Mage/src/mage/players/PlayerImpl.java | 20 +++-- 83 files changed, 798 insertions(+), 816 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/triggers/combat/damage/GravebladeMarauderTest.java diff --git a/Mage.Sets/src/mage/sets/apocalypse/WildResearch.java b/Mage.Sets/src/mage/sets/apocalypse/WildResearch.java index 37eba90ac71..7784cb8d7f8 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/WildResearch.java +++ b/Mage.Sets/src/mage/sets/apocalypse/WildResearch.java @@ -28,6 +28,7 @@ package mage.sets.apocalypse; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -51,9 +52,10 @@ import mage.target.common.TargetCardInLibrary; * @author emerald000 */ public class WildResearch extends CardImpl { - + private static final FilterCard filterEnchantment = new FilterCard("enchantment card"); private static final FilterCard filterInstant = new FilterCard("instant card"); + static { filterEnchantment.add(new CardTypePredicate(CardType.ENCHANTMENT)); filterInstant.add(new CardTypePredicate(CardType.INSTANT)); @@ -65,7 +67,7 @@ public class WildResearch extends CardImpl { // {1}{W}: Search your library for an enchantment card and reveal that card. Put it into your hand, then discard a card at random. Then shuffle your library. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new WildResearchEffect(filterEnchantment), new ManaCostsImpl<>("{1}{W}"))); - + // {1}{U}: Search your library for an instant card and reveal that card. Put it into your hand, then discard a card at random. Then shuffle your library. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new WildResearchEffect(filterInstant), new ManaCostsImpl<>("{1}{U}"))); @@ -82,43 +84,44 @@ public class WildResearch extends CardImpl { } class WildResearchEffect extends OneShotEffect { - + protected final FilterCard filter; - + WildResearchEffect(FilterCard filter) { super(Outcome.DrawCard); this.staticText = "Search your library for an " + filter.getMessage() + " and reveal that card. Put it into your hand, then discard a card at random. Then shuffle your library."; this.filter = filter; } - + WildResearchEffect(final WildResearchEffect effect) { super(effect); this.filter = effect.filter; } - + @Override public WildResearchEffect copy() { return new WildResearchEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - Card card = player.getLibrary().remove(target.getFirstTarget(), game); + Card card = controller.getLibrary().remove(target.getFirstTarget(), game); if (card != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); Cards cards = new CardsImpl(); cards.add(card); - player.revealCards("Wild Research", cards, game, true); + controller.revealCards(sourceObject.getIdName(), cards, game, true); } } } - player.discardOne(true, source, game); - player.shuffleLibrary(game); + controller.discardOne(true, source, game); + controller.shuffleLibrary(game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/QuillmaneBaku.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/QuillmaneBaku.java index e8b0b354db3..b367b8f020f 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/QuillmaneBaku.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/QuillmaneBaku.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.betrayersofkamigawa; import java.util.UUID; @@ -39,7 +38,6 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -69,7 +67,7 @@ public class QuillmaneBaku extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(3); - + // Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Skullmane Baku. this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), filter, true)); @@ -87,11 +85,11 @@ public class QuillmaneBaku extends CardImpl { int maxConvManaCost = 0; for (Cost cost : ability.getCosts()) { if (cost instanceof RemoveVariableCountersSourceCost) { - maxConvManaCost = ((RemoveVariableCountersSourceCost)cost).getAmount(); + maxConvManaCost = ((RemoveVariableCountersSourceCost) cost).getAmount(); } } ability.getTargets().clear(); - FilterCreaturePermanent newFilter = new FilterCreaturePermanent("creature with converted mana cost " + maxConvManaCost + " or less"); + FilterCreaturePermanent newFilter = new FilterCreaturePermanent("creature with converted mana cost " + maxConvManaCost + " or less"); newFilter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, maxConvManaCost + 1)); TargetCreaturePermanent target = new TargetCreaturePermanent(newFilter); ability.getTargets().add(target); @@ -106,7 +104,7 @@ public class QuillmaneBaku extends CardImpl { public QuillmaneBaku copy() { return new QuillmaneBaku(this); } - + class QuillmaneBakuReturnEffect extends OneShotEffect { public QuillmaneBakuReturnEffect() { @@ -125,16 +123,15 @@ public class QuillmaneBaku extends CardImpl { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (permanent != null) { - player.moveCardToHandWithInfo((Card) permanent, source.getSourceId(), game, Zone.BATTLEFIELD); - return true; + controller.moveCards(permanent, null, Zone.HAND, source, game); } - return false; + return true; } } } diff --git a/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java b/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java index 0f0abeabc8c..d5fdc7aca32 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java @@ -27,8 +27,8 @@ */ package mage.sets.bornofthegods; -import java.util.List; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; @@ -44,7 +44,6 @@ import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterBasicLandCard; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; @@ -59,7 +58,6 @@ public class Peregrination extends CardImpl { super(ownerId, 132, "Peregrination", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{3}{G}"); this.expansionSetCode = "BNG"; - // Seach your library for up to two basic land cards, reveal those cards, and put one onto the battlefield tapped and the other into your hand. Shuffle your library, then scry 1. this.getSpellAbility().addEffect(new PeregrinationEffect()); Effect effect = new ScryEffect(1); @@ -97,36 +95,39 @@ class PeregrinationEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterBasicLandCard()); - Player player = game.getPlayer(source.getControllerId()); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { Cards revealed = new CardsImpl(); - for (UUID cardId: target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); + for (UUID cardId : target.getTargets()) { + Card card = controller.getLibrary().getCard(cardId, game); revealed.add(card); } - player.revealCards("Peregrination", revealed, game); + controller.revealCards(sourceObject.getIdName(), revealed, game); if (target.getTargets().size() == 2) { - TargetCard target2 = new TargetCard(Zone.PICK, filter); - player.choose(Outcome.Benefit, revealed, target2, game); + TargetCard target2 = new TargetCard(Zone.LIBRARY, filter); + controller.choose(Outcome.Benefit, revealed, target2, game); Card card = revealed.get(target2.getFirstTarget(), game); - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); revealed.remove(card); card = revealed.getCards(game).iterator().next(); - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - } - else if (target.getTargets().size() == 1) { + controller.moveCards(card, null, Zone.HAND, source, game); + } else if (target.getTargets().size() == 1) { Card card = revealed.getCards(game).iterator().next(); - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } diff --git a/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java b/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java index 11c738d3975..cd46582a1a4 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java @@ -103,13 +103,13 @@ class SatyrWayfinderEffect extends OneShotEffect { if (!cards.isEmpty()) { controller.revealCards(sourceObject.getName(), cards, game); TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand); - if (properCardFound && - controller.chooseUse(outcome, "Put a land card into your hand?", source, game) && - controller.choose(Outcome.DrawCard, cards, target, game)) { + if (properCardFound + && controller.chooseUse(outcome, "Put a land card into your hand?", source, game) + && controller.choose(Outcome.DrawCard, cards, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { cards.remove(card); - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); } } diff --git a/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java b/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java index 5196fbb0293..2669da9ec02 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java +++ b/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java @@ -28,6 +28,7 @@ package mage.sets.coldsnap; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -57,7 +58,7 @@ public class ScryingSheets extends CardImpl { // {tap}: Add {1} to your mana pool. this.addAbility(new ColorlessManaAbility()); - + // {1}{snow}, {tap}: Look at the top card of your library. If that card is snow, you may reveal it and put it into your hand. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScryingSheetsEffect(), new ManaCostsImpl<>("{1}{snow}")); ability.addCost(new TapSourceCost()); @@ -75,35 +76,35 @@ public class ScryingSheets extends CardImpl { } class ScryingSheetsEffect extends OneShotEffect { - + ScryingSheetsEffect() { super(Outcome.Benefit); this.staticText = "Look at the top card of your library. If that card is snow, you may reveal it and put it into your hand"; } - + ScryingSheetsEffect(final ScryingSheetsEffect effect) { super(effect); } - + @Override public ScryingSheetsEffect copy() { return new ScryingSheetsEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null && player.getLibrary().size() > 0) { - Card card = player.getLibrary().getFromTop(game); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + Card card = controller.getLibrary().getFromTop(game); if (card != null) { CardsImpl cards = new CardsImpl(); cards.add(card); - player.lookAtCards("Scrying Sheets", cards, game); + controller.lookAtCards(sourceObject.getIdName(), cards, game); if (card.getSupertype().contains("Snow")) { - if (player.chooseUse(outcome, new StringBuilder("Reveal ").append(card.getName()).append(" and put it into your hand?").toString(), source, game)) { - card = player.getLibrary().removeFromTop(game); - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - player.revealCards("Scrying Sheets", cards, game); + if (controller.chooseUse(outcome, "Reveal " + card.getLogName() + " and put it into your hand?", source, game)) { + controller.moveCards(card, null, Zone.HAND, source, game); + controller.revealCards(sourceObject.getIdName(), cards, game); } } } diff --git a/Mage.Sets/src/mage/sets/commander/DesecratorHag.java b/Mage.Sets/src/mage/sets/commander/DesecratorHag.java index e596914c128..6f13d8c35af 100644 --- a/Mage.Sets/src/mage/sets/commander/DesecratorHag.java +++ b/Mage.Sets/src/mage/sets/commander/DesecratorHag.java @@ -113,22 +113,20 @@ class DesecratorHagEffect extends OneShotEffect { } } if (cards.size() == 0) { - return false; + return true; } if (cards.size() > 1 && you.choose(Outcome.DrawCard, cards, target, game)) { if (target != null) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - return you.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + return you.moveCards(card, null, Zone.HAND, source, game); } } } else { - for (Card card : cards.getCards(game)) { - return you.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); - } + return you.moveCards(cards, null, Zone.HAND, source, game); } } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/commander/KodamasReach.java b/Mage.Sets/src/mage/sets/commander/KodamasReach.java index 1be260fab28..6b7883e9e8b 100644 --- a/Mage.Sets/src/mage/sets/commander/KodamasReach.java +++ b/Mage.Sets/src/mage/sets/commander/KodamasReach.java @@ -27,8 +27,8 @@ */ package mage.sets.commander; -import java.util.List; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -57,7 +57,6 @@ public class KodamasReach extends CardImpl { this.expansionSetCode = "CMD"; this.subtype.add("Arcane"); - // Search your library for up to two basic land cards, reveal those cards, and put one onto the battlefield tapped and the other into your hand. Then shuffle your library. this.getSpellAbility().addEffect(new KodamasReachEffect()); } @@ -92,43 +91,46 @@ class KodamasReachEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterBasicLandCard()); - Player player = game.getPlayer(source.getControllerId()); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { Cards revealed = new CardsImpl(); - for (UUID cardId: target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); + for (UUID cardId : target.getTargets()) { + Card card = controller.getLibrary().getCard(cardId, game); revealed.add(card); } - player.revealCards("Kodama's Reach", revealed, game); + controller.revealCards(sourceObject.getIdName(), revealed, game); if (target.getTargets().size() == 2) { TargetCard target2 = new TargetCard(Zone.PICK, filter); - player.choose(Outcome.Benefit, revealed, target2, game); + controller.choose(Outcome.Benefit, revealed, target2, game); Card card = revealed.get(target2.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); revealed.remove(card); } card = revealed.getCards(game).iterator().next(); if (card != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); } - } - else if (target.getTargets().size() == 1) { + } else if (target.getTargets().size() == 1) { Card card = revealed.getCards(game).iterator().next(); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); } } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java b/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java index 88036f444a0..b8c2db6801f 100644 --- a/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java +++ b/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java @@ -51,7 +51,6 @@ public class WhirlpoolWhelm extends CardImpl { super(ownerId, 69, "Whirlpool Whelm", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); this.expansionSetCode = "CMD"; - // Clash with an opponent, then return target creature to its owner's hand. If you win, you may put that creature on top of its owner's library instead. this.getSpellAbility().addEffect(new WhirlpoolWhelmEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); @@ -90,15 +89,15 @@ class WhirlpoolWhelmEffect extends OneShotEffect { if (controller != null) { boolean topOfLibrary = false; if (ClashEffect.getInstance().apply(game, source)) { - topOfLibrary = controller.chooseUse(outcome, "Put " + creature.getLogName() + " to top of libraray instead?" , source, game); + topOfLibrary = controller.chooseUse(outcome, "Put " + creature.getLogName() + " to top of libraray instead?", source, game); } if (topOfLibrary) { - controller.moveCardToHandWithInfo(creature, source.getSourceId(), game, Zone.BATTLEFIELD); - } else { controller.moveCardToLibraryWithInfo(creature, source.getSourceId(), game, Zone.BATTLEFIELD, true, true); + } else { + controller.moveCards(creature, null, Zone.HAND, source, game); } return true; } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/commander2014/GraveSifter.java b/Mage.Sets/src/mage/sets/commander2014/GraveSifter.java index 11a5d889289..e9dd6df2171 100644 --- a/Mage.Sets/src/mage/sets/commander2014/GraveSifter.java +++ b/Mage.Sets/src/mage/sets/commander2014/GraveSifter.java @@ -32,8 +32,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; @@ -101,22 +101,17 @@ class GraveSifterEffect extends OneShotEffect { typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { typeChoice.clearChoice(); if (player.choose(outcome, typeChoice, game)) { game.informPlayers(player.getLogName() + " has chosen: " + typeChoice.getChoice()); - FilterCard filter = new FilterCreatureCard("creature cards with creature type " + typeChoice.getChoice()+ " from your graveyard"); + FilterCard filter = new FilterCreatureCard("creature cards with creature type " + typeChoice.getChoice() + " from your graveyard"); filter.add(new SubtypePredicate(typeChoice.getChoice())); - Target target = new TargetCardInYourGraveyard(0,Integer.MAX_VALUE, filter); + Target target = new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, filter); player.chooseTarget(outcome, target, source, game); - for (UUID cardId: target.getTargets()) { - Card card = game.getCard(cardId); - if (card !=null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); - } - } + player.moveCards(new CardsImpl(target.getTargets()), null, Zone.HAND, source, game); } } diff --git a/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java b/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java index f5ceb039692..09778edade8 100644 --- a/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java +++ b/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java @@ -28,10 +28,6 @@ package mage.sets.conflux; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -42,6 +38,10 @@ import mage.abilities.keyword.VigilanceAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -73,7 +73,7 @@ public class SkywardEyeProphets extends CardImpl { public SkywardEyeProphets copy() { return new SkywardEyeProphets(this); } - + public static class SkywardEyeProphetsEffect extends OneShotEffect { public SkywardEyeProphetsEffect() { @@ -108,7 +108,7 @@ public class SkywardEyeProphets extends CardImpl { if (card.getCardType().contains(CardType.LAND)) { return controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); } else { - return controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/darksteel/PulseOfTheFields.java b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheFields.java index 49191523e34..a6ee275f3b7 100644 --- a/Mage.Sets/src/mage/sets/darksteel/PulseOfTheFields.java +++ b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheFields.java @@ -66,21 +66,21 @@ public class PulseOfTheFields extends CardImpl { } class PulseOfTheFieldsReturnToHandEffect extends OneShotEffect { - + PulseOfTheFieldsReturnToHandEffect() { super(Outcome.Benefit); this.staticText = "Then if an opponent has more life than you, return {this} to its owner's hand"; } - + PulseOfTheFieldsReturnToHandEffect(final PulseOfTheFieldsReturnToHandEffect effect) { super(effect); } - + @Override public PulseOfTheFieldsReturnToHandEffect copy() { return new PulseOfTheFieldsReturnToHandEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -89,7 +89,7 @@ class PulseOfTheFieldsReturnToHandEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null && player.getLife() > controller.getLife()) { Card card = game.getCard(source.getSourceId()); - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.STACK); + controller.moveCards(card, null, Zone.HAND, source, game); return true; } } diff --git a/Mage.Sets/src/mage/sets/darksteel/PulseOfTheGrid.java b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheGrid.java index 74a9349270e..1e8179a260f 100644 --- a/Mage.Sets/src/mage/sets/darksteel/PulseOfTheGrid.java +++ b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheGrid.java @@ -66,21 +66,21 @@ public class PulseOfTheGrid extends CardImpl { } class PulseOfTheGridReturnToHandEffect extends OneShotEffect { - + PulseOfTheGridReturnToHandEffect() { super(Outcome.Benefit); this.staticText = "Draw two cards, then discard a card. Then if an opponent has more cards in hand than you, return {this} to its owner's hand"; } - + PulseOfTheGridReturnToHandEffect(final PulseOfTheGridReturnToHandEffect effect) { super(effect); } - + @Override public PulseOfTheGridReturnToHandEffect copy() { return new PulseOfTheGridReturnToHandEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -89,7 +89,7 @@ class PulseOfTheGridReturnToHandEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null && player.getHand().size() > controller.getHand().size()) { Card card = game.getCard(source.getSourceId()); - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.STACK); + controller.moveCards(card, null, Zone.HAND, source, game); return true; } } diff --git a/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java b/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java index b090e5ffd8b..7efdd4e8fe6 100644 --- a/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java +++ b/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.darksteel; import java.util.UUID; @@ -105,7 +104,7 @@ public class SwordOfLightAndShadow extends CardImpl { // Target may only be added if possible target exists. Else the gain life effect won't trigger, becuase there is no valid target for the // return to hand ability if (controller.getGraveyard().count(new FilterCreatureCard(), ability.getSourceId(), ability.getControllerId(), game) > 0) { - ability.addTarget(new TargetCardInYourGraveyard(0,1,new FilterCreatureCard("creature card from your graveyard"))); + ability.addTarget(new TargetCardInYourGraveyard(0, 1, new FilterCreatureCard("creature card from your graveyard"))); } } } @@ -118,7 +117,7 @@ class SwordOfLightAndShadowAbility extends TriggeredAbilityImpl { public SwordOfLightAndShadowAbility() { super(Zone.BATTLEFIELD, new SwordOfLightAndShadowReturnToHandTargetEffect(), false); this.addEffect(new GainLifeEffect(3)); - + } public SwordOfLightAndShadowAbility(final SwordOfLightAndShadowAbility ability) { @@ -178,8 +177,8 @@ class SwordOfLightAndShadowReturnToHandTargetEffect extends OneShotEffect { case GRAVEYARD: Card card = game.getCard(targetId); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); - } else { + controller.moveCards(card, null, Zone.HAND, source, game); + } else { result = false; } break; diff --git a/Mage.Sets/src/mage/sets/dissension/RiseFall.java b/Mage.Sets/src/mage/sets/dissension/RiseFall.java index bfae9994127..91403495f23 100644 --- a/Mage.Sets/src/mage/sets/dissension/RiseFall.java +++ b/Mage.Sets/src/mage/sets/dissension/RiseFall.java @@ -29,15 +29,15 @@ package mage.sets.dissension; import java.util.UUID; import mage.MageObject; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.cards.SplitCard; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; @@ -54,9 +54,9 @@ import mage.target.common.TargetCreaturePermanent; public class RiseFall extends SplitCard { public RiseFall(UUID ownerId) { - super(ownerId, 156, "Rise", "Fall", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{U}{B}","{B}{R}", false ); + super(ownerId, 156, "Rise", "Fall", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{U}{B}", "{B}{R}", false); this.expansionSetCode = "DIS"; - + // Rise // Return target creature card from a graveyard and target creature on the battlefield to their owners' hands. getLeftHalfCard().getSpellAbility().addEffect(new RiseEffect()); @@ -99,14 +99,16 @@ class RiseEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { + Cards cardsToHand = new CardsImpl(); Card cardInGraveyard = game.getCard(getTargetPointer().getFirst(game, source)); if (cardInGraveyard != null) { - controller.moveCardToHandWithInfo(cardInGraveyard, source.getSourceId(), game, Zone.GRAVEYARD); + cardsToHand.add(cardInGraveyard); } Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); if (permanent != null) { - controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + cardsToHand.add(permanent); } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return false; @@ -147,7 +149,7 @@ class FallEffect extends OneShotEffect { cards.add(card); } targetPlayer.revealCards(sourceObject.getName(), cards, game); - for (Card cardToDiscard: cards.getCards(game)) { + for (Card cardToDiscard : cards.getCards(game)) { if (!cardToDiscard.getCardType().contains(CardType.LAND)) { targetPlayer.discard(cardToDiscard, source, game); } diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/MorgueBurst.java b/Mage.Sets/src/mage/sets/dragonsmaze/MorgueBurst.java index 2e3983e47e1..43f7b05fb55 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/MorgueBurst.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/MorgueBurst.java @@ -28,15 +28,14 @@ package mage.sets.dragonsmaze; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; @@ -55,7 +54,6 @@ public class MorgueBurst extends CardImpl { super(ownerId, 86, "Morgue Burst", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{4}{B}{R}"); this.expansionSetCode = "DGM"; - // Return target creature card from your graveyard to your hand. Morgue Burst deals damage to target creature or player equal to the power of the card returned this way. this.getSpellAbility().addEffect(new MorgueBurstEffect()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); @@ -93,7 +91,7 @@ class MorgueBurstEffect extends OneShotEffect { if (card != null) { Player player = game.getPlayer(card.getOwnerId()); if (player != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.HAND); + player.moveCards(card, null, Zone.HAND, source, game); int damage = card.getPower().getValue(); Permanent creature = game.getPermanent(source.getTargets().get(1).getTargets().get(0)); if (creature != null) { diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java index 7323fddb268..68212d32e00 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java @@ -95,9 +95,9 @@ class FoulRenewalEffect extends OneShotEffect { Card card = game.getCard(targetPointer.getFirst(game, source)); if (card != null) { int xValue = card.getToughness().getValue() * -1; - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + controller.moveCards(card, null, Zone.HAND, source, game); if (xValue != 0) { - ContinuousEffect effect = new BoostTargetEffect(xValue,xValue, Duration.EndOfTurn); + ContinuousEffect effect = new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(source.getTargets().get(1).getFirstTarget())); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java index a490b0d3a06..639d3f36c38 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java @@ -60,7 +60,6 @@ import mage.game.stack.Spell; import mage.players.Player; import mage.target.targetpointer.FixedTarget; - /** * * @author LevelX2 @@ -73,13 +72,13 @@ public class NarsetTranscendent extends CardImpl { this.subtype.add("Narset"); this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); - + // +1: Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand. this.addAbility(new LoyaltyAbility(new NarsetTranscendentEffect1(), 1)); - + // -2: When you cast your next instant or sorcery spell from your hand this turn, it gains rebound. this.addAbility(new LoyaltyAbility(new CreateDelayedTriggeredAbilityEffect(new NarsetTranscendentTriggeredAbility()), -2)); - + // -9:You get an emblem with "Your opponents can't cast noncreature spells." this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new NarsetTranscendentEmblem()), -9)); } @@ -119,11 +118,11 @@ class NarsetTranscendentEffect1 extends OneShotEffect { if (card != null) { CardsImpl cards = new CardsImpl(); cards.add(card); - controller.lookAtCards(sourceObject.getName(), cards, game); + controller.lookAtCards(sourceObject.getIdName(), cards, game); if (!card.getCardType().contains(CardType.CREATURE) && !card.getCardType().contains(CardType.LAND)) { - if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", source, game)) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - controller.revealCards(sourceObject.getName(), cards, game); + if (controller.chooseUse(outcome, "Reveal " + card.getLogName() + " and put it into your hand?", source, game)) { + controller.moveCards(card, null, Zone.HAND, source, game); + controller.revealCards(sourceObject.getIdName(), cards, game); } } return true; @@ -142,6 +141,7 @@ class NarsetTranscendentTriggeredAbility extends DelayedTriggeredAbility { private NarsetTranscendentTriggeredAbility(final NarsetTranscendentTriggeredAbility ability) { super(ability); } + @Override public NarsetTranscendentTriggeredAbility copy() { return new NarsetTranscendentTriggeredAbility(this); @@ -157,9 +157,9 @@ class NarsetTranscendentTriggeredAbility extends DelayedTriggeredAbility { if (event.getPlayerId().equals(this.getControllerId())) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && spell.getFromZone().equals(Zone.HAND)) { - if (spell.getCard() != null && - spell.getCard().getCardType().contains(CardType.INSTANT) || spell.getCard().getCardType().contains(CardType.SORCERY)) { - for(Effect effect: getEffects()) { + if (spell.getCard() != null + && spell.getCard().getCardType().contains(CardType.INSTANT) || spell.getCard().getCardType().contains(CardType.SORCERY)) { + for (Effect effect : getEffects()) { effect.setTargetPointer(new FixedTarget(spell.getId())); } return true; @@ -171,7 +171,7 @@ class NarsetTranscendentTriggeredAbility extends DelayedTriggeredAbility { @Override public String getRule() { - return "When you cast your next instant or sorcery spell from your hand this turn, " + super.getRule() ; + return "When you cast your next instant or sorcery spell from your hand this turn, " + super.getRule(); } } @@ -226,11 +226,11 @@ class NarsetTranscendentGainReboundEffect extends ContinuousEffectImpl { class NarsetTranscendentEmblem extends Emblem { // "Your opponents can't cast noncreature spells. - + public NarsetTranscendentEmblem() { - + this.setName("EMBLEM: Narset Transcendent"); - + this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new NarsetTranscendentCantCastEffect())); } } @@ -269,7 +269,7 @@ class NarsetTranscendentCantCastEffect extends ContinuousRuleModifyingEffectImpl public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.CAST_SPELL; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ProfanerOfTheDead.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ProfanerOfTheDead.java index b3c97cb4142..46e06e3a618 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/ProfanerOfTheDead.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ProfanerOfTheDead.java @@ -34,6 +34,8 @@ import mage.abilities.common.ExploitCreatureTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.ExploitAbility; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -99,9 +101,11 @@ class ProfanerOfTheDeadReturnEffect extends OneShotEffect { FilterCreaturePermanent filter = new FilterCreaturePermanent(); filter.add(new ControllerPredicate(TargetController.OPPONENT)); filter.add(new ToughnessPredicate(Filter.ComparisonType.LessThan, exploitedCreature.getToughness().getValue())); + Cards cardsToHand = new CardsImpl(); for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + cardsToHand.add(permanent); } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/VolcanicVision.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/VolcanicVision.java index 350cc728fac..b579e59ca82 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/VolcanicVision.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/VolcanicVision.java @@ -105,10 +105,10 @@ class VolcanicVisionReturnToHandTargetEffect extends OneShotEffect { case GRAVEYARD: Card card = game.getCard(targetId); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + controller.moveCards(card, null, Zone.HAND, source, game); int damage = card.getManaCost().convertedManaCost(); if (damage > 0) { - for(Permanent creature: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { creature.damage(damage, source.getSourceId(), game, false, true); } } diff --git a/Mage.Sets/src/mage/sets/elspethvstezzeret/EchoingTruth.java b/Mage.Sets/src/mage/sets/elspethvstezzeret/EchoingTruth.java index 772509be82a..2e52c6bcb58 100644 --- a/Mage.Sets/src/mage/sets/elspethvstezzeret/EchoingTruth.java +++ b/Mage.Sets/src/mage/sets/elspethvstezzeret/EchoingTruth.java @@ -32,12 +32,13 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.NamePredicate; import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; @@ -96,11 +97,13 @@ class ReturnToHandAllNamedPermanentsEffect extends OneShotEffect { if (permanent.getName().isEmpty()) { filter.add(new PermanentIdPredicate(permanent.getId())); // if no name (face down creature) only the creature itself is selected } else { - filter.add(new NamePredicate(permanent.getName())); + filter.add(new NamePredicate(permanent.getName())); } - for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { - controller.moveCardToHandWithInfo(perm, source.getSourceId(), game, Zone.BATTLEFIELD); + Cards cardsToHand = new CardsImpl(); + for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { + cardsToHand.add(perm); } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return true; diff --git a/Mage.Sets/src/mage/sets/fatereforged/RenownedWeaponsmith.java b/Mage.Sets/src/mage/sets/fatereforged/RenownedWeaponsmith.java index 1797c0979be..f82c282471f 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/RenownedWeaponsmith.java +++ b/Mage.Sets/src/mage/sets/fatereforged/RenownedWeaponsmith.java @@ -115,7 +115,7 @@ class RenownedWeaponsmithCondition implements Condition { @Override public boolean apply(Game game, Ability source) { MageObject object = game.getObject(source.getSourceId()); - return (object != null + return (object != null && object.getCardType().contains(CardType.ARTIFACT)); } } @@ -149,8 +149,8 @@ class RenownedWeaponsmithEffect extends OneShotEffect { Card card = game.getCard(target.getFirstTarget()); Cards revealed = new CardsImpl(); revealed.add(card); - controller.revealCards(sourceObject.getName(), revealed, game); - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.revealCards(sourceObject.getIdName(), revealed, game); + controller.moveCards(revealed, null, Zone.HAND, source, game); } } controller.shuffleLibrary(game); diff --git a/Mage.Sets/src/mage/sets/fatereforged/SageEyeAvengers.java b/Mage.Sets/src/mage/sets/fatereforged/SageEyeAvengers.java index f14d8c67ae7..191c9540b6b 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/SageEyeAvengers.java +++ b/Mage.Sets/src/mage/sets/fatereforged/SageEyeAvengers.java @@ -100,7 +100,7 @@ class SageEyeAvengersEffect extends OneShotEffect { if (sourceObject != null && controller != null) { Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (targetCreature != null && targetCreature.getPower().getValue() < sourceObject.getPower().getValue()) { - controller.moveCardToHandWithInfo(targetCreature, source.getSourceId(), game, Zone.BATTLEFIELD); + controller.moveCards(targetCreature, null, Zone.HAND, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/fatereforged/SoulfireGrandMaster.java b/Mage.Sets/src/mage/sets/fatereforged/SoulfireGrandMaster.java index 00b2744e19f..55fb26acdff 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/SoulfireGrandMaster.java +++ b/Mage.Sets/src/mage/sets/fatereforged/SoulfireGrandMaster.java @@ -130,28 +130,28 @@ class GainAbilitySpellsEffect extends ContinuousEffectImpl { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { - for (Card card: game.getExile().getAllCards(game)) { + for (Card card : game.getExile().getAllCards(game)) { if (card.getOwnerId().equals(source.getControllerId()) && filter.match(card, game)) { game.getState().addOtherAbility(card, ability); } } - for (Card card: player.getLibrary().getCards(game)) { + for (Card card : player.getLibrary().getCards(game)) { if (filter.match(card, game)) { game.getState().addOtherAbility(card, ability); } } - for (Card card: player.getHand().getCards(game)) { + for (Card card : player.getHand().getCards(game)) { if (filter.match(card, game)) { game.getState().addOtherAbility(card, ability); } } - for (Card card: player.getGraveyard().getCards(game)) { + for (Card card : player.getGraveyard().getCards(game)) { if (filter.match(card, game)) { game.getState().addOtherAbility(card, ability); } } for (StackObject stackObject : game.getStack()) { - if (stackObject.getControllerId().equals(source.getControllerId())) { + if (stackObject.getControllerId().equals(source.getControllerId())) { Card card = game.getCard(stackObject.getSourceId()); if (card != null && filter.match(card, game)) { if (!card.getAbilities().contains(ability)) { @@ -199,15 +199,15 @@ class SoulfireGrandMasterCastFromHandReplacementEffect extends ReplacementEffect @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - MageObject mageObject = game.getObject(spellId); - if (mageObject == null || !(mageObject instanceof Spell) || ((Spell)mageObject).isCopiedSpell()) { + MageObject mageObject = game.getObject(spellId); + if (mageObject == null || !(mageObject instanceof Spell) || ((Spell) mageObject).isCopiedSpell()) { return false; } else { Card sourceCard = game.getCard(spellId); if (sourceCard != null) { Player player = game.getPlayer(sourceCard.getOwnerId()); if (player != null) { - player.moveCardToHandWithInfo(sourceCard, source.getSourceId(), game, Zone.STACK); + player.moveCards(sourceCard, null, Zone.HAND, source, game); discard(); return true; } @@ -215,6 +215,7 @@ class SoulfireGrandMasterCastFromHandReplacementEffect extends ReplacementEffect } return false; } + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ZONE_CHANGE; @@ -225,21 +226,21 @@ class SoulfireGrandMasterCastFromHandReplacementEffect extends ReplacementEffect //Something hit the stack from the hand, see if its a spell with this ability. ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (spellId == null && // because this effect works only once, spellId has to be null here - zEvent.getFromZone() == Zone.HAND && - zEvent.getToZone() == Zone.STACK && - event.getPlayerId().equals(source.getControllerId())) { + zEvent.getFromZone() == Zone.HAND + && zEvent.getToZone() == Zone.STACK + && event.getPlayerId().equals(source.getControllerId())) { MageObject object = game.getObject(event.getTargetId()); if (object instanceof Card) { - if (filter.match((Card)object, game)) { + if (filter.match((Card) object, game)) { this.spellId = event.getTargetId(); } } } else { // the spell goes to graveyard now so move it to hand again - if (zEvent.getFromZone() == Zone.STACK && - zEvent.getToZone() == Zone.GRAVEYARD && - event.getTargetId().equals(spellId)) { - Spell spell = game.getStack().getSpell(spellId); + if (zEvent.getFromZone() == Zone.STACK + && zEvent.getToZone() == Zone.GRAVEYARD + && event.getTargetId().equals(spellId)) { + Spell spell = game.getStack().getSpell(spellId); if (spell != null && !spell.isCountered()) { return true; } diff --git a/Mage.Sets/src/mage/sets/fatereforged/SuddenReclamation.java b/Mage.Sets/src/mage/sets/fatereforged/SuddenReclamation.java index 3d9e62e2566..cb213a637ed 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/SuddenReclamation.java +++ b/Mage.Sets/src/mage/sets/fatereforged/SuddenReclamation.java @@ -33,6 +33,8 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -89,24 +91,26 @@ class SuddenReclamationEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { + Cards cardsToHand = new CardsImpl(); Target target = new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard")); target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseTarget(outcome, target, source, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) + && controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + cardsToHand.add(card); } } target = new TargetCardInYourGraveyard(new FilterLandCard("land card from your graveyard")); target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseTarget(outcome, target, source, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) + && controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + cardsToHand.add(card); } } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/fatereforged/TasigurTheGoldenFang.java b/Mage.Sets/src/mage/sets/fatereforged/TasigurTheGoldenFang.java index 466312f6bcb..4219bb760d4 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/TasigurTheGoldenFang.java +++ b/Mage.Sets/src/mage/sets/fatereforged/TasigurTheGoldenFang.java @@ -120,7 +120,7 @@ class TasigurTheGoldenFangEffect extends OneShotEffect { opponent.chooseTarget(outcome, target, source, game); Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + controller.moveCards(card, null, Zone.HAND, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java b/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java index 465bb3dcfda..a953de52613 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java +++ b/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java @@ -103,13 +103,13 @@ class TemurSabertoothEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Target target = new TargetPermanent(1,1, filter, true); + Target target = new TargetPermanent(1, 1, filter, true); if (target.canChoose(source.getSourceId(), controller.getId(), game)) { - if (controller.chooseUse(outcome, "Return another creature to hand?", source, game) && - controller.chooseTarget(outcome, target, source, game)) { + if (controller.chooseUse(outcome, "Return another creature to hand?", source, game) + && controller.chooseTarget(outcome, target, source, game)) { Permanent toHand = game.getPermanent(target.getFirstTarget()); if (toHand != null) { - controller.moveCardToHandWithInfo(toHand, source.getSourceId(), game, Zone.BATTLEFIELD); + controller.moveCards(toHand, null, Zone.HAND, source, game); } game.addEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), source); } diff --git a/Mage.Sets/src/mage/sets/fifthedition/Recall.java b/Mage.Sets/src/mage/sets/fifthedition/Recall.java index cbbb5e68973..ff5e44b188d 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/Recall.java +++ b/Mage.Sets/src/mage/sets/fifthedition/Recall.java @@ -31,8 +31,9 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSpellEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -52,7 +53,6 @@ public class Recall extends CardImpl { super(ownerId, 93, "Recall", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{X}{U}"); this.expansionSetCode = "5ED"; - // Discard X cards, then return a card from your graveyard to your hand for each card discarded this way. this.getSpellAbility().addEffect(new RecallEffect()); // Exile Recall. @@ -75,38 +75,33 @@ class RecallEffect extends OneShotEffect { super(Outcome.ReturnToHand); this.staticText = "Discard X cards, then return a card from your graveyard to your hand for each card discarded this way. "; } - + public RecallEffect(final RecallEffect effect) { super(effect); } - + @Override public RecallEffect copy() { return new RecallEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { // Discard X cards - int amount = source.getManaCostsToPay().getX(); - int discarded = Math.min(amount, player.getHand().size()); - player.discard(amount, false, source, game); - - // then return a card from your graveyard to your hand for each card discarded this way - TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(discarded, new FilterCard()); - target.choose(Outcome.ReturnToHand, player.getId(), source.getSourceId(), game); - for (UUID targetId : target.getTargets()) { - Card card = game.getCard(targetId); - if (card != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); - } + Cards cardsDiscarded = controller.discard(source.getManaCostsToPay().getX(), false, source, game); + if (!cardsDiscarded.isEmpty()) { + // then return a card from your graveyard to your hand for each card discarded this way + TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(cardsDiscarded.size(), new FilterCard()); + target.setNotTarget(true); + target.choose(Outcome.ReturnToHand, controller.getId(), source.getSourceId(), game); + controller.moveCards(new CardsImpl(target.getTargets()), null, Zone.HAND, source, game); } - + return true; } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/futuresight/LinessaZephyrMage.java b/Mage.Sets/src/mage/sets/futuresight/LinessaZephyrMage.java index 16b11f8a818..2d70219a2a8 100644 --- a/Mage.Sets/src/mage/sets/futuresight/LinessaZephyrMage.java +++ b/Mage.Sets/src/mage/sets/futuresight/LinessaZephyrMage.java @@ -76,13 +76,13 @@ public class LinessaZephyrMage extends CardImpl { ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // Grandeur - Discard another card named Linessa, Zephyr Mage: Target player returns a creature he or she controls to its owner's hand, then repeats this process for an artifact, an enchantment, and a land. ability = new GrandeurAbility(new LinessaZephyrMageEffect(), "Linessa, Zephyr Mage"); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } - + public LinessaZephyrMage(final LinessaZephyrMage card) { super(card); } @@ -105,21 +105,21 @@ public class LinessaZephyrMage extends CardImpl { } class LinessaZephyrMageEffect extends OneShotEffect { - + LinessaZephyrMageEffect() { super(Outcome.ReturnToHand); this.staticText = "Target player returns a creature he or she controls to its owner's hand, then repeats this process for an artifact, an enchantment, and a land"; } - + LinessaZephyrMageEffect(final LinessaZephyrMageEffect effect) { super(effect); } - + @Override public LinessaZephyrMageEffect copy() { return new LinessaZephyrMageEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -132,7 +132,7 @@ class LinessaZephyrMageEffect extends OneShotEffect { if (target.choose(Outcome.ReturnToHand, targetPlayer.getId(), source.getSourceId(), game)) { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { - targetPlayer.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + targetPlayer.moveCards(permanent, null, Zone.HAND, source, game); } } @@ -144,10 +144,10 @@ class LinessaZephyrMageEffect extends OneShotEffect { if (target.choose(Outcome.ReturnToHand, targetPlayer.getId(), source.getSourceId(), game)) { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { - targetPlayer.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + targetPlayer.moveCards(permanent, null, Zone.HAND, source, game); } } - + // an enchantment, filter = new FilterControlledPermanent("enchantment you control"); filter.add(new CardTypePredicate(CardType.ENCHANTMENT)); @@ -156,10 +156,10 @@ class LinessaZephyrMageEffect extends OneShotEffect { if (target.choose(Outcome.ReturnToHand, targetPlayer.getId(), source.getSourceId(), game)) { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { - targetPlayer.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + targetPlayer.moveCards(permanent, null, Zone.HAND, source, game); } } - + // and a land. filter = new FilterControlledPermanent("land you control"); filter.add(new CardTypePredicate(CardType.LAND)); @@ -168,10 +168,10 @@ class LinessaZephyrMageEffect extends OneShotEffect { if (target.choose(Outcome.ReturnToHand, targetPlayer.getId(), source.getSourceId(), game)) { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { - targetPlayer.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + targetPlayer.moveCards(permanent, null, Zone.HAND, source, game); } } - + return true; } } diff --git a/Mage.Sets/src/mage/sets/futuresight/VenserShaperSavant.java b/Mage.Sets/src/mage/sets/futuresight/VenserShaperSavant.java index 6cf33d4ecbb..1045ba09c7c 100644 --- a/Mage.Sets/src/mage/sets/futuresight/VenserShaperSavant.java +++ b/Mage.Sets/src/mage/sets/futuresight/VenserShaperSavant.java @@ -103,18 +103,19 @@ class VenserShaperSavantEffect extends OneShotEffect { if (controller != null) { Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (permanent != null) { - return controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + return controller.moveCards(permanent, null, Zone.HAND, source, game); } /** - * 01.05.2007 If a spell is returned to its owner's hand, it's removed from - * the stack and thus will not resolve. The spell isn't countered; it just no longer exists. - * 01.05.2007 If a copy of a spell is returned to its owner's hand, it's moved there, - * then it will cease to exist as a state-based action. - * 01.05.2007 If Venser's enters-the-battlefield ability targets a spell cast with flashback, - * that spell will be exiled instead of returning to its owner's hand. + * 01.05.2007 If a spell is returned to its owner's hand, it's + * removed from the stack and thus will not resolve. The spell isn't + * countered; it just no longer exists. 01.05.2007 If a copy of a + * spell is returned to its owner's hand, it's moved there, then it + * will cease to exist as a state-based action. 01.05.2007 If + * Venser's enters-the-battlefield ability targets a spell cast with + * flashback, that spell will be exiled instead of returning to its + * owner's hand. */ - Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); if (spell != null) { Card card = null; @@ -123,7 +124,7 @@ class VenserShaperSavantEffect extends OneShotEffect { } game.getStack().remove(spell); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.STACK); + controller.moveCards(card, null, Zone.HAND, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/gatecrash/DinrovaHorror.java b/Mage.Sets/src/mage/sets/gatecrash/DinrovaHorror.java index 5eab7a69163..042d85b8e69 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/DinrovaHorror.java +++ b/Mage.Sets/src/mage/sets/gatecrash/DinrovaHorror.java @@ -28,15 +28,15 @@ package mage.sets.gatecrash; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -95,8 +95,8 @@ class DinrovaHorrorEffect extends OneShotEffect { if (target != null) { Player controller = game.getPlayer(target.getControllerId()); if (controller != null) { - controller.moveCardToHandWithInfo(target, source.getSourceId(), game, Zone.BATTLEFIELD); - controller.discard(1, source, game); + controller.moveCards(target, null, Zone.HAND, source, game); + controller.discard(1, false, source, game); return true; } } diff --git a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java index 40ec318e1bd..0d92cdf0bac 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java +++ b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java @@ -29,11 +29,6 @@ package mage.sets.gatecrash; import java.util.UUID; import mage.MageObject; - -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.EntersBattlefieldAbility; @@ -50,7 +45,11 @@ import mage.abilities.keyword.TrampleAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; @@ -71,8 +70,6 @@ public class DomriRade extends CardImpl { this.expansionSetCode = "GTC"; this.subtype.add("Domri"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); // +1: Look at the top card of your library. If it's a creature card, you may reveal it and put it into your hand. @@ -127,8 +124,8 @@ class DomriRadeEffect1 extends OneShotEffect { controller.lookAtCards(sourceObject.getName(), cards, game); if (card.getCardType().contains(CardType.CREATURE)) { if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", source, game)) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - controller.revealCards(sourceObject.getName(), cards, game); + controller.moveCards(card, null, Zone.HAND, source, game); + controller.revealCards(sourceObject.getIdName(), cards, game); } } return true; @@ -139,7 +136,9 @@ class DomriRadeEffect1 extends OneShotEffect { } class DomriRadeEmblem extends Emblem { + // "Creatures you control have double strike, trample, hexproof and haste." + public DomriRadeEmblem() { this.setName("EMBLEM: Domri Rade"); FilterPermanent filter = new FilterControlledCreaturePermanent("Creatures"); @@ -156,7 +155,7 @@ class DomriRadeEmblem extends Emblem { } class DomriRadeTargetOtherCreaturePermanent extends TargetCreaturePermanent { - + public DomriRadeTargetOtherCreaturePermanent() { super(); } diff --git a/Mage.Sets/src/mage/sets/iceage/DemonicConsultation.java b/Mage.Sets/src/mage/sets/iceage/DemonicConsultation.java index fec01eeb83c..79f6528f5b4 100644 --- a/Mage.Sets/src/mage/sets/iceage/DemonicConsultation.java +++ b/Mage.Sets/src/mage/sets/iceage/DemonicConsultation.java @@ -28,6 +28,7 @@ package mage.sets.iceage; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -54,7 +55,6 @@ public class DemonicConsultation extends CardImpl { super(ownerId, 9, "Demonic Consultation", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{B}"); this.expansionSetCode = "ICE"; - // Name a card. Exile the top six cards of your library, then reveal cards from the top of your library until you reveal the named card. Put that card into your hand and exile all other cards revealed this way. this.getSpellAbility().addEffect(new DemonicConsultationEffect()); } @@ -70,63 +70,58 @@ public class DemonicConsultation extends CardImpl { } class DemonicConsultationEffect extends OneShotEffect { - + DemonicConsultationEffect() { super(Outcome.Benefit); this.staticText = "Name a card. Exile the top six cards of your library, then reveal cards from the top of your library until you reveal the named card. Put that card into your hand and exile all other cards revealed this way"; } - + DemonicConsultationEffect(final DemonicConsultationEffect effect) { super(effect); } - + @Override public DemonicConsultationEffect copy() { return new DemonicConsultationEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { // Name a card. Choice choice = new ChoiceImpl(); choice.setChoices(CardRepository.instance.getNames()); - while (!player.choose(Outcome.Benefit, choice, game)) { - if (!player.canRespond()) { + while (!controller.choose(Outcome.Benefit, choice, game)) { + if (!controller.canRespond()) { return false; } } String name = choice.getChoice(); game.informPlayers("Card named: " + name); - + // Exile the top six cards of your library, - int num = Math.min(6, player.getLibrary().size()); - for (int i = 0; i < num; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); - } - } - + controller.moveCards(controller.getLibrary().getTopCards(game, 6), null, Zone.EXILED, source, game); + // then reveal cards from the top of your library until you reveal the named card. - Cards cards = new CardsImpl(Zone.LIBRARY); - while (player.getLibrary().size() > 0) { - Card card = player.getLibrary().removeFromTop(game); + Cards cardsToReaveal = new CardsImpl(); + Card cardToHand = null; + while (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); if (card != null) { - cards.add(card); + cardsToReaveal.add(card); // Put that card into your hand if (card.getName().equals(name)) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + cardToHand = card; break; } - // and exile all other cards revealed this way. - else { - player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); - } } } - player.revealCards("Demonic Consultation", cards, game); + controller.moveCards(cardToHand, null, Zone.HAND, source, game); + controller.revealCards(sourceObject.getIdName(), cardsToReaveal, game); + cardsToReaveal.remove(cardToHand); + controller.moveCards(cardsToReaveal, null, Zone.EXILED, source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java b/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java index aed1c1e2af2..4dc4e3bd417 100644 --- a/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java +++ b/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java @@ -29,10 +29,6 @@ package mage.sets.innistrad; import java.util.UUID; import mage.MageObject; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.condition.common.MorbidCondition; import mage.abilities.effects.OneShotEffect; @@ -40,6 +36,10 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterBasicLandCard; import mage.game.Game; import mage.players.Player; @@ -55,7 +55,6 @@ public class CaravanVigil extends CardImpl { super(ownerId, 173, "Caravan Vigil", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{G}"); this.expansionSetCode = "ISD"; - // Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. // Morbid - You may put that card onto the battlefield instead of putting it into your hand if a creature died this turn. this.getSpellAbility().addEffect(new CaravanVigilEffect()); @@ -103,10 +102,10 @@ class CaravanVigilEffect extends OneShotEffect { && controller.chooseUse(Outcome.PutLandInPlay, "Do you wish to put the card onto the battlefield instead?", source, game)) { controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); } else { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); } - controller.revealCards(sourceObject.getName(), cards, game); - } + controller.revealCards(sourceObject.getIdName(), cards, game); + } } controller.shuffleLibrary(game); return true; diff --git a/Mage.Sets/src/mage/sets/invasion/Recoil.java b/Mage.Sets/src/mage/sets/invasion/Recoil.java index f062d0bb68b..8b220966d18 100644 --- a/Mage.Sets/src/mage/sets/invasion/Recoil.java +++ b/Mage.Sets/src/mage/sets/invasion/Recoil.java @@ -50,11 +50,10 @@ public class Recoil extends CardImpl { super(ownerId, 264, "Recoil", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}{B}"); this.expansionSetCode = "INV"; - // Return target permanent to its owner's hand. Then that player discards a card. this.getSpellAbility().addEffect(new RecoilEffect()); - this.getSpellAbility().addTarget(new TargetPermanent()); - + this.getSpellAbility().addTarget(new TargetPermanent()); + } public Recoil(final Recoil card) { @@ -86,13 +85,11 @@ class RecoilEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent target = game.getPermanent(source.getFirstTarget()); - if (target != null) { - Player controller = game.getPlayer(target.getControllerId()); - if (controller != null) { - controller.moveCardToHandWithInfo(target, source.getSourceId(), game, Zone.BATTLEFIELD); - controller.discard(1, source, game); - return true; - } + Player controller = game.getPlayer(target.getControllerId()); + if (target != null && controller != null) { + controller.moveCards(target, null, Zone.HAND, source, game); + controller.discard(1, false, source, game); + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java b/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java index b5024166052..46f26f68d52 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java @@ -64,12 +64,12 @@ import mage.target.common.TargetOpponent; public class AthreosGodOfPassage extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature you own"); - + static { filter.add(new AnotherPredicate()); filter.add(new OwnerPredicate(TargetController.YOU)); } - + public AthreosGodOfPassage(UUID ownerId) { super(ownerId, 146, "Athreos, God of Passage", Rarity.MYTHIC, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{W}{B}"); this.expansionSetCode = "JOU"; @@ -84,12 +84,12 @@ public class AthreosGodOfPassage extends CardImpl { // As long as your devotion to white and black is less than seven, Athreos isn't a creature. Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.W, ColoredManaSymbol.B), 7); effect.setText("As long as your devotion to white and black is less than seven, Athreos isn't a creature"); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); // Whenever another creature you own dies, return it to your hand unless target opponent pays 3 life. Ability ability = new AthreosDiesCreatureTriggeredAbility(new AthreosGodOfPassageReturnEffect(), false, filter); ability.addTarget(new TargetOpponent()); this.addAbility(ability); - + } public AthreosGodOfPassage(final AthreosGodOfPassage card) { @@ -103,21 +103,21 @@ public class AthreosGodOfPassage extends CardImpl { } class AthreosGodOfPassageReturnEffect extends OneShotEffect { - + public AthreosGodOfPassageReturnEffect() { super(Outcome.Benefit); this.staticText = "return it to your hand unless target opponent pays 3 life"; } - + public AthreosGodOfPassageReturnEffect(final AthreosGodOfPassageReturnEffect effect) { super(effect); } - + @Override public AthreosGodOfPassageReturnEffect copy() { return new AthreosGodOfPassageReturnEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -134,13 +134,13 @@ class AthreosGodOfPassageReturnEffect extends OneShotEffect { if (cost.pay(source, game, source.getSourceId(), opponent.getId(), false)) { paid = true; } - } + } } if (opponent == null || !paid) { if (game.getState().getZone(creature.getId()).equals(Zone.GRAVEYARD)) { - controller.moveCardToHandWithInfo(creature, source.getSourceId(), game, Zone.GRAVEYARD); + controller.moveCards(creature, null, Zone.HAND, source, game); } - } + } } return true; } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/BrainMaggot.java b/Mage.Sets/src/mage/sets/journeyintonyx/BrainMaggot.java index e2ce4ed1bcb..3f758c3321a 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/BrainMaggot.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/BrainMaggot.java @@ -27,7 +27,6 @@ */ package mage.sets.journeyintonyx; -import java.util.LinkedList; import java.util.UUID; import mage.MageInt; import mage.MageObject; @@ -74,7 +73,7 @@ public class BrainMaggot extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility(new BrainMaggotExileEffect()); ability.addTarget(new TargetOpponent()); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new BrainMaggotReturnExiledCardAbility())); - this.addAbility(ability); + this.addAbility(ability); } public BrainMaggot(final BrainMaggot card) { @@ -110,7 +109,7 @@ class BrainMaggotExileEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && opponent != null && sourcePermanent != null) { if (!opponent.getHand().isEmpty()) { - opponent.revealCards(sourcePermanent.getName(), opponent.getHand(), game); + opponent.revealCards(sourcePermanent.getIdName(), opponent.getHand(), game); FilterCard filter = new FilterNonlandCard("nonland card to exile"); TargetCard target = new TargetCard(Zone.HAND, filter); @@ -130,11 +129,10 @@ class BrainMaggotExileEffect extends OneShotEffect { } /** - * Returns the exiled card as source permanent leaves battlefield - * Uses no stack + * Returns the exiled card as source permanent leaves battlefield Uses no stack + * * @author LevelX2 */ - class BrainMaggotReturnExiledCardAbility extends DelayedTriggeredAbility { public BrainMaggotReturnExiledCardAbility() { @@ -190,18 +188,13 @@ class BrainMaggotReturnExiledCardEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (sourceObject != null && controller != null) { - int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() -1; + int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1; ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter)); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (exile != null && sourcePermanent != null) { - LinkedList cards = new LinkedList<>(exile); - for (UUID cardId : cards) { - Card card = game.getCard(cardId); - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED); - } - exile.clear(); + controller.moveCards(exile, null, Zone.HAND, source, game); return true; - } + } } return false; } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/Hubris.java b/Mage.Sets/src/mage/sets/journeyintonyx/Hubris.java index c9ac8245496..0193cf32751 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/Hubris.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/Hubris.java @@ -31,6 +31,8 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -52,12 +54,10 @@ public class Hubris extends CardImpl { super(ownerId, 41, "Hubris", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); this.expansionSetCode = "JOU"; - // Return target creature and all Auras attached to it to their owners' hand. this.getSpellAbility().addEffect(new HubrisReturnEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - } public Hubris(final Hubris card) { @@ -96,16 +96,12 @@ class HubrisReturnEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID targetId: targetPointer.getTargets(game, source)) { + for (UUID targetId : targetPointer.getTargets(game, source)) { Permanent creature = game.getPermanent(targetId); if (creature != null) { - controller.moveCardToHandWithInfo(creature, source.getSourceId(), game, Zone.BATTLEFIELD); - for (UUID attachementId: creature.getAttachments()) { - Permanent attachment = game.getPermanent(attachementId); - if (attachment != null && filter.match(attachment, game)) { - controller.moveCardToHandWithInfo(attachment, source.getSourceId(), game, Zone.BATTLEFIELD); - } - } + Cards cardsToHand = new CardsImpl(creature.getAttachments()); + cardsToHand.add(creature); + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/NessianGameWarden.java b/Mage.Sets/src/mage/sets/journeyintonyx/NessianGameWarden.java index c0da2b6ed25..2926899d604 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/NessianGameWarden.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/NessianGameWarden.java @@ -101,36 +101,30 @@ class NessianGameWardenEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (player == null || sourcePermanent == null) { + if (controller == null || sourcePermanent == null) { return false; } Cards cards = new CardsImpl(); int count = new PermanentsOnBattlefieldCount(filter).calculate(game, source, this); - count = Math.min(player.getLibrary().size(), count); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - player.lookAtCards(sourcePermanent.getName(), cards, game); + cards.addAll(controller.getLibrary().getTopCards(game, count)); + controller.lookAtCards(sourcePermanent.getIdName(), cards, game); if (!cards.isEmpty()) { TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard("creature card to put into your hand")); - if (target.canChoose(source.getSourceId(), player.getId(), game) && player.choose(Outcome.DrawCard, cards, target, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) && controller.choose(Outcome.DrawCard, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { - player.revealCards(sourcePermanent.getName(), new CardsImpl(card), game); + controller.revealCards(sourcePermanent.getName(), new CardsImpl(card), game); cards.remove(card); - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); } } } - player.putCardsOnBottomOfLibrary(cards, game, source, true); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; } } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/ScourgeOfFleets.java b/Mage.Sets/src/mage/sets/journeyintonyx/ScourgeOfFleets.java index b6b3b9e6720..29a3a66637f 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/ScourgeOfFleets.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/ScourgeOfFleets.java @@ -33,6 +33,8 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -78,27 +80,27 @@ public class ScourgeOfFleets extends CardImpl { } class ScourgeOfFleetsEffect extends OneShotEffect { - + private static final FilterControlledPermanent filter = new FilterControlledPermanent("number of Islands you control"); - + static { filter.add(new SubtypePredicate("Island")); } - + public ScourgeOfFleetsEffect() { super(Outcome.Benefit); this.staticText = "return each creature your opponents control with toughness X or less, where X is the number of Islands you control"; } - + public ScourgeOfFleetsEffect(final ScourgeOfFleetsEffect effect) { super(effect); } - + @Override public ScourgeOfFleetsEffect copy() { return new ScourgeOfFleetsEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -106,10 +108,12 @@ class ScourgeOfFleetsEffect extends OneShotEffect { int islands = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game); FilterPermanent creatureFilter = new FilterCreaturePermanent(); creatureFilter.add(new ControllerPredicate(TargetController.OPPONENT)); - creatureFilter.add(new ToughnessPredicate(Filter.ComparisonType.LessThan, islands +1)); - for (Permanent permanent: game.getBattlefield().getActivePermanents(creatureFilter, source.getControllerId(), source.getSourceId(), game)) { - controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + creatureFilter.add(new ToughnessPredicate(Filter.ComparisonType.LessThan, islands + 1)); + Cards cardsToHand = new CardsImpl(); + for (Permanent permanent : game.getBattlefield().getActivePermanents(creatureFilter, source.getControllerId(), source.getSourceId(), game)) { + cardsToHand.add(permanent); } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/magic2011/Cultivate.java b/Mage.Sets/src/mage/sets/magic2011/Cultivate.java index b4fe191ce45..b68d4a6bdeb 100644 --- a/Mage.Sets/src/mage/sets/magic2011/Cultivate.java +++ b/Mage.Sets/src/mage/sets/magic2011/Cultivate.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,16 +20,15 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2011; -import java.util.List; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -93,41 +92,44 @@ class CultivateEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterBasicLandCard()); - Player player = game.getPlayer(source.getControllerId()); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { Cards revealed = new CardsImpl(); - for (UUID cardId: (List)target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); + for (UUID cardId : target.getTargets()) { + Card card = controller.getLibrary().getCard(cardId, game); revealed.add(card); } - player.revealCards("Cultivate", revealed, game); + controller.revealCards(sourceObject.getIdName(), revealed, game); if (target.getTargets().size() == 2) { TargetCard target2 = new TargetCard(Zone.LIBRARY, filter); - player.choose(Outcome.Benefit, revealed, target2, game); + controller.choose(Outcome.Benefit, revealed, target2, game); Card card = revealed.get(target2.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); revealed.remove(card); } card = revealed.getCards(game).iterator().next(); if (card != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); } - } - else if (target.getTargets().size() == 1) { + } else if (target.getTargets().size() == 1) { Card card = revealed.getCards(game).iterator().next(); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); } } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } diff --git a/Mage.Sets/src/mage/sets/magic2015/Quickling.java b/Mage.Sets/src/mage/sets/magic2015/Quickling.java index 21d407e9e75..569c612cf4b 100644 --- a/Mage.Sets/src/mage/sets/magic2015/Quickling.java +++ b/Mage.Sets/src/mage/sets/magic2015/Quickling.java @@ -79,6 +79,7 @@ public class Quickling extends CardImpl { return new Quickling(this); } } + class QuicklingEffect extends OneShotEffect { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another creature you control"); @@ -88,12 +89,12 @@ class QuicklingEffect extends OneShotEffect { filter.add(new AnotherPredicate()); } - QuicklingEffect ( ) { + QuicklingEffect() { super(Outcome.ReturnToHand); staticText = effectText; } - QuicklingEffect ( QuicklingEffect effect ) { + QuicklingEffect(QuicklingEffect effect) { super(effect); } @@ -106,13 +107,13 @@ class QuicklingEffect extends OneShotEffect { if (target.canChoose(controller.getId(), game) && controller.chooseUse(outcome, "Return another creature you control to its owner's hand?", source, game)) { controller.chooseTarget(Outcome.ReturnToHand, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); - if ( permanent != null ) { + if (permanent != null) { targetChosen = true; - controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + controller.moveCards(permanent, null, Zone.HAND, source, game); } } - if ( !targetChosen ) { + if (!targetChosen) { new SacrificeSourceEffect().apply(game, source); } return true; diff --git a/Mage.Sets/src/mage/sets/mirage/ForbiddenCrypt.java b/Mage.Sets/src/mage/sets/mirage/ForbiddenCrypt.java index e886dc432b5..ef346c00eac 100644 --- a/Mage.Sets/src/mage/sets/mirage/ForbiddenCrypt.java +++ b/Mage.Sets/src/mage/sets/mirage/ForbiddenCrypt.java @@ -57,7 +57,6 @@ public class ForbiddenCrypt extends CardImpl { super(ownerId, 22, "Forbidden Crypt", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); this.expansionSetCode = "MIR"; - // If you would draw a card, return a card from your graveyard to your hand instead. If you can't, you lose the game. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ForbiddenCryptDrawCardReplacementEffect())); // If a card would be put into your graveyard from anywhere, exile that card instead. @@ -80,7 +79,7 @@ class ForbiddenCryptDrawCardReplacementEffect extends ReplacementEffectImpl { super(Duration.WhileOnBattlefield, Outcome.Neutral); this.staticText = "If you would draw a card, return a card from your graveyard to your hand instead. If you can't, you lose the game"; } - + public ForbiddenCryptDrawCardReplacementEffect(final ForbiddenCryptDrawCardReplacementEffect effect) { super(effect); } @@ -92,22 +91,23 @@ class ForbiddenCryptDrawCardReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { boolean cardReturned = false; TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(); - if (target.canChoose(source.getSourceId(), player.getId(), game)) { - if (target.choose(Outcome.ReturnToHand, player.getId(), source.getSourceId(), game)) { + target.setNotTarget(true); + if (target.canChoose(source.getSourceId(), controller.getId(), game)) { + if (target.choose(Outcome.ReturnToHand, controller.getId(), source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + controller.moveCards(card, null, Zone.HAND, source, game); cardReturned = true; } } } if (!cardReturned) { - game.informPlayers(new StringBuilder(player.getLogName()).append(" can't return a card from graveyard to hand.").toString()); - player.lost(game); + game.informPlayers(controller.getLogName() + " can't return a card from graveyard to hand."); + controller.lost(game); } return true; } @@ -118,12 +118,12 @@ class ForbiddenCryptDrawCardReplacementEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.DRAW_CARD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { return event.getPlayerId().equals(source.getControllerId()); } - + } class ForbiddenCryptPutIntoYourGraveyardReplacementEffect extends ReplacementEffectImpl { @@ -132,7 +132,7 @@ class ForbiddenCryptPutIntoYourGraveyardReplacementEffect extends ReplacementEff super(Duration.WhileOnBattlefield, Outcome.Detriment); this.staticText = "If a card would be put into your graveyard from anywhere, exile that card instead"; } - + public ForbiddenCryptPutIntoYourGraveyardReplacementEffect(final ForbiddenCryptPutIntoYourGraveyardReplacementEffect effect) { super(effect); } @@ -141,7 +141,7 @@ class ForbiddenCryptPutIntoYourGraveyardReplacementEffect extends ReplacementEff public ForbiddenCryptPutIntoYourGraveyardReplacementEffect copy() { return new ForbiddenCryptPutIntoYourGraveyardReplacementEffect(this); } - + @Override public boolean apply(Game game, Ability source) { return true; @@ -166,12 +166,12 @@ class ForbiddenCryptPutIntoYourGraveyardReplacementEffect extends ReplacementEff } return true; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ZONE_CHANGE; - } - + } + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { @@ -185,5 +185,5 @@ class ForbiddenCryptPutIntoYourGraveyardReplacementEffect extends ReplacementEff } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/mirrodin/SpoilsOfTheVault.java b/Mage.Sets/src/mage/sets/mirrodin/SpoilsOfTheVault.java index f2017a43afa..d2eeb3bd174 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/SpoilsOfTheVault.java +++ b/Mage.Sets/src/mage/sets/mirrodin/SpoilsOfTheVault.java @@ -53,7 +53,6 @@ public class SpoilsOfTheVault extends CardImpl { super(ownerId, 78, "Spoils of the Vault", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{B}"); this.expansionSetCode = "MRD"; - // Name a card. Reveal cards from the top of your library until you reveal the named card, then put that card into your hand. Exile all other cards revealed this way, and you lose 1 life for each of the exiled cards. this.getSpellAbility().addEffect(new NameACardEffect(NameACardEffect.TypeOfName.ALL)); this.getSpellAbility().addEffect(new SpoilsOfTheVaultEffect()); @@ -69,7 +68,6 @@ public class SpoilsOfTheVault extends CardImpl { } } - class SpoilsOfTheVaultEffect extends OneShotEffect { public SpoilsOfTheVaultEffect() { @@ -94,28 +92,25 @@ class SpoilsOfTheVaultEffect extends OneShotEffect { if (sourceObject == null || controller == null || cardName == null || cardName.isEmpty()) { return false; } - - Cards cards = new CardsImpl(); + + Cards cardsToReveal = new CardsImpl(); + Cards cardsToExile = new CardsImpl(); while (controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); if (card != null) { - cards.add(card); - if(card.getName().equals(cardName)){ - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + cardsToReveal.add(card); + if (card.getName().equals(cardName)) { + controller.moveCards(card, null, Zone.HAND, source, game); break; + } else { + cardsToExile.add(card); } - else{ - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); - } - } - else{ - break; } } - - controller.revealCards(sourceObject.getName(), cards, game); - controller.loseLife(cards.size(), game); - + controller.revealCards(sourceObject.getIdName(), cardsToReveal, game); + controller.moveCards(cardsToExile, null, Zone.EXILED, source, game); + controller.loseLife(cardsToExile.size(), game); + return true; } } diff --git a/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java b/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java index 8a75832ee6b..6c15cb1f329 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java +++ b/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java @@ -28,6 +28,7 @@ package mage.sets.modernmasters; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -52,7 +53,6 @@ public class PetalsOfInsight extends CardImpl { this.expansionSetCode = "MMA"; this.subtype.add("Arcane"); - // Look at the top three cards of your library. You may put those cards on the bottom of your library in any order. If you do, return Petals of Insight to its owner's hand. Otherwise, draw three cards. this.getSpellAbility().addEffect(new PetalsOfInsightEffect()); } @@ -85,33 +85,23 @@ class PetalsOfInsightEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { return false; } Cards cards = new CardsImpl(); - int count = Math.min(player.getLibrary().size(), 3); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - player.lookAtCards("Petals of Insight", cards, game); - if (player.chooseUse(outcome, "Put the cards on the bottom of your library in any order?", source, game)) { - player.putCardsOnBottomOfLibrary(cards, game, source, true); + cards.addAll(controller.getLibrary().getTopCards(game, 3)); + + controller.lookAtCards(sourceObject.getIdName(), cards, game); + if (controller.chooseUse(outcome, "Put the cards on the bottom of your library in any order?", source, game)) { + controller.putCardsOnBottomOfLibrary(cards, game, source, true); Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); if (spellCard != null) { - player.moveCardToHandWithInfo(spellCard, source.getSourceId(), game, Zone.STACK); + controller.moveCards(spellCard, null, Zone.HAND, source, game); } } else { - for (UUID cardId: cards) { - Card card = game.getCard(cardId); - if (card != null) { - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - } - player.drawCards(3, game); + controller.drawCards(3, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/modernmasters2015/AllSunsDawn.java b/Mage.Sets/src/mage/sets/modernmasters2015/AllSunsDawn.java index 7c68912d601..0b01857a2ed 100644 --- a/Mage.Sets/src/mage/sets/modernmasters2015/AllSunsDawn.java +++ b/Mage.Sets/src/mage/sets/modernmasters2015/AllSunsDawn.java @@ -34,6 +34,8 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSpellEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -56,7 +58,7 @@ public class AllSunsDawn extends CardImpl { private final static FilterCard filterBlue = new FilterCard("blue card from your graveyard"); private final static FilterCard filterBlack = new FilterCard("black card from your graveyard"); private final static FilterCard filterWhite = new FilterCard("white card from your graveyard"); - + static { filterGreen.add(new ColorPredicate(ObjectColor.GREEN)); filterRed.add(new ColorPredicate(ObjectColor.RED)); @@ -64,18 +66,18 @@ public class AllSunsDawn extends CardImpl { filterBlack.add(new ColorPredicate(ObjectColor.BLACK)); filterWhite.add(new ColorPredicate(ObjectColor.WHITE)); } - + public AllSunsDawn(UUID ownerId) { super(ownerId, 138, "All Suns' Dawn", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{G}"); this.expansionSetCode = "MM2"; - // For each color, return up to one target card of that color from your graveyard to your hand. + // For each color, return up to one target card of that color from your graveyard to your hand. this.getSpellAbility().addEffect(new AllSunsDawnEffect()); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0,1,filterGreen)); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0,1,filterRed)); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0,1,filterBlue)); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0,1,filterBlack)); - this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0,1,filterWhite)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 1, filterGreen)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 1, filterRed)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 1, filterBlue)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 1, filterBlack)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 1, filterWhite)); // Exile All Suns' Dawn. this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); } @@ -91,32 +93,34 @@ public class AllSunsDawn extends CardImpl { } class AllSunsDawnEffect extends OneShotEffect { - + public AllSunsDawnEffect() { super(Outcome.ReturnToHand); this.staticText = "For each color, return up to one target card of that color from your graveyard to your hand. Exile {this}"; } - + public AllSunsDawnEffect(final AllSunsDawnEffect effect) { super(effect); } - + @Override public AllSunsDawnEffect copy() { return new AllSunsDawnEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for(Target target: source.getTargets()) { + Cards cardsToHand = new CardsImpl(); + for (Target target : source.getTargets()) { UUID targetId = target.getFirstTarget(); Card card = game.getCard(targetId); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD, true); + cardsToHand.add(card); } } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java b/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java index b03ec15c5ae..dd376b43af1 100644 --- a/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java +++ b/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java @@ -28,14 +28,13 @@ package mage.sets.onslaught; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; -import mage.constants.Outcome; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; @@ -55,7 +54,6 @@ public class ChainOfVapor extends CardImpl { super(ownerId, 73, "Chain of Vapor", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{U}"); this.expansionSetCode = "ONS"; - // Return target nonland permanent to its owner's hand. Then that permanent's controller may sacrifice a land. If the player does, he or she may copy this spell and may choose a new target for that copy. this.getSpellAbility().addEffect(new ChainOfVaporEffect()); this.getSpellAbility().addTarget(new TargetNonlandPermanent()); @@ -94,16 +92,14 @@ class ChainOfVaporEffect extends OneShotEffect { } Permanent permanent = game.getPermanent(source.getFirstTarget()); if (permanent != null) { - if (!controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD)){ - return false; - } + controller.moveCards(permanent, null, Zone.HAND, source, game); Player player = game.getPlayer(permanent.getControllerId()); - if (player.chooseUse(Outcome.ReturnToHand, "Sacrifice a land to copy this spell?", source, game)){ + if (player.chooseUse(Outcome.ReturnToHand, "Sacrifice a land to copy this spell?", source, game)) { TargetControlledPermanent target = new TargetControlledPermanent(new FilterControlledLandPermanent()); - if (player.chooseTarget(Outcome.Sacrifice, target, source, game)){ + if (player.chooseTarget(Outcome.Sacrifice, target, source, game)) { Permanent land = game.getPermanent(target.getFirstTarget()); - if(land != null){ - if(land.sacrifice(source.getSourceId(), game)){ + if (land != null) { + if (land.sacrifice(source.getSourceId(), game)) { Spell spell = game.getStack().getSpell(source.getSourceId()); if (spell != null) { Spell copy = spell.copySpell(); @@ -123,9 +119,10 @@ class ChainOfVaporEffect extends OneShotEffect { } } } + return true; } - - return true; + + return false; } @Override diff --git a/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java b/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java index 1be7a060ebc..788ec1f3ab5 100644 --- a/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java +++ b/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java @@ -30,9 +30,9 @@ package mage.sets.onslaught; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; @@ -55,7 +55,6 @@ public class WeirdHarvest extends CardImpl { super(ownerId, 299, "Weird Harvest", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{G}{G}"); this.expansionSetCode = "ONS"; - // Each player may search his or her library for up to X creature cards, reveal those cards, and put them into his or her hand. Then each player who searched his or her library this way shuffles it. getSpellAbility().addEffect(new WeirdHarvestEffect()); } @@ -89,20 +88,21 @@ class WeirdHarvestEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { int xValue = source.getManaCostsToPay().getX(); if (xValue > 0) { List usingPlayers = new ArrayList<>(); - this.chooseAndSearchLibrary(usingPlayers, controller, xValue, source, game); - for (UUID playerId: controller.getInRange()) { + this.chooseAndSearchLibrary(usingPlayers, controller, xValue, source, sourceObject, game); + for (UUID playerId : controller.getInRange()) { if (!playerId.equals(controller.getId())) { Player player = game.getPlayer(playerId); if (player != null) { - this.chooseAndSearchLibrary(usingPlayers, player, xValue, source, game); + this.chooseAndSearchLibrary(usingPlayers, player, xValue, source, sourceObject, game); } } } - for (Player player: usingPlayers) { + for (Player player : usingPlayers) { player.shuffleLibrary(game); } return true; @@ -111,21 +111,15 @@ class WeirdHarvestEffect extends OneShotEffect { return false; } - private void chooseAndSearchLibrary(List usingPlayers, Player player, int xValue, Ability source, Game game) { + private void chooseAndSearchLibrary(List usingPlayers, Player player, int xValue, Ability source, MageObject sourceObject, Game game) { if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up " + xValue + " creature cards and put them into your hand?", source, game)) { usingPlayers.add(player); TargetCardInLibrary target = new TargetCardInLibrary(0, xValue, new FilterCreatureCard()); if (player.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - Cards cards = new CardsImpl(); - for (UUID cardId: (List)target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - cards.add(card); - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - } - } - player.revealCards("Weird Harvest", cards, game); + Cards cards = new CardsImpl(target.getTargets()); + player.moveCards(cards, null, Zone.HAND, source, game); + player.revealCards(sourceObject.getIdName() + " (" + player.getName() + ")", cards, game); } } } diff --git a/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java b/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java index 4342192abcb..22a1c755e1b 100644 --- a/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java +++ b/Mage.Sets/src/mage/sets/planeshift/SkyshipWeatherlight.java @@ -34,61 +34,60 @@ import mage.util.CardUtil; * @author nick.myers */ public class SkyshipWeatherlight extends CardImpl { - + public SkyshipWeatherlight(UUID ownerId) { super(ownerId, 133, "Skyship Weatherlight", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}"); this.expansionSetCode = "PLS"; this.supertype.add("Legendary"); - + // When Skyship Weatherlight enters the battlefield, search your library for any number of artifact and/or creature cards and exile them. Then shuffle your library. this.addAbility(new EntersBattlefieldTriggeredAbility(new SkyshipWeatherlightEffect(), false)); - + // {4}, {tap}, Choose a card at random that was removed from the game with Skyship Weatherlight. Put that card into your hand. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SkyshipWeatherlightEffect2(), new GenericManaCost(4)); ability.addCost(new TapSourceCost()); this.addAbility(ability); } - + public SkyshipWeatherlight(final SkyshipWeatherlight card) { super(card); } - + @Override public SkyshipWeatherlight copy() { return new SkyshipWeatherlight(this); } - + } class SkyshipWeatherlightEffect extends SearchEffect { - + private static final FilterCard filter = new FilterCard("artifact and/or creature card"); - - + static { filter.add(Predicates.or( - new CardTypePredicate(CardType.ARTIFACT), - new CardTypePredicate(CardType.CREATURE))); + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE))); } - + public SkyshipWeatherlightEffect() { - + super(new TargetCardInLibrary(0, Integer.MAX_VALUE, filter), Outcome.Neutral); this.staticText = "search your library for any number of artifact and/or creature cards and remove them from the game. Then shuffle your library"; - + } - + public SkyshipWeatherlightEffect(final SkyshipWeatherlightEffect effect) { super(effect); } - + @Override public SkyshipWeatherlightEffect copy() { return new SkyshipWeatherlightEffect(this); } - + @Override - public boolean apply (Game game, Ability source) { + public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (sourceObject != null && controller != null) { @@ -108,25 +107,25 @@ class SkyshipWeatherlightEffect extends SearchEffect { } return false; } - + } class SkyshipWeatherlightEffect2 extends OneShotEffect { - + public SkyshipWeatherlightEffect2() { super(Outcome.ReturnToHand); this.staticText = "Choose a card at random that was removed from the game with {this}. Put that card into your hand"; } - + public SkyshipWeatherlightEffect2(final SkyshipWeatherlightEffect2 effect) { super(effect); } - + @Override public SkyshipWeatherlightEffect2 copy() { return new SkyshipWeatherlightEffect2(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -134,12 +133,11 @@ class SkyshipWeatherlightEffect2 extends OneShotEffect { if (sourceObject != null && controller != null) { ExileZone exZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())); if (exZone != null) { - Card card = exZone.getRandom(game); - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED); + controller.moveCards(exZone.getRandom(game), null, Zone.HAND, source, game); } return true; } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/ravnica/CloudstoneCurio.java b/Mage.Sets/src/mage/sets/ravnica/CloudstoneCurio.java index db7a7afef5e..661f4f5883b 100644 --- a/Mage.Sets/src/mage/sets/ravnica/CloudstoneCurio.java +++ b/Mage.Sets/src/mage/sets/ravnica/CloudstoneCurio.java @@ -57,6 +57,7 @@ import mage.target.TargetPermanent; public class CloudstoneCurio extends CardImpl { private static final FilterPermanent filter = new FilterPermanent("a nonartifact permanent"); + static { filter.add(Predicates.not(new CardTypePredicate(CardType.ARTIFACT))); filter.add(new ControllerPredicate(TargetController.YOU)); @@ -69,7 +70,6 @@ public class CloudstoneCurio extends CardImpl { // Whenever a nonartifact permanent enters the battlefield under your control, you may return another permanent you control that shares a card type with it to its owner's hand. this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new CloudstoneCurioEffect(), filter, true, SetTargetPointer.PERMANENT, "", true)); - } public CloudstoneCurio(final CloudstoneCurio card) { @@ -120,7 +120,7 @@ class CloudstoneCurioEffect extends OneShotEffect { if (target.canChoose(controller.getId(), game) && controller.chooseTarget(outcome, target, source, game)) { Permanent returningCreature = game.getPermanent(target.getFirstTarget()); if (returningCreature != null) { - controller.moveCardToHandWithInfo(returningCreature, source.getSourceId(), game, Zone.BATTLEFIELD); + controller.moveCards(returningCreature, null, Zone.HAND, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/ravnica/DarkConfidant.java b/Mage.Sets/src/mage/sets/ravnica/DarkConfidant.java index 830ed264fa4..d5c22e87007 100644 --- a/Mage.Sets/src/mage/sets/ravnica/DarkConfidant.java +++ b/Mage.Sets/src/mage/sets/ravnica/DarkConfidant.java @@ -28,10 +28,6 @@ package mage.sets.ravnica; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -40,8 +36,11 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.TargetController; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -76,6 +75,7 @@ public class DarkConfidant extends CardImpl { } class DarkConfidantEffect extends OneShotEffect { + DarkConfidantEffect() { super(Outcome.DrawCard); this.staticText = "reveal the top card of your library and put that card into your hand. You lose life equal to its converted mana cost"; @@ -87,17 +87,16 @@ class DarkConfidantEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (player != null && sourcePermanent != null) { - if (player.getLibrary().size() > 0) { - Card card = player.getLibrary().removeFromTop(game); + if (controller != null && sourcePermanent != null) { + if (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); if (card != null) { - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards(sourcePermanent.getName(), cards, game); - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - player.loseLife(card.getManaCost().convertedManaCost(), game); + Cards cards = new CardsImpl(card); + controller.revealCards(sourcePermanent.getIdName(), cards, game); + controller.moveCards(card, null, Zone.HAND, source, game); + controller.loseLife(card.getManaCost().convertedManaCost(), game); } return true; diff --git a/Mage.Sets/src/mage/sets/returntoravnica/FaerieImpostor.java b/Mage.Sets/src/mage/sets/returntoravnica/FaerieImpostor.java index 4d786071745..a4f918823d2 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/FaerieImpostor.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/FaerieImpostor.java @@ -28,9 +28,6 @@ package mage.sets.returntoravnica; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -38,7 +35,9 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; @@ -88,12 +87,12 @@ class FaerieImpostorEffect extends OneShotEffect { filter.add(new AnotherPredicate()); } - FaerieImpostorEffect ( ) { + FaerieImpostorEffect() { super(Outcome.ReturnToHand); staticText = effectText; } - FaerieImpostorEffect ( FaerieImpostorEffect effect ) { + FaerieImpostorEffect(FaerieImpostorEffect effect) { super(effect); } @@ -108,13 +107,13 @@ class FaerieImpostorEffect extends OneShotEffect { controller.choose(Outcome.ReturnToHand, target, source.getSourceId(), game); Permanent permanent = game.getPermanent(target.getFirstTarget()); - if ( permanent != null ) { + if (permanent != null) { targetChosen = true; - controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + controller.moveCards(permanent, null, Zone.HAND, source, game); } } - if ( !targetChosen ) { + if (!targetChosen) { new SacrificeSourceEffect().apply(game, source); } return true; diff --git a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java index 3be54f89388..93753306a08 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java @@ -258,7 +258,7 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect { for (UUID cardUuid : cardsToHand) { Card card = cardsToHand.get(cardUuid, game); if (card != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + player.moveCards(card, null, Zone.HAND, source, game); } } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/ElderPineOfJukai.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/ElderPineOfJukai.java index ac6b74af586..860c187ec2f 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/ElderPineOfJukai.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/ElderPineOfJukai.java @@ -99,13 +99,13 @@ class ElderPineOfJukaiEffect extends OneShotEffect { MageObject sourceObject = game.getObject(source.getSourceId()); if (controller == null || sourceObject == null) { return false; - } + } Cards cards = new CardsImpl(); cards.addAll(controller.getLibrary().getTopCards(game, 3)); controller.revealCards(sourceObject.getName(), cards, game); - for (Card card: cards.getCards(game)) { + for (Card card : cards.getCards(game)) { if (card.getCardType().contains(CardType.LAND)) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); cards.remove(card); } } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/CerebralEruption.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/CerebralEruption.java index 318cd6d1486..404279a7b39 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/CerebralEruption.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/CerebralEruption.java @@ -1,16 +1,16 @@ /* * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. @@ -28,6 +28,7 @@ package mage.sets.scarsofmirrodin; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -55,7 +56,6 @@ public class CerebralEruption extends CardImpl { super(ownerId, 86, "Cerebral Eruption", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{R}{R}"); this.expansionSetCode = "SOM"; - // Target opponent reveals the top card of his or her library. Cerebral Eruption deals damage equal to the revealed card's converted mana cost to that player and each creature he or she controls. If a land card is revealed this way, return Cerebral Eruption to its owner's hand. this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addEffect(new CerebralEruptionEffect()); @@ -87,21 +87,21 @@ class CerebralEruptionEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getFirstTarget()); - if (player != null && player.getLibrary().size() > 0) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (player != null && sourceObject != null && player.getLibrary().size() > 0) { Card card = player.getLibrary().getFromTop(game); - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Cerebral Eruption", cards, game); + Cards cards = new CardsImpl(card); + player.revealCards(sourceObject.getIdName(), cards, game); game.getState().setValue(source.getSourceId().toString(), card); int damage = card.getManaCost().convertedManaCost(); player.damage(damage, source.getSourceId(), game, false, true); - for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, player.getId(), game)) { + for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, player.getId(), game)) { perm.damage(damage, source.getSourceId(), game, false, true); } if (card.getCardType().contains(CardType.LAND)) { Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); if (spellCard != null) { - player.moveCardToHandWithInfo(spellCard, source.getSourceId(), game, Zone.STACK); + player.moveCards(spellCard, null, Zone.HAND, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/PsychicMiasma.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/PsychicMiasma.java index 389297a1198..99de7634a75 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/PsychicMiasma.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/PsychicMiasma.java @@ -1,16 +1,16 @@ /* * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. @@ -50,7 +50,6 @@ public class PsychicMiasma extends CardImpl { super(ownerId, 76, "Psychic Miasma", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{B}"); this.expansionSetCode = "SOM"; - // Target player discards a card. If a land card is discarded this way, return Psychic Miasma to its owner's hand. this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new PsychicMiasmaEffect()); @@ -86,9 +85,10 @@ class PsychicMiasmaEffect extends OneShotEffect { if (discardedCard != null && discardedCard.getCardType().contains(CardType.LAND)) { Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); if (spellCard != null) { - player.moveCardToHandWithInfo(spellCard, source.getSourceId(), game, Zone.STACK); + player.moveCards(spellCard, null, Zone.HAND, source, game); } } + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java b/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java index 402a2e440ab..99251d9485a 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java @@ -100,7 +100,7 @@ class AdviceFromTheFaeEffect extends OneShotEffect { for (Card card : cardsFromTopLibrary) { cards.add(card); } - controller.lookAtCards(mageObject.getName(), cards, game); + controller.lookAtCards(mageObject.getIdName(), cards, game); int max = 0; for (UUID playerId : controller.getInRange()) { FilterCreaturePermanent filter = new FilterCreaturePermanent(); @@ -111,20 +111,11 @@ class AdviceFromTheFaeEffect extends OneShotEffect { } } } - if (game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), controller.getId(), game) > max) { - TargetCard target = new TargetCard(2, Zone.LIBRARY, new FilterCard()); - if (controller.choose(Outcome.DrawCard, cards, target, game)) { - controller.moveCardToHandWithInfo(game.getCard(target.getFirstTarget()), source.getSourceId(), game, Zone.LIBRARY); - cards.remove(game.getCard(target.getFirstTarget())); - controller.moveCardToHandWithInfo(game.getCard(target.getTargets().get(1)), source.getSourceId(), game, Zone.LIBRARY); - cards.remove(game.getCard(target.getTargets().get(1))); - } - } else { - TargetCard target = new TargetCard(1, Zone.LIBRARY, new FilterCard()); - if (controller.choose(Outcome.DrawCard, cards, target, game)) { - controller.moveCardToHandWithInfo(game.getCard(target.getFirstTarget()), source.getSourceId(), game, Zone.LIBRARY); - cards.remove(game.getCard(target.getFirstTarget())); - } + boolean moreCreatures = game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), controller.getId(), game) > max; + TargetCard target = new TargetCard(moreCreatures ? 2 : 1, Zone.LIBRARY, new FilterCard()); + if (controller.choose(Outcome.DrawCard, cards, target, game)) { + cards.removeAll(target.getTargets()); + controller.moveCards(new CardsImpl(target.getTargets()), null, Zone.HAND, source, game); } controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; diff --git a/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java b/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java index 80ee8b645bf..23fd96ae723 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java @@ -50,7 +50,6 @@ public class AdNauseam extends CardImpl { super(ownerId, 63, "Ad Nauseam", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{B}{B}"); this.expansionSetCode = "ALA"; - // Reveal the top card of your library and put that card into your hand. You lose life equal to its converted mana cost. You may repeat this process any number of times. this.getSpellAbility().addEffect(new AdNauseamEffect()); } @@ -92,12 +91,12 @@ class AdNauseamEffect extends OneShotEffect { while (controller.chooseUse(outcome, message, source, game) && controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); int cmc = card.getManaCost().convertedManaCost(); if (cmc > 0) { controller.loseLife(cmc, game); } - controller.revealCards(new StringBuilder(sourceCard.getName()).append(" put into hand").toString(), new CardsImpl(card), game); + controller.revealCards(sourceCard.getIdName() + " put into hand", new CardsImpl(card), game); } } return true; diff --git a/Mage.Sets/src/mage/sets/shardsofalara/CruelUltimatum.java b/Mage.Sets/src/mage/sets/shardsofalara/CruelUltimatum.java index 0e4a703fca4..6e853e8797b 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/CruelUltimatum.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/CruelUltimatum.java @@ -58,7 +58,6 @@ public class CruelUltimatum extends CardImpl { super(ownerId, 164, "Cruel Ultimatum", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{U}{U}{B}{B}{B}{R}{R}"); this.expansionSetCode = "ALA"; - // Target opponent sacrifices a creature, discards three cards, then loses 5 life. // You return a creature card from your graveyard to your hand, draw three cards, then gain 5 life. this.getSpellAbility().addTarget(new TargetOpponent()); @@ -99,17 +98,17 @@ class CruelUltimatumEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard")); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game) && player.choose(Outcome.ReturnToHand, target, source.getSourceId(), game)) { + if (target.canChoose(source.getSourceId(), source.getControllerId(), game) && controller.choose(Outcome.ReturnToHand, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card == null) { return false; } - return player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + controller.moveCards(card, null, Zone.HAND, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java b/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java index f0a2e2f5bd3..e667e1d7cd6 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/TidehollowSculler.java @@ -69,9 +69,8 @@ public class TidehollowSculler extends CardImpl { ability.addTarget(new TargetOpponent()); this.addAbility(ability); - // When Tidehollow Sculler leaves the battlefield, return the exiled card to its owner's hand. - this.addAbility(new LeavesBattlefieldTriggeredAbility(new TidehollowScullerLeaveEffect(), false )); + this.addAbility(new LeavesBattlefieldTriggeredAbility(new TidehollowScullerLeaveEffect(), false)); } public TidehollowSculler(final TidehollowSculler card) { @@ -124,7 +123,6 @@ class TidehollowScullerExileEffect extends OneShotEffect { return false; } - } class TidehollowScullerLeaveEffect extends OneShotEffect { @@ -148,17 +146,13 @@ class TidehollowScullerLeaveEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null) { - int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() -1; + int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1; ExileZone exZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter)); if (exZone != null) { - for (Card card : exZone.getCards(game)) { - if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED); - } - } - } + controller.moveCards(exZone, null, Zone.HAND, source, game); + } return true; } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/tenthedition/Abundance.java b/Mage.Sets/src/mage/sets/tenthedition/Abundance.java index 767dceb20f1..09bc7c058bf 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/Abundance.java +++ b/Mage.Sets/src/mage/sets/tenthedition/Abundance.java @@ -28,6 +28,7 @@ package mage.sets.tenthedition; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; @@ -94,35 +95,35 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player player = game.getPlayer(event.getPlayerId()); - if (player != null) { + Player controller = game.getPlayer(event.getPlayerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { FilterCard filter = new FilterCard(); - if (player.chooseUse(Outcome.Benefit, "Choose land? (No = nonland)", source, game)) { + if (controller.chooseUse(Outcome.Benefit, "Choose land? (No = nonland)", source, game)) { filter.add(new CardTypePredicate(CardType.LAND)); - } - else { + } else { filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); } Cards cards = new CardsImpl(); - while (player.getLibrary().size() > 0) { - Card card = player.getLibrary().removeFromTop(game); + while (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); if (filter.match(card, source.getSourceId(), source.getControllerId(), game)) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.moveCards(card, null, Zone.HAND, source, game); break; } cards.add(card); } - player.revealCards("Abundance", cards, game); - player.putCardsOnBottomOfLibrary(cards, game, source, true); + controller.revealCards(sourceObject.getIdName(), cards, game); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); } return true; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.DRAW_CARD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getPlayerId().equals(source.getControllerId())) { @@ -133,4 +134,4 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/torment/MesmericFiend.java b/Mage.Sets/src/mage/sets/torment/MesmericFiend.java index e04a248377b..b1d4d738348 100644 --- a/Mage.Sets/src/mage/sets/torment/MesmericFiend.java +++ b/Mage.Sets/src/mage/sets/torment/MesmericFiend.java @@ -71,7 +71,7 @@ public class MesmericFiend extends CardImpl { this.addAbility(ability); // When Mesmeric Fiend leaves the battlefield, return the exiled card to its owner's hand. - this.addAbility(new LeavesBattlefieldTriggeredAbility(new MesmericFiendLeaveEffect(), false )); + this.addAbility(new LeavesBattlefieldTriggeredAbility(new MesmericFiendLeaveEffect(), false)); } public MesmericFiend(final MesmericFiend card) { @@ -83,6 +83,7 @@ public class MesmericFiend extends CardImpl { return new MesmericFiend(this); } } + class MesmericFiendExileEffect extends OneShotEffect { public MesmericFiendExileEffect() { @@ -120,7 +121,6 @@ class MesmericFiendExileEffect extends OneShotEffect { return false; } - } class MesmericFiendLeaveEffect extends OneShotEffect { @@ -143,18 +143,13 @@ class MesmericFiendLeaveEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); - if (controller != null && sourceObject !=null) { - int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() -1; + if (controller != null && sourceObject != null) { + int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1; ExileZone exZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter)); if (exZone != null) { - for (Card card : exZone.getCards(game)) { - if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED); - } - } - return true; + return controller.moveCards(exZone, null, Zone.HAND, source, game); } } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/urzassaga/IllGottenGains.java b/Mage.Sets/src/mage/sets/urzassaga/IllGottenGains.java index e4899307daa..f731566dde4 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/IllGottenGains.java +++ b/Mage.Sets/src/mage/sets/urzassaga/IllGottenGains.java @@ -32,8 +32,8 @@ import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSpellEffect; import mage.abilities.effects.common.discard.DiscardHandAllEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -54,13 +54,12 @@ public class IllGottenGains extends CardImpl { super(ownerId, 138, "Ill-Gotten Gains", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); this.expansionSetCode = "USG"; - // Exile Ill-Gotten Gains. this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); - + // Each player discards his or her hand, this.getSpellAbility().addEffect(new DiscardHandAllEffect()); - + //then returns up to three cards from his or her graveyard to his or her hand. this.getSpellAbility().addEffect(new IllGottenGainsEffect()); } @@ -76,34 +75,31 @@ public class IllGottenGains extends CardImpl { } class IllGottenGainsEffect extends OneShotEffect { - + IllGottenGainsEffect() { super(Outcome.ReturnToHand); this.staticText = ", then returns up to three cards from his or her graveyard to his or her hand."; } - + IllGottenGainsEffect(final IllGottenGainsEffect effect) { super(effect); } - + @Override public IllGottenGainsEffect copy() { return new IllGottenGainsEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId : controller.getInRange()){ + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { Target target = new TargetCardInYourGraveyard(0, 3, new FilterCard()); if (target.choose(Outcome.ReturnToHand, player.getId(), source.getSourceId(), game)) { - for (UUID targetId : target.getTargets()) { - Card card = game.getCard(targetId); - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); - } + controller.moveCards(new CardsImpl(target.getTargets()), null, Zone.HAND, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/urzassaga/NoRestForTheWicked.java b/Mage.Sets/src/mage/sets/urzassaga/NoRestForTheWicked.java index 4fc753a2123..8d3b3c4a02d 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/NoRestForTheWicked.java +++ b/Mage.Sets/src/mage/sets/urzassaga/NoRestForTheWicked.java @@ -35,6 +35,8 @@ import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -86,22 +88,20 @@ class NoRestForTheWickedEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { NoRestForTheWickedWatcher watcher = (NoRestForTheWickedWatcher) game.getState().getWatchers().get("NoRestForTheWickedWatcher"); - if (watcher != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (watcher != null && controller != null) { + Cards cardsToHand = new CardsImpl(); for (UUID cardId : watcher.cards) { Card c = game.getCard(cardId); if (c != null) { if (game.getState().getZone(cardId) == Zone.GRAVEYARD && c.getCardType().contains(CardType.CREATURE) && c.getOwnerId().equals(source.getControllerId())) { - //400.3 - Player p = game.getPlayer(source.getControllerId()); - if (p != null) { - p.moveCardToHandWithInfo(c, source.getSourceId(), game, Zone.GRAVEYARD); - } - return false; + cardsToHand.add(c); } } } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java b/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java index 8f07a34ec05..d21d96e185d 100644 --- a/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java +++ b/Mage.Sets/src/mage/sets/zendikar/GoblinGuide.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.zendikar; import java.util.UUID; @@ -108,10 +107,10 @@ class GoblinGuideTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.getSourceId()) ) { + if (event.getSourceId().equals(this.getSourceId())) { UUID defenderId = game.getCombat().getDefendingPlayerId(getSourceId(), game); if (defenderId != null) { - for (Effect effect :this.getEffects()) { + for (Effect effect : this.getEffects()) { // set here because attacking creature can be removed until effect resolves effect.setTargetPointer(new FixedTarget(defenderId)); } @@ -134,8 +133,8 @@ class GoblinGuideTriggeredAbility extends TriggeredAbilityImpl { return new GoblinGuideTriggeredAbility(this); } - } + class GoblinGuideEffect extends OneShotEffect { public GoblinGuideEffect() { @@ -153,7 +152,7 @@ class GoblinGuideEffect extends OneShotEffect { } @Override - public boolean apply(Game game, Ability source) { + public boolean apply(Game game, Ability source) { Player defender = game.getPlayer(getTargetPointer().getFirst(game, source)); MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null && defender != null) { @@ -163,7 +162,7 @@ class GoblinGuideEffect extends OneShotEffect { cards.add(card); defender.revealCards(sourceObject.getName(), cards, game); if (card.getCardType().contains(CardType.LAND)) { - defender.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + defender.moveCards(card, null, Zone.HAND, source, game); } } return true; @@ -171,4 +170,4 @@ class GoblinGuideEffect extends OneShotEffect { return false; } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/combat/damage/GravebladeMarauderTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/combat/damage/GravebladeMarauderTest.java new file mode 100644 index 00000000000..bab7f3ca404 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/combat/damage/GravebladeMarauderTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.triggers.combat.damage; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class GravebladeMarauderTest extends CardTestPlayerBase { + + @Test + public void testTwoAttackers() { + addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion", 3); + + // Whenever Graveblade Marauder deals combat damage to a player, that player loses life equal to the number of creature cards in your graveyard. + addCard(Zone.BATTLEFIELD, playerB, "Graveblade Marauder", 2);// 1/4 + + attack(2, playerB, "Graveblade Marauder"); + attack(2, playerB, "Graveblade Marauder"); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 12); // 1 + 3 + 1 + 3 = 8 + assertLife(playerB, 20); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 79a7367c1c0..eac8d92bc10 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1693,13 +1693,13 @@ public class TestPlayer implements Player { } @Override - public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) { - return computerPlayer.moveCardToHandWithInfo(card, sourceId, game, fromZone); + public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game) { + return computerPlayer.moveCardToHandWithInfo(card, sourceId, game); } @Override - public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean withName) { - return computerPlayer.moveCardToHandWithInfo(card, sourceId, game, fromZone, withName); + public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, boolean withName) { + return computerPlayer.moveCardToHandWithInfo(card, sourceId, game, withName); } @Override diff --git a/Mage/src/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java b/Mage/src/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java index 91b85072c9a..48dc5dcdadb 100644 --- a/Mage/src/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java +++ b/Mage/src/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,22 +20,19 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; import mage.constants.Outcome; -import mage.constants.Zone; import mage.game.Game; import mage.players.Player; -import mage.target.TargetCard; import mage.target.common.TargetCardInYourGraveyard; /** @@ -52,6 +49,7 @@ public class ReturnToHandFromGraveyardCost extends CostImpl { this.text = new StringBuilder("return ").append(target.getTargetName()).append(" from graveyard to it's owner's hand").toString(); } } + public ReturnToHandFromGraveyardCost(ReturnToHandFromGraveyardCost cost) { super(cost); } @@ -61,12 +59,12 @@ public class ReturnToHandFromGraveyardCost extends CostImpl { Player controller = game.getPlayer(controllerId); if (controller != null) { if (targets.choose(Outcome.ReturnToHand, controllerId, sourceId, game)) { - for (UUID targetId: targets.get(0).getTargets()) { + for (UUID targetId : targets.get(0).getTargets()) { mage.cards.Card targetCard = game.getCard(targetId); if (targetCard == null) { return false; } - paid |= controller.moveCardToHandWithInfo(targetCard, sourceId, game, Zone.HAND); + paid |= controller.moveCardToHandWithInfo(targetCard, sourceId, game); } } } diff --git a/Mage/src/mage/abilities/costs/common/ReturnToHandTargetPermanentCost.java b/Mage/src/mage/abilities/costs/common/ReturnToHandTargetPermanentCost.java index 4506854c705..6a0e383c83f 100644 --- a/Mage/src/mage/abilities/costs/common/ReturnToHandTargetPermanentCost.java +++ b/Mage/src/mage/abilities/costs/common/ReturnToHandTargetPermanentCost.java @@ -25,14 +25,12 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; import mage.constants.Outcome; -import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -62,12 +60,12 @@ public class ReturnToHandTargetPermanentCost extends CostImpl { Player controller = game.getPlayer(controllerId); if (controller != null) { if (targets.choose(Outcome.ReturnToHand, controllerId, sourceId, game)) { - for (UUID targetId: targets.get(0).getTargets()) { + for (UUID targetId : targets.get(0).getTargets()) { Permanent permanent = game.getPermanent(targetId); if (permanent == null) { return false; } - paid |= controller.moveCardToHandWithInfo(permanent, sourceId, game, Zone.HAND); + paid |= controller.moveCardToHandWithInfo(permanent, sourceId, game); } } } @@ -84,5 +82,4 @@ public class ReturnToHandTargetPermanentCost extends CostImpl { return new ReturnToHandTargetPermanentCost(this); } - } diff --git a/Mage/src/mage/abilities/effects/common/ClashWinReturnToHandSpellEffect.java b/Mage/src/mage/abilities/effects/common/ClashWinReturnToHandSpellEffect.java index 98bc04994d1..0ee9f0ac298 100644 --- a/Mage/src/mage/abilities/effects/common/ClashWinReturnToHandSpellEffect.java +++ b/Mage/src/mage/abilities/effects/common/ClashWinReturnToHandSpellEffect.java @@ -60,7 +60,7 @@ public class ClashWinReturnToHandSpellEffect extends OneShotEffect implements Ma if (ClashEffect.getInstance().apply(game, source)) { Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); if (spellCard != null) { - controller.moveCardToHandWithInfo(spellCard, source.getSourceId(), game, Zone.STACK); + controller.moveCards(spellCard, null, Zone.HAND, source, game); } } return true; diff --git a/Mage/src/mage/abilities/effects/common/EnvoyEffect.java b/Mage/src/mage/abilities/effects/common/EnvoyEffect.java index e0f4c22e8b2..d9e584f607e 100644 --- a/Mage/src/mage/abilities/effects/common/EnvoyEffect.java +++ b/Mage/src/mage/abilities/effects/common/EnvoyEffect.java @@ -71,18 +71,20 @@ public class EnvoyEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); - if(controller == null || sourceObject == null) { + if (controller == null || sourceObject == null) { return false; } Cards cards = new CardsImpl(); cards.addAll(controller.getLibrary().getTopCards(game, numCards)); - controller.revealCards(sourceObject.getName(), cards, game); - for(Card card: cards.getCards(game)) { - if(filter.match(card, game)) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - cards.remove(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + Cards cardsToHand = new CardsImpl(); + for (Card card : cards.getCards(game)) { + if (filter.match(card, game)) { + cardsToHand.add(card); } } + cards.removeAll(cardsToHand); + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; } @@ -94,6 +96,6 @@ public class EnvoyEffect extends OneShotEffect { } return "Reveal the top " + CardUtil.numberToText(numCards) + " cards of your library. Put all " - + filter.getMessage() + " revealed this way into your hand and the rest on the bottom of your library in any order."; + + filter.getMessage() + " revealed this way into your hand and the rest on the bottom of your library in any order."; } } diff --git a/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java b/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java index fda55a0478a..7e086481be5 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,19 +20,17 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -61,16 +59,11 @@ public class ReturnFromGraveyardToHandTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (UUID cardId: getTargetPointer().getTargets(game, source)) { - Card card = game.getCard(cardId); - if (card != null && game.getState().getZone(cardId).equals(Zone.GRAVEYARD)) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); - } - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + return controller.moveCards(new CardsImpl(getTargetPointer().getTargets(game, source)), null, Zone.HAND, source, game); } - return true; + return false; } @Override @@ -79,14 +72,14 @@ public class ReturnFromGraveyardToHandTargetEffect extends OneShotEffect { return staticText; } StringBuilder sb = new StringBuilder(); - Target target = mode.getTargets().get(0); + Target target = mode.getTargets().get(0); sb.append("return "); if (target.getMaxNumberOfTargets() > 1) { if (target.getMaxNumberOfTargets() != target.getNumberOfTargets()) { sb.append("up to "); } sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets())).append(" "); - } + } if (!mode.getTargets().get(0).getTargetName().startsWith("another")) { sb.append("target "); } diff --git a/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java index 7dccfd5a674..e669693c00a 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import mage.abilities.Ability; @@ -61,7 +60,7 @@ public class ReturnSourceFromGraveyardToHandEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Card card = controller.getGraveyard().get(source.getSourceId(), game); if (card != null) { - return controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + return controller.moveCards(card, null, Zone.HAND, source, game); } return false; } diff --git a/Mage/src/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java index aeddab66962..2b0a53aba5f 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java @@ -25,11 +25,12 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterPermanent; @@ -41,12 +42,10 @@ import mage.players.Player; * * @author Plopman */ - - public class ReturnToHandFromBattlefieldAllEffect extends OneShotEffect { private final FilterPermanent filter; - + public ReturnToHandFromBattlefieldAllEffect(FilterPermanent filter) { super(Outcome.ReturnToHand); this.filter = filter; @@ -62,9 +61,11 @@ public class ReturnToHandFromBattlefieldAllEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { + Cards cardsToHand = new CardsImpl(); for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + cardsToHand.add(permanent); } + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); return true; } return false; diff --git a/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java index 624fcf86de6..10893c286b6 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToHandSourceEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. @@ -45,20 +45,23 @@ import mage.players.Player; public class ReturnToHandSourceEffect extends OneShotEffect { boolean fromBattlefieldOnly; - boolean returnFromNextZone ; - + boolean returnFromNextZone; + public ReturnToHandSourceEffect() { this(false); } - + public ReturnToHandSourceEffect(boolean fromBattlefieldOnly) { this(fromBattlefieldOnly, false); } /** - * - * @param fromBattlefieldOnly the object is only returned if it's on the battlefield as the effect resolves - * @param returnFromNextZone the object is only returned, if it has changed the zone one time after the source ability triggered or was activated (e.g. Angelic Destiny) + * + * @param fromBattlefieldOnly the object is only returned if it's on the + * battlefield as the effect resolves + * @param returnFromNextZone the object is only returned, if it has changed + * the zone one time after the source ability triggered or was activated + * (e.g. Angelic Destiny) */ public ReturnToHandSourceEffect(boolean fromBattlefieldOnly, boolean returnFromNextZone) { super(Outcome.ReturnToHand); @@ -83,8 +86,8 @@ public class ReturnToHandSourceEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { MageObject mageObject; - if (returnFromNextZone && - game.getState().getZoneChangeCounter(source.getSourceId()) == source.getSourceObjectZoneChangeCounter() + 1) { + if (returnFromNextZone + && game.getState().getZoneChangeCounter(source.getSourceId()) == source.getSourceObjectZoneChangeCounter() + 1) { mageObject = game.getObject(source.getSourceId()); } else { mageObject = source.getSourceObjectIfItStillExists(game); @@ -94,13 +97,13 @@ public class ReturnToHandSourceEffect extends OneShotEffect { case BATTLEFIELD: Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { - return controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + return controller.moveCards(permanent, null, Zone.HAND, source, game); } break; case GRAVEYARD: Card card = (Card) mageObject; if (!fromBattlefieldOnly) { - return controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + return controller.moveCards(card, null, Zone.HAND, source, game); } } } diff --git a/Mage/src/mage/abilities/effects/common/ReturnToHandSpellEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToHandSpellEffect.java index ab34bb72add..c7f138bd302 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToHandSpellEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToHandSpellEffect.java @@ -31,7 +31,7 @@ public class ReturnToHandSpellEffect extends OneShotEffect implements MageSingle Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); - controller.moveCardToHandWithInfo(spellCard, source.getSourceId(), game, Zone.STACK); + controller.moveCards(spellCard, null, Zone.HAND, source, game); return true; } return false; diff --git a/Mage/src/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java b/Mage/src/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java index 78cf2a7424e..0d3335958e6 100644 --- a/Mage/src/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java +++ b/Mage/src/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java @@ -28,11 +28,13 @@ package mage.abilities.effects.common; import java.util.Set; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; @@ -45,7 +47,6 @@ import mage.util.CardUtil; * * @author LevelX */ - public class RevealLibraryPutIntoHandEffect extends OneShotEffect { private DynamicValue amountCards; @@ -78,27 +79,26 @@ public class RevealLibraryPutIntoHandEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { return false; } CardsImpl cards = new CardsImpl(); - int amount = Math.min(amountCards.calculate(game, source, this), player.getLibrary().size()); - for (int i = 0; i < amount; i++) { - cards.add(player.getLibrary().removeFromTop(game)); - } - player.revealCards(new StringBuilder("Put ").append(filter.getMessage()).append(" into hand").toString(), cards, game); + cards.addAll(controller.getLibrary().getTopCards(game, amountCards.calculate(game, source, this))); + controller.revealCards(sourceObject.getIdName(), cards, game); Set cardsList = cards.getCards(game); + Cards cardsToHand = new CardsImpl(); for (Card card : cardsList) { if (filter.match(card, game)) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + cardsToHand.add(card); cards.remove(card); } } - - player.putCardsOnBottomOfLibrary(cards, game, source, anyOrder); + controller.moveCards(cardsToHand, null, Zone.HAND, source, game); + controller.putCardsOnBottomOfLibrary(cards, game, source, anyOrder); return true; } diff --git a/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java b/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java index 76462b5b011..d77f5ca6a46 100644 --- a/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java @@ -134,7 +134,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { Cards revealedCards = new CardsImpl(Zone.HAND); numberToReveal = Math.min(player.getHand().size(), numberToReveal); if (player.getHand().size() > numberToReveal) { - TargetCardInHand chosenCards = new TargetCardInHand(numberToReveal, numberToReveal, new FilterCard("card in "+ player.getLogName() +"'s hand")); + TargetCardInHand chosenCards = new TargetCardInHand(numberToReveal, numberToReveal, new FilterCard("card in " + player.getLogName() + "'s hand")); chosenCards.setNotTarget(true); if (chosenCards.canChoose(player.getId(), game) && player.chooseTarget(Outcome.Discard, player.getHand(), chosenCards, source, game)) { if (!chosenCards.getTargets().isEmpty()) { @@ -151,7 +151,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { revealedCards.addAll(player.getHand()); } - player.revealCards(sourceCard != null ? sourceCard.getName() :"Discard", revealedCards, game); + player.revealCards(sourceCard != null ? sourceCard.getIdName() + " (" + sourceCard.getZoneChangeCounter(game) + ")" : "Discard", revealedCards, game); boolean result = true; int filteredCardsCount = revealedCards.count(filter, source.getSourceId(), source.getControllerId(), game); @@ -183,7 +183,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { private String setText() { StringBuilder sb = new StringBuilder("Target "); - switch(targetController) { + switch (targetController) { case OPPONENT: sb.append("opponent"); break; diff --git a/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInHandEffect.java b/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInHandEffect.java index 8c6c4e35228..694e8bf70eb 100644 --- a/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInHandEffect.java +++ b/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInHandEffect.java @@ -93,14 +93,12 @@ public class SearchLibraryPutInHandEffect extends SearchEffect { if (target.getTargets().size() > 0) { Cards cards = new CardsImpl(); for (UUID cardId : target.getTargets()) { - Card card = controller.getLibrary().remove(cardId, game); + Card card = game.getCard(cardId); if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, revealCards); - if (revealCards) { - cards.add(card); - } + cards.add(card); } } + controller.moveCards(cards, null, Zone.HAND, source, game); if (revealCards) { String name = "Reveal"; Card sourceCard = game.getCard(source.getSourceId()); diff --git a/Mage/src/mage/abilities/effects/keyword/SweepEffect.java b/Mage/src/mage/abilities/effects/keyword/SweepEffect.java index 01b10693559..5e3fc1f3d48 100644 --- a/Mage/src/mage/abilities/effects/keyword/SweepEffect.java +++ b/Mage/src/mage/abilities/effects/keyword/SweepEffect.java @@ -27,16 +27,15 @@ */ package mage.abilities.effects.keyword; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; @@ -53,7 +52,7 @@ public class SweepEffect extends OneShotEffect { public SweepEffect(String sweepSubtype) { super(Outcome.Benefit); this.sweepSubtype = sweepSubtype; - this.staticText = "Sweep - Return any number of "+ sweepSubtype + (sweepSubtype.endsWith("s") ? "":"s") + " you control to their owner's hand"; + this.staticText = "Sweep - Return any number of " + sweepSubtype + (sweepSubtype.endsWith("s") ? "" : "s") + " you control to their owner's hand"; } public SweepEffect(final SweepEffect effect) { @@ -75,10 +74,7 @@ public class SweepEffect extends OneShotEffect { Target target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true); if (controller.chooseTarget(outcome, target, source, game)) { game.getState().setValue(CardUtil.getCardZoneString("sweep", source.getSourceId(), game), target.getTargets().size()); - for (UUID uuid : target.getTargets()) { - Permanent land = game.getPermanent(uuid); - controller.moveCardToHandWithInfo(land, source.getSourceId(), game, Zone.HAND); - } + controller.moveCards(new CardsImpl(target.getTargets()), null, Zone.HAND, source, game); } return true; } diff --git a/Mage/src/mage/abilities/keyword/AuraSwapAbility.java b/Mage/src/mage/abilities/keyword/AuraSwapAbility.java index d4590bec685..ea4ddd1a6aa 100644 --- a/Mage/src/mage/abilities/keyword/AuraSwapAbility.java +++ b/Mage/src/mage/abilities/keyword/AuraSwapAbility.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; import mage.abilities.Ability; @@ -48,21 +47,21 @@ import mage.target.common.TargetCardInHand; * @author Mael */ public class AuraSwapAbility extends ActivatedAbilityImpl { - + public AuraSwapAbility(ManaCost manaCost) { super(Zone.BATTLEFIELD, new AuraSwapEffect(), manaCost); - + } - + public AuraSwapAbility(final AuraSwapAbility ability) { super(ability); } - + @Override public AuraSwapAbility copy() { return new AuraSwapAbility(this); } - + @Override public String getRule() { return new StringBuilder("Aura swap ").append(getManaCostsToPay().getText()).append(" (") @@ -72,42 +71,42 @@ public class AuraSwapAbility extends ActivatedAbilityImpl { } class AuraSwapEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard(); - + static { filter.add(new SubtypePredicate("Aura")); } - + AuraSwapEffect() { super(Outcome.PutCardInPlay); this.staticText = "Exchange this Aura with an Aura card in your hand."; } - + AuraSwapEffect(final AuraSwapEffect effect) { super(effect); } - + @Override public AuraSwapEffect copy() { return new AuraSwapEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Permanent auraPermanent = game.getPermanent(source.getSourceId()); if (auraPermanent != null && auraPermanent.getSubtype().contains("Aura") && auraPermanent.getOwnerId().equals(source.getControllerId())) { Permanent enchantedPermanent = game.getPermanent(auraPermanent.getAttachedTo()); filter.add(new AuraCardCanAttachToPermanentId(enchantedPermanent.getId())); TargetCardInHand target = new TargetCardInHand(0, 1, filter); - if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { + if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card auraInHand = game.getCard(target.getFirstTarget()); if (auraInHand != null) { - player.putOntoBattlefieldWithInfo(auraInHand, game, Zone.HAND, source.getSourceId()); + controller.putOntoBattlefieldWithInfo(auraInHand, game, Zone.HAND, source.getSourceId()); enchantedPermanent.addAttachment(auraInHand.getId(), game); - player.moveCardToHandWithInfo(auraPermanent, source.getSourceId(), game, Zone.BATTLEFIELD); + controller.moveCards(auraPermanent, null, Zone.HAND, source, game); return true; } } diff --git a/Mage/src/mage/abilities/keyword/TransmuteAbility.java b/Mage/src/mage/abilities/keyword/TransmuteAbility.java index 156a9dc8848..f4b095ea41a 100644 --- a/Mage/src/mage/abilities/keyword/TransmuteAbility.java +++ b/Mage/src/mage/abilities/keyword/TransmuteAbility.java @@ -5,7 +5,6 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.Outcome; @@ -17,25 +16,29 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; -import java.util.UUID; +import mage.MageObject; import mage.constants.TimingRule; /** * - * 702.52. Transmute + * 702.52. Transmute * - * 702.52a Transmute is an activated ability that functions only while the card with transmute is - * in a player’s hand. “Transmute [cost]” means “[Cost], Discard this card: Search your library for - * a card with the same converted mana cost as the discarded card, reveal that card, and put it into - * your hand. Then shuffle your library. Play this ability only any time you could play a sorcery.” + * 702.52a Transmute is an activated ability that functions only while the card + * with transmute is in a player’s hand. “Transmute [cost]” means “[Cost], + * Discard this card: Search your library for a card with the same converted + * mana cost as the discarded card, reveal that card, and put it into your hand. + * Then shuffle your library. Play this ability only any time you could play a + * sorcery.” * - * 702.52b Although the transmute ability is playable only if the card is in a player’s hand, it - * continues to exist while the object is in play and in all other zones. Therefore objects with - * transmute will be affected by effects that depend on objects having one or more activated abilities. + * 702.52b Although the transmute ability is playable only if the card is in a + * player’s hand, it continues to exist while the object is in play and in all + * other zones. Therefore objects with transmute will be affected by effects + * that depend on objects having one or more activated abilities. * * @author Loki */ public class TransmuteAbility extends SimpleActivatedAbility { + public TransmuteAbility(String manaCost) { super(Zone.HAND, new TransmuteEffect(), new ManaCostsImpl(manaCost)); this.setTiming(TimingRule.SORCERY); @@ -60,6 +63,7 @@ public class TransmuteAbility extends SimpleActivatedAbility { } class TransmuteEffect extends OneShotEffect { + TransmuteEffect() { super(Outcome.Benefit); staticText = "Transmute"; @@ -71,27 +75,20 @@ class TransmuteEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Card sourceCard = game.getCard(source.getSourceId()); - - if (sourceCard != null && player != null) { - FilterCard filter = new FilterCard("card with converted mana cost " + sourceCard.getManaCost().convertedManaCost()); - filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, sourceCard.getManaCost().convertedManaCost())); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null && controller != null) { + FilterCard filter = new FilterCard("card with converted mana cost " + sourceObject.getManaCost().convertedManaCost()); + filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, sourceObject.getManaCost().convertedManaCost())); TargetCardInLibrary target = new TargetCardInLibrary(1, filter); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - Cards revealed = new CardsImpl(); - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().remove(cardId, game); - if (card != null) { - player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - revealed.add(card); - } - } - player.revealCards("Search", revealed, game); + Cards revealed = new CardsImpl(target.getTargets()); + controller.revealCards(sourceObject.getIdName(), revealed, game); + controller.moveCards(revealed, null, Zone.HAND, source, game); } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index 023d63e04ca..cf94a946082 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -640,18 +640,17 @@ public interface Player extends MageItem, Copyable { * @param fromZone if null, this info isn't postet * @return */ - boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone); + boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game); /** * @param card * @param sourceId * @param game * @param withName show the card name in the log - * @param fromZone * @return * */ - boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean withName); + boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, boolean withName); /** * Uses card.moveToExile and posts a inform message about moving the card to @@ -662,7 +661,6 @@ public interface Player extends MageItem, Copyable { * @param exileName name of exile zone (optional) * @param sourceId * @param game - * @param fromZone if null, this info isn't postet * @param withName * @return */ diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index fc0e8c1a280..cbe259f9655 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -2881,6 +2881,9 @@ public abstract class PlayerImpl implements Player, Serializable { public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { ArrayList cardList = new ArrayList<>(); for (UUID cardId : cards) { + if (fromZone == null) { + fromZone = game.getState().getZone(cardId); + } if (fromZone.equals(Zone.BATTLEFIELD)) { Permanent permanent = game.getPermanent(cardId); if (permanent != null) { @@ -2925,6 +2928,7 @@ public abstract class PlayerImpl implements Player, Serializable { case EXILED: boolean result = false; for (Card card : cards) { + fromZone = game.getState().getZone(card.getId()); result |= moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName); } return result; @@ -2933,18 +2937,21 @@ public abstract class PlayerImpl implements Player, Serializable { case HAND: result = false; for (Card card : cards) { - result |= moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, withName); + fromZone = game.getState().getZone(card.getId()); + result |= moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, withName); } return result; case BATTLEFIELD: result = false; for (Card card : cards) { + fromZone = game.getState().getZone(card.getId()); result |= putOntoBattlefieldWithInfo(card, game, fromZone, source == null ? null : source.getSourceId(), false, !withName); } return result; case LIBRARY: result = false; for (Card card : cards) { + fromZone = game.getState().getZone(card.getId()); result |= moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, withName); } return result; @@ -2954,13 +2961,14 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) { - return this.moveCardToHandWithInfo(card, sourceId, game, fromZone, true); + public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game) { + return this.moveCardToHandWithInfo(card, sourceId, game, true); } @Override - public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean withName) { + public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, boolean withName) { boolean result = false; + Zone fromZone = game.getState().getZone(card.getId()); if (card.moveToZone(Zone.HAND, sourceId, game, false)) { if (card instanceof PermanentCard) { card = game.getCard(card.getId()); @@ -3025,6 +3033,7 @@ public abstract class PlayerImpl implements Player, Serializable { Card card = cards.get(targetObjectId, game); cards.remove(targetObjectId); if (card != null) { + fromZone = game.getState().getZone(card.getId()); result &= choosingPlayer.moveCardToGraveyardWithInfo(card, sourceId, game, fromZone); } target.clearChosen(); @@ -3045,6 +3054,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) { boolean result = false; + // Zone fromZone = game.getState().getZone(card.getId()); if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone.equals(Zone.BATTLEFIELD) : false)) { if (!game.isSimulation()) { if (card instanceof PermanentCard) { @@ -3052,7 +3062,7 @@ public abstract class PlayerImpl implements Player, Serializable { } StringBuilder sb = new StringBuilder(this.getLogName()) .append(" puts ").append(card.getLogName()).append(" ") - .append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") : ""); + .append(fromZone != null ? "from " + fromZone.toString().toLowerCase(Locale.ENGLISH) + " " : ""); if (card.getOwnerId().equals(getId())) { sb.append("into his or her graveyard"); } else { From 9dc0bf97fb9031267e56bf2034e8f9563acda38b Mon Sep 17 00:00:00 2001 From: klayhamn Date: Fri, 31 Jul 2015 01:32:59 +0300 Subject: [PATCH 05/24] Add missing trample ability to foriysian --- Mage.Sets/src/mage/sets/timespiral/ForiysianTotem.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/timespiral/ForiysianTotem.java b/Mage.Sets/src/mage/sets/timespiral/ForiysianTotem.java index b8a107eac5b..f5c35e200ed 100644 --- a/Mage.Sets/src/mage/sets/timespiral/ForiysianTotem.java +++ b/Mage.Sets/src/mage/sets/timespiral/ForiysianTotem.java @@ -30,17 +30,19 @@ package mage.sets.timespiral; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.SourceIsCreatureCondition; +import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.TrampleAbility; import mage.abilities.mana.RedManaAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; import mage.game.permanent.token.Token; import java.util.UUID; @@ -51,7 +53,7 @@ import java.util.UUID; */ public class ForiysianTotem extends CardImpl { - private final static String ruleText = "As long as Foriysian Totem is a creature, it can block an additional creature."; + private final static String ruleText = "As long as {this} is a creature, it can block an additional creature."; public ForiysianTotem(UUID ownerId) { super(ownerId, 254, "Foriysian Totem", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); @@ -64,7 +66,7 @@ public class ForiysianTotem extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new ForiysianTotemToken(), "", Duration.EndOfTurn), new ManaCostsImpl<>("{4}{R}"))); // As long as Foriysian Totem is a creature, it can block an additional creature. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new CanBlockAdditionalCreatureEffect(1), SourceIsCreatureCondition.getInstance() , ruleText))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new CanBlockAdditionalCreatureEffect(1), new SourceMatchesFilterCondition(new FilterCreaturePermanent()), ruleText))); } public ForiysianTotem(final ForiysianTotem card) { @@ -88,5 +90,6 @@ class ForiysianTotemToken extends Token { color.setRed(true); power = new MageInt(4); toughness = new MageInt(4); + this.addAbility(TrampleAbility.getInstance()); } } \ No newline at end of file From 5444b2a53beca160db2dfdda0fad50e03a7f5b12 Mon Sep 17 00:00:00 2001 From: klayhamn Date: Tue, 4 Aug 2015 23:25:16 +0300 Subject: [PATCH 06/24] removing the no-longer-necessary SourceIsCreature condition --- .../common/SourceIsCreatureCondition.java | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 Mage/src/mage/abilities/condition/common/SourceIsCreatureCondition.java diff --git a/Mage/src/mage/abilities/condition/common/SourceIsCreatureCondition.java b/Mage/src/mage/abilities/condition/common/SourceIsCreatureCondition.java deleted file mode 100644 index 0a877da1621..00000000000 --- a/Mage/src/mage/abilities/condition/common/SourceIsCreatureCondition.java +++ /dev/null @@ -1,25 +0,0 @@ -package mage.abilities.condition.common; - -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.condition.Condition; -import mage.constants.CardType; -import mage.game.Game; - -/** - * @author klayhamn - */ -public class SourceIsCreatureCondition implements Condition { - - private static final SourceIsCreatureCondition fInstance = new SourceIsCreatureCondition(); - - public static Condition getInstance() { - return fInstance; - } - - @Override - public boolean apply(Game game, Ability source) { - MageObject object = game.getObject(source.getSourceId()); - return object != null && object.getCardType().contains(CardType.CREATURE); - } -} From e5433599b679b6541da89f5ebaa66895e63c761a Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 4 Aug 2015 23:09:11 +0200 Subject: [PATCH 07/24] * Costal Piracy - Fixed some code problems. --- .../mage/sets/mercadianmasques/CoastalPiracy.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/CoastalPiracy.java b/Mage.Sets/src/mage/sets/mercadianmasques/CoastalPiracy.java index 3f82bc4f48e..775da107107 100644 --- a/Mage.Sets/src/mage/sets/mercadianmasques/CoastalPiracy.java +++ b/Mage.Sets/src/mage/sets/mercadianmasques/CoastalPiracy.java @@ -35,22 +35,21 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.DamagedEvent; +import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; /** -* -* @author Xavierv3131 -*/ + * + * @author Xavierv3131 + */ public class CoastalPiracy extends CardImpl { public CoastalPiracy(UUID ownerId) { super(ownerId, 68, "Coastal Piracy", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}"); this.expansionSetCode = "MMQ"; - // Whenever a creature you control deals combat damage to an opponent, you may draw a card. this.addAbility(new CoastalPiracyTriggeredAbility()); } @@ -88,8 +87,8 @@ class CoastalPiracyTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (((DamagedPlayerEvent) event).isCombatDamage()) && - game.getOpponents(this.controllerId).contains(((DamagedPlayerEvent) event).getPlayerId())) { + if (((DamagedPlayerEvent) event).isCombatDamage() + && game.getOpponents(this.controllerId).contains(((DamagedPlayerEvent) event).getPlayerId())) { Permanent creature = game.getPermanent(event.getSourceId()); if (creature != null && creature.getControllerId().equals(controllerId)) { return true; @@ -103,4 +102,4 @@ class CoastalPiracyTriggeredAbility extends TriggeredAbilityImpl { return "Whenever a creature you control deals combat damage to an opponent, you may draw a card."; } -} \ No newline at end of file +} From 7ff4087bc7096518c74efc437f381ad623112035 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 4 Aug 2015 23:20:38 +0200 Subject: [PATCH 08/24] * Kicker - Fixed that canceled multikicker activations were not reseted on recast. --- Mage/src/mage/abilities/keyword/KickerAbility.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mage/src/mage/abilities/keyword/KickerAbility.java b/Mage/src/mage/abilities/keyword/KickerAbility.java index 9318c39e039..3753632b553 100644 --- a/Mage/src/mage/abilities/keyword/KickerAbility.java +++ b/Mage/src/mage/abilities/keyword/KickerAbility.java @@ -143,6 +143,13 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo for (OptionalAdditionalCost cost : kickerCosts) { cost.reset(); } + String key = getActivationKey(source, "", game); + for (String activationKey : activations.keySet()) { + if (activationKey.startsWith(key) && activations.get(activationKey) > 0) { + activations.put(key, 0); + } + } + } public int getXManaValue() { From 796a8d15d6678fcef19b0392eef05c2ad8796278 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 4 Aug 2015 23:23:51 +0200 Subject: [PATCH 09/24] * Petalmane Baku - Fixed wrong activation cost. --- .../src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java index d7ee3a8fd78..0e0eca1d7e4 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java @@ -34,7 +34,7 @@ import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.RemoveVariableCountersSourceCost; -import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.CountersCount; import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue; import mage.abilities.effects.common.ManaEffect; @@ -72,7 +72,7 @@ public class PetalmaneBaku extends CardImpl { Ability ability = new DynamicManaAbility( new Mana(0, 0, 0, 0, 0, 0, 1), new RemovedCountersForCostValue(), - new TapSourceCost(), + new ManaCostsImpl<>("{1}"), "Add X mana of any one color to your mana pool", true, new CountersCount(CounterType.KI)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), From 36cacff5375e8fcd4126362635b511f8ed70a285 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 4 Aug 2015 23:31:55 +0200 Subject: [PATCH 10/24] * Historical Standard - Fixed the missing Scourge expansion data. --- .../src/mage/deck/HistoricalStandard.java | 87 +++++++----------- .../src/mage/deck/SuperStandard.java | 91 ++++++++----------- 2 files changed, 73 insertions(+), 105 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalStandard.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalStandard.java index ceb699b1247..9fef3463b57 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalStandard.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalStandard.java @@ -1,25 +1,24 @@ package mage.deck; -import mage.cards.ExpansionSet; -import mage.cards.Sets; -import mage.cards.decks.Constructed; -import mage.cards.decks.Deck; -import mage.constants.SetType; - import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; +import mage.cards.ExpansionSet; +import mage.cards.Sets; +import mage.cards.decks.Constructed; +import mage.cards.decks.Deck; +import mage.constants.SetType; /** * This class represents a deck from any past standard. - * + * * This class was originally made to work with the historical standard ruleset. - * Data taken from http://thattournament.website/historic-tournament.php - * (site changed, originally http://mtgt.nfshost.com/historic-tournament.php) - * + * Data taken from http://thattournament.website/historic-tournament.php (site + * changed, originally http://mtgt.nfshost.com/historic-tournament.php) + * * If there are any questions or corrections, feel free to contact me. * * @author Marthinwurer (at gmail.com) @@ -27,77 +26,56 @@ import java.util.Map; public class HistoricalStandard extends Constructed { /* - * This array stores the set codes of each standard up to + * This array stores the set codes of each standard up to * Kamigawa/Ravnica standard, where rotation stabilized. */ protected static final String[][] standards = { - // 1st standard: The Dark, Fallen Empires, and 4th. - { "DRK", "FEM", "4ED" }, - + {"DRK", "FEM", "4ED"}, // 2nd standard: 4th, Fallen Empires, Ice Age, Chronicles, Homelands, // Alliances, and Mirage. {"FEM", "4ED", "ICE", "HML", "ALL", "MIR"}, - // 3rd standard: 4th, Chronicles, Alliances, Mirage, Visions. {"4ED", "ALL", "MIR", "VIS"}, - // 4th Standard: Ice Age, Homelands, Alliances, Mirage, Visions, 5th, // and Weatherlight. {"ICE", "HML", "ALL", "MIR", "VIS", "5ED", "WTH"}, - // 5th Standard: Mirage, Visions, 5th, Weatherlight, Tempest, // Stronghold, and Exodus. {"MIR", "VIS", "5ED", "WTH", "TMP", "STH", "EXO"}, - // 6th Standard: 5th, Tempest, Stronghold, Exodus, Urza's Saga, Urza's // Legacy, Urza's Destiny. {"5ED", "TMP", "STH", "EXO", "USG", "ULG"}, - // 7th Standard: Tempest, Stronghold, Exodus, Urza's Saga, Urza's // Legacy, 6th, Urza's Destiny. {"TMP", "STH", "EXO", "USG", "ULG", "6ED", "UDS"}, - // 8th Standard: Urza's Saga, Urza's Legacy, 6th, Urza's Destiny, // Mercadian Masques, Nemesis, Prophecy. {"USG", "ULG", "6ED", "UDS", "MMQ", "NMS", "PCY"}, - // 9th Standard {"6ED", "MMQ", "NMS", "PCY", "INV", "PLS"}, - // 10th Standard {"7ED", "MMQ", "NMS", "PCY", "INV", "PLS", "APC"}, - // 11th Standard {"7ED", "INV", "APC", "PLS", "ODY", "TOR", "JUD"}, - // 12th Standard - {"7ED", "ODY", "TOR", "JUD", "ONS", "LGN", "LGN"}, - + {"7ED", "ODY", "TOR", "JUD", "ONS", "LGN", "SCG"}, // 13th Standard - {"8ED", "ODY", "TOR", "JUD", "ONS", "LGN", "LGN"}, - + {"8ED", "ODY", "TOR", "JUD", "ONS", "LGN", "SCG"}, // 14th Standard - {"8ED", "ONS", "LGN", "LGN", "MRD", "DST", "5DN"}, - + {"8ED", "ONS", "LGN", "SCG", "MRD", "DST", "5DN"}, // 15th Standard {"8ED", "MRD", "DST", "5DN", "CHK", "BOK", "SOK"}, - // 16th Standard {"9ED", "MRD", "DST", "5DN", "CHK", "BOK", "SOK"}, - // 17th Standard {"9ED", "CHK", "BOK", "SOK", "RAV", "GPT", "DIS", "CSP"}, - // 18th Standard {"9ED", "RAV", "GPT", "DIS", "CSP", "TSP", "TSB", "PLC", "FUT"}, - // 19th Standard {"10E", "RAV", "GPT", "DIS", "CSP", "TSP", "PLC", "FUT"}, - // 20th Standard {"10E", "CSP", "TSP", "PLC", "FUT", "LRW", "MOR", "SHM", "EVE"}, - // 21st Standard {"10E", "LRW", "MOR", "SHM", "EVE", "ALA", "CON", "ARB"} }; @@ -108,7 +86,7 @@ public class HistoricalStandard extends Constructed { */ public HistoricalStandard() { super("Constructed - Historical Standard"); - + // banned cards banned.add("Balance"); banned.add("Memory Jar"); @@ -122,23 +100,24 @@ public class HistoricalStandard extends Constructed { /** * Overridden validate function. Changes the standard sets, then uses the * regular validation function to test validity. + * * @param deck - the deck to validate. - * @return + * @return */ @Override public boolean validate(Deck deck) { Map leastInvalid = null; - + boolean valid = false; - + // first, check whether misty and batterskull are in the same deck. Map counts = new HashMap<>(); countCards(counts, deck.getCards()); countCards(counts, deck.getSideboard()); - if( counts.containsKey("Stoneforge Mystic") - && counts.containsKey("Batterskull")){ - + if (counts.containsKey("Stoneforge Mystic") + && counts.containsKey("Batterskull")) { + // if both, then skip all following tests by returning return false; } @@ -159,7 +138,7 @@ public class HistoricalStandard extends Constructed { break; } - // if the map holding the invalid cards is empty, set it to a + // if the map holding the invalid cards is empty, set it to a // copy of the current invalid list. if (leastInvalid == null) { leastInvalid = new HashMap<>(this.getInvalid()); @@ -182,7 +161,7 @@ public class HistoricalStandard extends Constructed { Calendar.SEPTEMBER, 1); GregorianCalendar current = new GregorianCalendar(); - // use the method for determining regular standard legality, but change + // use the method for determining regular standard legality, but change // the date for each standard. while (end.before(current) && !valid) { @@ -190,11 +169,11 @@ public class HistoricalStandard extends Constructed { setCodes.clear(); invalid.clear(); - // increment the start and end dates. + // increment the start and end dates. start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1); end.set(Calendar.YEAR, start.get(Calendar.YEAR) + 2); - // Get the sets in that time period. + // Get the sets in that time period. // (code taken from standard.java) for (ExpansionSet set : Sets.getInstance().values()) { if (set.getReleaseDate().after(start.getTime()) @@ -203,7 +182,7 @@ public class HistoricalStandard extends Constructed { setCodes.add(set.getCode()); } } - + // validate it. If it validates, clear the invalid cards and break. if (super.validate(deck)) { invalid.clear(); @@ -214,20 +193,20 @@ public class HistoricalStandard extends Constructed { // see how many invalid cards there are. if there are less invalid // cards than the stored invalid list, assign the current invalid // to leastInvalid. - if (leastInvalid == null){ + if (leastInvalid == null) { leastInvalid = new HashMap<>(this.getInvalid()); - - }else if (leastInvalid.size() > this.getInvalid().size()) { + + } else if (leastInvalid.size() > this.getInvalid().size()) { leastInvalid = new HashMap<>(this.getInvalid()); } } - // if no standard environment is valid, set the invalid to the + // if no standard environment is valid, set the invalid to the // invalid that had the least errors. - if( !valid ){ + if (!valid) { this.invalid = new HashMap<>(leastInvalid); } - + // return the validity. return valid; } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperStandard.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperStandard.java index 9b6a91dba0f..1f30667570f 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperStandard.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperStandard.java @@ -1,26 +1,25 @@ package mage.deck; -import mage.cards.ExpansionSet; -import mage.cards.Sets; -import mage.cards.decks.Constructed; -import mage.cards.decks.Deck; -import mage.constants.SetType; - import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; +import mage.cards.ExpansionSet; +import mage.cards.Sets; +import mage.cards.decks.Constructed; +import mage.cards.decks.Deck; +import mage.constants.SetType; /** - * This class represents a deck conforming to the rules contained in the - subreddit /r/SuperStandard. - * + * This class represents a deck conforming to the rules contained in the + * subreddit /r/SuperStandard. + * * This class was originally made to work with the historical standard ruleset. - * Data taken from http://thattournament.website/historic-tournament.php - * (site changed, originally thtp://mtgt.nfshost.com/historic-tournament.php) - * + * Data taken from http://thattournament.website/historic-tournament.php (site + * changed, originally thtp://mtgt.nfshost.com/historic-tournament.php) + * * If there are any questions or corrections, feel free to contact me. * * @author Marthinwurer (at gmail.com) @@ -28,42 +27,31 @@ import java.util.Map; public class SuperStandard extends Constructed { /* - * This array stores the set codes of each standard up to + * This array stores the set codes of each standard up to * Kamigawa/Ravnica standard, where rotation stabilized. * Data taken from http://thattournament.website/historic-tournament.php */ protected static final String[][] standards = { - // 11th Standard {"7ED", "INV", "APC", "PLS", "ODY", "TOR", "JUD"}, - // 12th Standard - {"7ED", "ODY", "TOR", "JUD", "ONS", "LGN", "LGN"}, - + {"7ED", "ODY", "TOR", "JUD", "ONS", "LGN", "SCG"}, // 13th Standard - {"8ED", "ODY", "TOR", "JUD", "ONS", "LGN", "LGN"}, - + {"8ED", "ODY", "TOR", "JUD", "ONS", "LGN", "SCG"}, // 14th Standard - {"8ED", "ONS", "LGN", "LGN", "MRD", "DST", "5DN"}, - + {"8ED", "ONS", "LGN", "SCG", "MRD", "DST", "5DN"}, // 15th Standard {"8ED", "MRD", "DST", "5DN", "CHK", "BOK", "SOK"}, - // 16th Standard {"9ED", "MRD", "DST", "5DN", "CHK", "BOK", "SOK"}, - // 17th Standard {"9ED", "CHK", "BOK", "SOK", "RAV", "GPT", "DIS", "CSP"}, - // 18th Standard {"9ED", "RAV", "GPT", "DIS", "CSP", "TSP", "TSB", "PLC", "FUT"}, - // 19th Standard {"10E", "RAV", "GPT", "DIS", "CSP", "TSP", "PLC", "FUT"}, - // 20th Standard {"10E", "CSP", "TSP", "PLC", "FUT", "LRW", "MOR", "SHM", "EVE"}, - // 21st Standard {"10E", "LRW", "MOR", "SHM", "EVE", "ALA", "CON", "ARB"} }; @@ -87,23 +75,24 @@ public class SuperStandard extends Constructed { /** * Overridden validate function. Changes the standard sets, then uses the * regular validation function to test validity. + * * @param deck - the deck to validate. - * @return + * @return */ @Override public boolean validate(Deck deck) { Map leastInvalid = null; - + boolean valid = false; - + // first, check whether misty and batterskull are in the same deck. Map counts = new HashMap<>(); countCards(counts, deck.getCards()); countCards(counts, deck.getSideboard()); - if( counts.containsKey("Stoneforge Mystic") - && counts.containsKey("Batterskull")){ - + if (counts.containsKey("Stoneforge Mystic") + && counts.containsKey("Batterskull")) { + // if both, then skip all following tests by returning return false; } @@ -117,12 +106,12 @@ public class SuperStandard extends Constructed { // add the sets to the setCodes. setCodes = new ArrayList<>(Arrays.asList(sets)); - - // if either of the mirrodin blocks are in the time period, ban + + // if either of the mirrodin blocks are in the time period, ban // misty and darksteel citadel - if( setCodes.contains("MRD") || setCodes.contains("SOM")){ + if (setCodes.contains("MRD") || setCodes.contains("SOM")) { banned.add("Darksteel Citadel"); - }else{ + } else { banned.remove("Darksteel Citadel"); } @@ -132,7 +121,7 @@ public class SuperStandard extends Constructed { break; } - // if the map holding the invalid cards is empty, set it to a + // if the map holding the invalid cards is empty, set it to a // copy of the current invalid list. if (leastInvalid == null) { leastInvalid = new HashMap<>(this.getInvalid()); @@ -155,7 +144,7 @@ public class SuperStandard extends Constructed { Calendar.SEPTEMBER, 1); GregorianCalendar current = new GregorianCalendar(); - // use the method for determining regular standard legality, but change + // use the method for determining regular standard legality, but change // the date for each standard. while (end.before(current) && !valid) { @@ -163,11 +152,11 @@ public class SuperStandard extends Constructed { setCodes.clear(); invalid.clear(); - // increment the start and end dates. + // increment the start and end dates. start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1); end.set(Calendar.YEAR, start.get(Calendar.YEAR) + 2); - // Get the sets in that time period. + // Get the sets in that time period. // (code taken from standard.java) for (ExpansionSet set : Sets.getInstance().values()) { if (set.getReleaseDate().after(start.getTime()) @@ -176,12 +165,12 @@ public class SuperStandard extends Constructed { setCodes.add(set.getCode()); } } - - // if either of the mirrodin blocks are in the time period, ban + + // if either of the mirrodin blocks are in the time period, ban // misty and darksteel citadel - if( setCodes.contains("MRD") || setCodes.contains("SOM")){ + if (setCodes.contains("MRD") || setCodes.contains("SOM")) { banned.add("Darksteel Citadel"); - }else{ + } else { banned.remove("Darksteel Citadel"); } @@ -195,20 +184,20 @@ public class SuperStandard extends Constructed { // see how many invalid cards there are. if there are less invalid // cards than the stored invalid list, assign the current invalid // to leastInvalid. - if (leastInvalid == null){ + if (leastInvalid == null) { leastInvalid = new HashMap<>(this.getInvalid()); - - }else if (leastInvalid.size() > this.getInvalid().size()) { + + } else if (leastInvalid.size() > this.getInvalid().size()) { leastInvalid = new HashMap<>(this.getInvalid()); } } - // if no standard environment is valid, set the invalid to the + // if no standard environment is valid, set the invalid to the // invalid that had the least errors. - if( !valid ){ + if (!valid) { this.invalid = new HashMap<>(leastInvalid); } - + // return the validity. return valid; } From cbbc70d26b06f8ae15ddf8a5b620f49fe48a8de2 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 5 Aug 2015 00:07:53 +0200 Subject: [PATCH 11/24] * Made table filter more accurate and moved Historical and Super Standard format to Other filter. --- .../java/mage/client/table/TablesPanel.java | 349 +++++++++--------- 1 file changed, 172 insertions(+), 177 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index a92e06a60f0..1a56c2873dc 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -1,37 +1,36 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ /* * TablesPanel.java * * Created on 15-Dec-2009, 10:54:01 PM */ - package mage.client.table; import java.awt.Color; @@ -117,14 +116,16 @@ public class TablesPanel extends javax.swing.JPanel { private List messages; private int currentMessage; private MageTableRowSorter activeTablesSorter; - + JToggleButton[] filterButtons; - + private static final int[] defaultColumnsWidth = {35, 150, 120, 180, 80, 120, 80, 60, 60}; - - /** Creates new form TablesPanel */ + + /** + * Creates new form TablesPanel + */ public TablesPanel() { - + tableModel = new TableTableModel(); matchesModel = new MatchesTableModel(); gameChooser = new GameChooser(); @@ -133,49 +134,46 @@ public class TablesPanel extends javax.swing.JPanel { tableModel.setSession(session); tableTables.createDefaultColumnsFromModel(); - + activeTablesSorter = new MageTableRowSorter(tableModel); tableTables.setRowSorter(activeTablesSorter); - - TableUtil.setColumnWidthAndOrder(tableTables, defaultColumnsWidth, + + TableUtil.setColumnWidthAndOrder(tableTables, defaultColumnsWidth, PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER); - + tableCompleted.setRowSorter(new MageTableRowSorter(matchesModel)); chatPanel.useExtendedView(ChatPanel.VIEW_MODE.NONE); chatPanel.setBorder(null); chatPanel.setChatType(ChatPanel.ChatType.TABLES); - filterButtons = new JToggleButton[] - {btnStateWaiting, btnStateActive, btnStateFinished, - btnTypeMatch, btnTypeTourneyConstructed, btnTypeTourneyLimited, - btnFormatBlock, btnFormatStandard, btnFormatModern, btnFormatLegacy, btnFormatVintage, btnFormatCommander, btnFormatTinyLeader, btnFormatLimited, btnFormatOther, - btnSkillBeginner, btnSkillCasual, btnSkillSerious }; - - JComponent[] components = new JComponent[] {chatPanel, jSplitPane1, jScrollPane1, jScrollPane2, topPanel, jPanel3}; + filterButtons = new JToggleButton[]{btnStateWaiting, btnStateActive, btnStateFinished, + btnTypeMatch, btnTypeTourneyConstructed, btnTypeTourneyLimited, + btnFormatBlock, btnFormatStandard, btnFormatModern, btnFormatLegacy, btnFormatVintage, btnFormatCommander, btnFormatTinyLeader, btnFormatLimited, btnFormatOther, + btnSkillBeginner, btnSkillCasual, btnSkillSerious}; + + JComponent[] components = new JComponent[]{chatPanel, jSplitPane1, jScrollPane1, jScrollPane2, topPanel, jPanel3}; for (JComponent component : components) { component.setOpaque(false); } - jScrollPane1.getViewport().setBackground(new Color(255,255,255,50)); - jScrollPane2.getViewport().setBackground(new Color(255,255,255,50)); - + jScrollPane1.getViewport().setBackground(new Color(255, 255, 255, 50)); + jScrollPane2.getViewport().setBackground(new Color(255, 255, 255, 50)); + restoreSettings(); - + Action openTableAction; - openTableAction = new AbstractAction() - { + openTableAction = new AbstractAction() { @Override - public void actionPerformed(ActionEvent e) - { - int modelRow = Integer.valueOf( e.getActionCommand() ); - UUID tableId = (UUID)tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 3); - UUID gameId = (UUID)tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 2); - String action = (String)tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN); - String deckType = (String)tableModel.getValueAt(modelRow, TableTableModel.COLUMN_DECK_TYPE); - String status = (String)tableModel.getValueAt(modelRow, TableTableModel.COLUMN_STATUS); - boolean isTournament = (Boolean)tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 1); - String owner = (String)tableModel.getValueAt(modelRow, TableTableModel.COLUMN_OWNER); + public void actionPerformed(ActionEvent e) { + int modelRow = Integer.valueOf(e.getActionCommand()); + UUID tableId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 3); + UUID gameId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 2); + String action = (String) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN); + String deckType = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_DECK_TYPE); + String status = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_STATUS); + boolean isTournament = (Boolean) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 1); + String owner = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_OWNER); switch (action) { case "Join": if (owner.equals(session.getUserName()) || owner.startsWith(session.getUserName() + ",")) { @@ -213,49 +211,46 @@ public class TablesPanel extends javax.swing.JPanel { } else { logger.info("Joining table " + tableId); joinTableDialog.showDialog(roomId, tableId, false, false); - } + } break; case "Remove": if (JOptionPane.showConfirmDialog(null, "Are you sure you want to remove table?", "Removing table", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { session.removeTable(roomId, tableId); - } + } break; case "Show": if (isTournament) { logger.info("Showing tournament table " + tableId); session.watchTable(roomId, tableId); - } + } break; case "Watch": if (!isTournament) { logger.info("Watching table " + tableId); session.watchTable(roomId, tableId); - } + } break; case "Replay": logger.info("Replaying game " + gameId); session.replayGame(gameId); break; } - } - }; + } + }; - Action closedTableAction; - closedTableAction = new AbstractAction() - { + Action closedTableAction; + closedTableAction = new AbstractAction() { @Override - public void actionPerformed(ActionEvent e) - { - int modelRow = Integer.valueOf( e.getActionCommand() ); - String action = (String)matchesModel.getValueAt(modelRow, MatchesTableModel.ACTION_COLUMN); + public void actionPerformed(ActionEvent e) { + int modelRow = Integer.valueOf(e.getActionCommand()); + String action = (String) matchesModel.getValueAt(modelRow, MatchesTableModel.ACTION_COLUMN); switch (action) { - case "Replay": - List gameList = matchesModel.getListofGames(modelRow); + case "Replay": + List gameList = matchesModel.getListofGames(modelRow); if (gameList != null && gameList.size() > 0) { if (gameList.size() == 1) { session.replayGame(gameList.get(0)); - } - else { + } else { gameChooser.show(gameList, MageFrame.getDesktop().getMousePosition()); } } @@ -265,18 +260,18 @@ public class TablesPanel extends javax.swing.JPanel { if (matchesModel.isTournament(modelRow)) { logger.info("Showing tournament table " + matchesModel.getTableId(modelRow)); session.watchTable(roomId, matchesModel.getTableId(modelRow)); - } + } break; } } }; - + // !!!! adds action buttons to the table panel (don't delete this) new ButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TableTableModel.ACTION_COLUMN)); new ButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.ACTION_COLUMN)); // !!!! } - + public void cleanUp() { saveSettings(); chatPanel.cleanUp(); @@ -291,30 +286,30 @@ public class TablesPanel extends javax.swing.JPanel { PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, Integer.toString(this.jSplitPane2.getDividerLocation())); PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, Integer.toString(chatPanel.getSplitDividerLocation())); } - + private void restoreSettings() { // filter settings String formatSettings = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_FILTER_SETTINGS, ""); int i = 0; for (JToggleButton component : filterButtons) { if (formatSettings.length() > i) { - component.setSelected(formatSettings.substring(i,i+1).equals("x")); + component.setSelected(formatSettings.substring(i, i + 1).equals("x")); } else { component.setSelected(true); } i++; - } + } setTableFilter(); } - + private void saveSettings() { // Filters StringBuilder formatSettings = new StringBuilder(); for (JToggleButton component : filterButtons) { - formatSettings.append(component.isSelected() ? "x":"-"); + formatSettings.append(component.isSelected() ? "x" : "-"); } PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_FILTER_SETTINGS, formatSettings.toString()); - + TableUtil.saveColumnWidthAndOrderToPrefs(tableTables, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); } @@ -331,13 +326,12 @@ public class TablesPanel extends javax.swing.JPanel { } if (this.btnStateFinished.isSelected()) { this.jSplitPane2.setDividerLocation(-1); - } - else { + } else { location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, null); if (location != null && jSplitPane2 != null) { jSplitPane2.setDividerLocation(Integer.parseInt(location)); } - } + } location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, null); if (location != null && chatPanel != null) { chatPanel.setSplitDividerLocation(Integer.parseInt(location)); @@ -345,7 +339,7 @@ public class TablesPanel extends javax.swing.JPanel { } } } - + public Map getUIComponents() { Map components = new HashMap<>(); @@ -390,11 +384,10 @@ public class TablesPanel extends javax.swing.JPanel { updateMatchesTask = new UpdateMatchesTask(session, roomId, this); updateMatchesTask.execute(); } - } - else { - if (updateMatchesTask != null) { - updateMatchesTask.cancel(true); - } + } else { + if (updateMatchesTask != null) { + updateMatchesTask.cancel(true); + } } } } @@ -445,15 +438,15 @@ public class TablesPanel extends javax.swing.JPanel { reloadMessages(); MageFrame.getUI().addButton(MageComponents.NEW_GAME_BUTTON, btnNewTable); - + // divider locations have to be set with delay else values set are overwritten with system defaults Executors.newSingleThreadScheduledExecutor().schedule(new Runnable() { @Override public void run() { restoreDividerLocations(); } - }, 300, TimeUnit.MILLISECONDS); - + }, 300, TimeUnit.MILLISECONDS); + } protected void reloadMessages() { @@ -476,7 +469,7 @@ public class TablesPanel extends javax.swing.JPanel { this.saveDividerLocations(); for (Component component : MageFrame.getDesktop().getComponents()) { if (component instanceof TableWaitingDialog) { - ((TableWaitingDialog)component).closeDialog(); + ((TableWaitingDialog) component).closeDialog(); } } stopTasks(); @@ -487,7 +480,7 @@ public class TablesPanel extends javax.swing.JPanel { c = c.getParent(); } if (c != null) { - ((TablesPane)c).hideFrame(); + ((TablesPane) c).hideFrame(); } } @@ -520,31 +513,31 @@ public class TablesPanel extends javax.swing.JPanel { // format List> formatFilterList = new ArrayList<>(); if (btnFormatBlock.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Block", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Constructed.*Block", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatStandard.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Standard", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Constructed - Standard", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatModern.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Modern", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Constructed - Modern", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatLegacy.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Legacy", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Constructed - Legacy", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatVintage.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Vintage", TableTableModel.COLUMN_DECK_TYPE)); - } + formatFilterList.add(RowFilter.regexFilter("^Constructed - Vintage", TableTableModel.COLUMN_DECK_TYPE)); + } if (btnFormatCommander.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Commander", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatTinyLeader.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Tiny", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Tiny", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatLimited.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Limited", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Limited", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatOther.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("Pauper|Extended", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Constructed - Pauper|^Constructed - Extended|^Constructed - Historical|^Constructed - Super", TableTableModel.COLUMN_DECK_TYPE)); } List> skillFilterList = new ArrayList<>(); @@ -557,7 +550,7 @@ public class TablesPanel extends javax.swing.JPanel { if (btnSkillSerious.isSelected()) { skillFilterList.add(RowFilter.regexFilter(SkillLevel.SERIOUS.toString(), TableTableModel.COLUMN_SKILL)); } - + if (stateFilterList.isEmpty() || typeFilterList.isEmpty() || formatFilterList.isEmpty() || skillFilterList.isEmpty()) { // no selection activeTablesSorter.setRowFilter(RowFilter.regexFilter("Nothing", TableTableModel.COLUMN_SKILL)); } else { @@ -568,7 +561,7 @@ public class TablesPanel extends javax.swing.JPanel { } else if (stateFilterList.size() == 1) { filterList.addAll(stateFilterList); } - + if (typeFilterList.size() > 1) { filterList.add(RowFilter.orFilter(typeFilterList)); } else if (typeFilterList.size() == 1) { @@ -586,7 +579,7 @@ public class TablesPanel extends javax.swing.JPanel { } else if (skillFilterList.size() == 1) { filterList.addAll(skillFilterList); } - + if (filterList.size() == 1) { activeTablesSorter.setRowFilter(filterList.get(0)); } else { @@ -594,11 +587,11 @@ public class TablesPanel extends javax.swing.JPanel { } } } - - /** This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents @@ -1124,37 +1117,37 @@ public class TablesPanel extends javax.swing.JPanel { }// //GEN-END:initComponents private void btnNewTournamentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTournamentActionPerformed - newTournamentDialog.showDialog(roomId); + newTournamentDialog.showDialog(roomId); }//GEN-LAST:event_btnNewTournamentActionPerformed private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed - TableView table; - try { - File f = new File("test.dck"); - if (!f.exists()) { - JOptionPane.showMessageDialog(null, "Couldn't find test.dck file for quick game start", "Error", JOptionPane.ERROR_MESSAGE); - return; - } - - MatchOptions options = new MatchOptions("1", "Two Player Duel"); - options.getPlayerTypes().add("Human"); - options.getPlayerTypes().add("Computer - mad"); - options.setDeckType("Limited"); - options.setAttackOption(MultiplayerAttackOption.LEFT); - options.setRange(RangeOfInfluence.ALL); - options.setWinsNeeded(1); - options.setMatchTimeLimit(MatchTimeLimit.NONE); - options.setFreeMulligans(2); - options.setSkillLevel(SkillLevel.CASUAL); - options.setRollbackTurnsAllowed(true); - table = session.createTable(roomId, options); - - session.joinTable(roomId, table.getTableId(), "Human", "Human", 1, DeckImporterUtil.importDeck("test.dck"),""); - session.joinTable(roomId, table.getTableId(), "Computer", "Computer - mad", 5, DeckImporterUtil.importDeck("test.dck"),""); - session.startMatch(roomId, table.getTableId()); - } catch (HeadlessException ex) { - handleError(ex); + TableView table; + try { + File f = new File("test.dck"); + if (!f.exists()) { + JOptionPane.showMessageDialog(null, "Couldn't find test.dck file for quick game start", "Error", JOptionPane.ERROR_MESSAGE); + return; } + + MatchOptions options = new MatchOptions("1", "Two Player Duel"); + options.getPlayerTypes().add("Human"); + options.getPlayerTypes().add("Computer - mad"); + options.setDeckType("Limited"); + options.setAttackOption(MultiplayerAttackOption.LEFT); + options.setRange(RangeOfInfluence.ALL); + options.setWinsNeeded(1); + options.setMatchTimeLimit(MatchTimeLimit.NONE); + options.setFreeMulligans(2); + options.setSkillLevel(SkillLevel.CASUAL); + options.setRollbackTurnsAllowed(true); + table = session.createTable(roomId, options); + + session.joinTable(roomId, table.getTableId(), "Human", "Human", 1, DeckImporterUtil.importDeck("test.dck"), ""); + session.joinTable(roomId, table.getTableId(), "Computer", "Computer - mad", 5, DeckImporterUtil.importDeck("test.dck"), ""); + session.startMatch(roomId, table.getTableId()); + } catch (HeadlessException ex) { + handleError(ex); + } }//GEN-LAST:event_btnQuickStartActionPerformed private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed @@ -1180,8 +1173,7 @@ public class TablesPanel extends javax.swing.JPanel { private void btnStateFinishedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStateFinishedActionPerformed if (this.btnStateFinished.isSelected()) { this.jSplitPane2.setDividerLocation(-1); - } - else { + } else { this.jSplitPane2.setDividerLocation(this.jPanel3.getHeight()); } this.startTasks(); @@ -1192,7 +1184,6 @@ public class TablesPanel extends javax.swing.JPanel { JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE); } - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JToggleButton btnFormatBlock; private javax.swing.JToggleButton btnFormatCommander; @@ -1235,14 +1226,15 @@ public class TablesPanel extends javax.swing.JPanel { private javax.swing.JTable tableTables; private javax.swing.JPanel topPanel; // End of variables declaration//GEN-END:variables - + } class TableTableModel extends AbstractTableModel { + ImageIcon tourneyIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/tourney_icon.png")); ImageIcon matchIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/match_icon.png")); - - public static final int COLUMN_ICON = 0; + + public static final int COLUMN_ICON = 0; public static final int COLUMN_DECK_TYPE = 1; // column the deck type is located (starting with 0) Start string is used to check for Limited public static final int COLUMN_OWNER = 2; public static final int COLUMN_GAME_TYPE = 3; @@ -1251,18 +1243,19 @@ class TableTableModel extends AbstractTableModel { public static final int COLUMN_SKILL = 7; public static final int ACTION_COLUMN = 8; // column the action is located (starting with 0) - private final String[] columnNames = new String[]{"M/T","Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Created / Started", "Skill Level", "Action"}; - + private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Created / Started", "Skill Level", "Action"}; + private TableView[] tables = new TableView[0]; - private static final DateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss");; + private static final DateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss"); + ; private Session session; - + public void loadData(Collection tables) throws MageRemoteException { this.tables = tables.toArray(new TableView[0]); this.fireTableDataChanged(); - } - + } + @Override public int getRowCount() { return tables.length; @@ -1281,7 +1274,7 @@ class TableTableModel extends AbstractTableModel { public Object getValueAt(int arg0, int arg1) { switch (arg1) { case 0: - return tables[arg0].isTournament() ? tourneyIcon:matchIcon; + return tables[arg0].isTournament() ? tourneyIcon : matchIcon; case 1: return tables[arg0].getDeckType(); case 2: @@ -1316,10 +1309,10 @@ class TableTableModel extends AbstractTableModel { } else { owner = tables[arg0].getControllerName(); if (session != null && owner.equals(session.getUserName())) { - return ""; + return ""; } return "Watch"; - } + } default: return ""; } @@ -1348,7 +1341,7 @@ class TableTableModel extends AbstractTableModel { } @Override - public Class getColumnClass(int columnIndex){ + public Class getColumnClass(int columnIndex) { switch (columnIndex) { case COLUMN_ICON: return Icon.class; @@ -1410,7 +1403,8 @@ class UpdateTablesTask extends SwingWorker> { get(); } catch (InterruptedException | ExecutionException ex) { logger.fatal("Update Tables Task error", ex); - } catch (CancellationException ex) {} + } catch (CancellationException ex) { + } } } @@ -1449,7 +1443,8 @@ class UpdatePlayersTask extends SwingWorker> { get(); } catch (InterruptedException | ExecutionException ex) { logger.fatal("Update Players Task error", ex); - } catch (CancellationException ex) {} + } catch (CancellationException ex) { + } } } @@ -1458,7 +1453,7 @@ class MatchesTableModel extends AbstractTableModel { public static final int ACTION_COLUMN = 6; // column the action is located (starting with 0) public static final int GAMES_LIST_COLUMN = 7; - private final String[] columnNames = new String[]{"Deck Type", "Players", "Game Type", "Result", "Start Time", "End Time","Action"}; + private final String[] columnNames = new String[]{"Deck Type", "Players", "Game Type", "Result", "Start Time", "End Time", "Action"}; private MatchView[] matches = new MatchView[0]; private static final DateFormat timeFormatter = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); @@ -1509,30 +1504,29 @@ class MatchesTableModel extends AbstractTableModel { } else { return "None"; } - } + } case 7: return matches[arg0].getGames(); } return ""; } - - public List getListofGames (int row) { - return matches[row].getGames(); + + public List getListofGames(int row) { + return matches[row].getGames(); } - + public boolean isTournament(int row) { - return matches[row].isTournament(); + return matches[row].isTournament(); } public UUID getMatchId(int row) { - return matches[row].getMatchId(); + return matches[row].getMatchId(); } - + public UUID getTableId(int row) { - return matches[row].getTableId(); + return matches[row].getTableId(); } - - + @Override public String getColumnName(int columnIndex) { String colName = ""; @@ -1545,7 +1539,7 @@ class MatchesTableModel extends AbstractTableModel { } @Override - public Class getColumnClass(int columnIndex){ + public Class getColumnClass(int columnIndex) { return String.class; } @@ -1593,7 +1587,8 @@ class UpdateMatchesTask extends SwingWorker> { get(); } catch (InterruptedException | ExecutionException ex) { logger.fatal("Update Matches Task error", ex); - } catch (CancellationException ex) {} + } catch (CancellationException ex) { + } } } @@ -1611,7 +1606,7 @@ class GameChooser extends JPopupMenu { return; } this.removeAll(); - for (UUID gameId: games) { + for (UUID gameId : games) { this.add(new GameChooserAction(gameId, gameId.toString())); } this.show(MageFrame.getDesktop(), p.x, p.y); From 17d6fc327f67bd71547406d1202c79e9484a3874 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Wed, 5 Aug 2015 07:34:29 +0300 Subject: [PATCH 12/24] Remove SetCardColorSourceEffect and use BecomesColorSourceEffect instead --- .../mage/sets/odyssey/RepentantVampire.java | 4 +- .../src/mage/sets/odyssey/WaywardAngel.java | 10 +- .../sets/timespiral/BlazingBladeAskari.java | 8 +- .../continuous/SetCardColorSourceEffect.java | 101 ------------------ 4 files changed, 11 insertions(+), 112 deletions(-) delete mode 100644 Mage/src/mage/abilities/effects/common/continuous/SetCardColorSourceEffect.java diff --git a/Mage.Sets/src/mage/sets/odyssey/RepentantVampire.java b/Mage.Sets/src/mage/sets/odyssey/RepentantVampire.java index 33480b005c4..c2062edc5ef 100644 --- a/Mage.Sets/src/mage/sets/odyssey/RepentantVampire.java +++ b/Mage.Sets/src/mage/sets/odyssey/RepentantVampire.java @@ -38,8 +38,8 @@ import mage.abilities.condition.common.CardsInControllerGraveCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.effects.common.continuous.SetCardColorSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -77,7 +77,7 @@ public class RepentantVampire extends CardImpl { this.addAbility(new DiesAndDealtDamageThisTurnTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false)); // Threshold - As long as seven or more cards are in your graveyard, Repentant Vampire is white and has "{tap}: Destroy target black creature." Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( - new SetCardColorSourceEffect(ObjectColor.WHITE, Duration.WhileOnBattlefield), + new BecomesColorSourceEffect(ObjectColor.WHITE, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), "Threshold - As long as seven or more cards are in your graveyard, {this} is white")); Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost()); diff --git a/Mage.Sets/src/mage/sets/odyssey/WaywardAngel.java b/Mage.Sets/src/mage/sets/odyssey/WaywardAngel.java index f73fe6f3e36..0c65b84ddad 100644 --- a/Mage.Sets/src/mage/sets/odyssey/WaywardAngel.java +++ b/Mage.Sets/src/mage/sets/odyssey/WaywardAngel.java @@ -36,9 +36,9 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.CardsInControllerGraveCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.SacrificeControllerEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.effects.common.continuous.SetCardColorSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.VigilanceAbility; @@ -75,21 +75,21 @@ public class WaywardAngel extends CardImpl { new CardsInControllerGraveCondition(7), "Threshold - As long as seven or more cards are in your graveyard, {this} gets +3/+3,")); ability.addEffect(new ConditionalContinuousEffect( - new SetCardColorSourceEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield), + new BecomesColorSourceEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), " is black,")); ability.addEffect(new ConditionalContinuousEffect( new GainAbilitySourceEffect(TrampleAbility.getInstance()), new CardsInControllerGraveCondition(7), " has trample,")); - + Ability gainedAbility = new BeginningOfUpkeepTriggeredAbility(new SacrificeControllerEffect(new FilterControlledCreaturePermanent(), 1, ""), TargetController.YOU, false); - + ability.addEffect(new ConditionalContinuousEffect( new GainAbilitySourceEffect(gainedAbility), new CardsInControllerGraveCondition(7), " and has \"At the beginning of your upkeep, sacrifice a creature.\" ")); - + this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/timespiral/BlazingBladeAskari.java b/Mage.Sets/src/mage/sets/timespiral/BlazingBladeAskari.java index de158ab2596..d20676a6e54 100644 --- a/Mage.Sets/src/mage/sets/timespiral/BlazingBladeAskari.java +++ b/Mage.Sets/src/mage/sets/timespiral/BlazingBladeAskari.java @@ -29,16 +29,16 @@ package mage.sets.timespiral; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.continuous.SetCardColorSourceEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; import mage.abilities.keyword.FlankingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Rarity; import mage.constants.Zone; /** @@ -59,7 +59,7 @@ public class BlazingBladeAskari extends CardImpl { // Flanking this.addAbility(new FlankingAbility()); // {2}: Blazing Blade Askari becomes colorless until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SetCardColorSourceEffect(new ObjectColor(""), Duration.EndOfTurn), new ManaCostsImpl("{2}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesColorSourceEffect(new ObjectColor(), Duration.EndOfTurn), new ManaCostsImpl("{2}"))); } public BlazingBladeAskari(final BlazingBladeAskari card) { diff --git a/Mage/src/mage/abilities/effects/common/continuous/SetCardColorSourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/SetCardColorSourceEffect.java deleted file mode 100644 index e45ed9f9a42..00000000000 --- a/Mage/src/mage/abilities/effects/common/continuous/SetCardColorSourceEffect.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - * - */ - -package mage.abilities.effects.common.continuous; - -import mage.MageObject; -import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.Mode; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.game.stack.StackObject; - - -/** - * - * @author nicolas.perrenou - */ - - -public class SetCardColorSourceEffect extends ContinuousEffectImpl { - - private ObjectColor setColor; - - public SetCardColorSourceEffect(ObjectColor setColor, Duration duration, String text) { - super(duration, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Benefit); - this.setColor = setColor; - staticText = text; - } - - public SetCardColorSourceEffect(ObjectColor setColor, Duration duration) { - super(duration, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Benefit); - this.setColor = setColor; - } - - public SetCardColorSourceEffect(final SetCardColorSourceEffect effect) { - super(effect); - this.setColor = effect.setColor; - } - - @Override - public boolean apply(Game game, Ability source) { - MageObject o = game.getObject(source.getSourceId()); - if (o != null) { - if (o instanceof Permanent || o instanceof StackObject) { - o.getColor(game).setColor(setColor); - } - } - - return false; - } - - @Override - public SetCardColorSourceEffect copy() { - return new SetCardColorSourceEffect(this); - } - - @Override - public String getText(Mode mode) { - StringBuilder sb = new StringBuilder(); - sb.append("{this} "); - if (mode.getTargets().size() > 0) { - sb.append(mode.getTargets().get(0).getTargetName()); - } - sb.append(" becomes ").append(setColor.getDescription()); - sb.append(" ").append(duration.toString()); - return sb.toString(); - } -} From e9a72577031280733686cc715230fe3813c2ff5e Mon Sep 17 00:00:00 2001 From: LoneFox Date: Wed, 5 Aug 2015 07:51:23 +0300 Subject: [PATCH 13/24] Move DealsDamageToOpponentTriggeredAbility out of effects directory It is obviously an ability and not an effect... --- .../src/mage/sets/alarareborn/VedalkenHeretic.java | 4 ++-- Mage.Sets/src/mage/sets/apocalypse/FungalShambler.java | 2 +- .../src/mage/sets/avacynrestored/TandemLookout.java | 2 +- Mage.Sets/src/mage/sets/commander/HydraOmnivore.java | 2 +- .../mage/sets/commander2013/LuXunScholarGeneral.java | 2 +- Mage.Sets/src/mage/sets/conflux/CharnelhoardWurm.java | 6 +++--- .../src/mage/sets/fatereforged/MindscourDragon.java | 4 ++-- Mage.Sets/src/mage/sets/legends/NicolBolas.java | 4 ++-- Mage.Sets/src/mage/sets/magic2010/HypnoticSpecter.java | 8 ++++---- .../src/mage/sets/ninthedition/ThievingMagpie.java | 6 +++--- .../src/mage/sets/riseoftheeldrazi/SnakeUmbra.java | 10 +++++----- .../src/mage/sets/shadowmoor/WitherscaleWurm.java | 2 +- Mage.Sets/src/mage/sets/timespiral/LooterIlKor.java | 6 +++--- .../common/DealsDamageToOpponentTriggeredAbility.java | 4 ++-- 14 files changed, 31 insertions(+), 31 deletions(-) rename Mage/src/mage/abilities/{effects => }/common/DealsDamageToOpponentTriggeredAbility.java (98%) diff --git a/Mage.Sets/src/mage/sets/alarareborn/VedalkenHeretic.java b/Mage.Sets/src/mage/sets/alarareborn/VedalkenHeretic.java index 5b8f0d526ab..0a1d61f2124 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/VedalkenHeretic.java +++ b/Mage.Sets/src/mage/sets/alarareborn/VedalkenHeretic.java @@ -29,7 +29,7 @@ package mage.sets.alarareborn; import java.util.UUID; import mage.MageInt; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -54,7 +54,7 @@ public class VedalkenHeretic extends CardImpl { // Whenever Vedalken Heretic deals damage to an opponent, you may draw a card. this.addAbility(new DealsDamageToOpponentTriggeredAbility(new DrawCardSourceControllerEffect(1), true)); - + } public VedalkenHeretic(final VedalkenHeretic card) { diff --git a/Mage.Sets/src/mage/sets/apocalypse/FungalShambler.java b/Mage.Sets/src/mage/sets/apocalypse/FungalShambler.java index e8f9d48bd5d..385de243c2c 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/FungalShambler.java +++ b/Mage.Sets/src/mage/sets/apocalypse/FungalShambler.java @@ -30,8 +30,8 @@ package mage.sets.apocalypse; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.keyword.TrampleAbility; diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java b/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java index 255339d3844..a2cec673f68 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java @@ -30,8 +30,8 @@ package mage.sets.avacynrestored; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.GainAbilityPairedEffect; import mage.abilities.keyword.SoulbondAbility; diff --git a/Mage.Sets/src/mage/sets/commander/HydraOmnivore.java b/Mage.Sets/src/mage/sets/commander/HydraOmnivore.java index dd8d6c6eb69..fea88abc3d2 100644 --- a/Mage.Sets/src/mage/sets/commander/HydraOmnivore.java +++ b/Mage.Sets/src/mage/sets/commander/HydraOmnivore.java @@ -31,8 +31,8 @@ import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; diff --git a/Mage.Sets/src/mage/sets/commander2013/LuXunScholarGeneral.java b/Mage.Sets/src/mage/sets/commander2013/LuXunScholarGeneral.java index 32ea1712b71..e8e4489d913 100644 --- a/Mage.Sets/src/mage/sets/commander2013/LuXunScholarGeneral.java +++ b/Mage.Sets/src/mage/sets/commander2013/LuXunScholarGeneral.java @@ -29,7 +29,7 @@ package mage.sets.commander2013; import java.util.UUID; import mage.MageInt; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.keyword.HorsemanshipAbility; import mage.cards.CardImpl; diff --git a/Mage.Sets/src/mage/sets/conflux/CharnelhoardWurm.java b/Mage.Sets/src/mage/sets/conflux/CharnelhoardWurm.java index 983fccfc748..7356e7d86ab 100644 --- a/Mage.Sets/src/mage/sets/conflux/CharnelhoardWurm.java +++ b/Mage.Sets/src/mage/sets/conflux/CharnelhoardWurm.java @@ -28,14 +28,14 @@ package mage.sets.conflux; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.target.common.TargetCardInYourGraveyard; /** diff --git a/Mage.Sets/src/mage/sets/fatereforged/MindscourDragon.java b/Mage.Sets/src/mage/sets/fatereforged/MindscourDragon.java index 6e4002d8703..919fef0d1c8 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/MindscourDragon.java +++ b/Mage.Sets/src/mage/sets/fatereforged/MindscourDragon.java @@ -30,7 +30,7 @@ package mage.sets.fatereforged; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -53,7 +53,7 @@ public class MindscourDragon extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // Whenever Mindscour Dragon deals combat damage to an opponent, target player puts the top four cards of his or her library into his or her graveyard. Ability ability = new DealsDamageToOpponentTriggeredAbility(new PutLibraryIntoGraveTargetEffect(4), false, true); ability.addTarget(new TargetPlayer()); diff --git a/Mage.Sets/src/mage/sets/legends/NicolBolas.java b/Mage.Sets/src/mage/sets/legends/NicolBolas.java index 55a7c2b4ab2..8bf534631e0 100644 --- a/Mage.Sets/src/mage/sets/legends/NicolBolas.java +++ b/Mage.Sets/src/mage/sets/legends/NicolBolas.java @@ -30,8 +30,8 @@ package mage.sets.legends; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; import mage.abilities.effects.common.discard.DiscardHandTargetEffect; import mage.abilities.keyword.FlyingAbility; @@ -60,7 +60,7 @@ public class NicolBolas extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // At the beginning of your upkeep, sacrifice Nicol Bolas unless you pay {U}{B}{R}. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{U}{B}{R}")), TargetController.YOU, false)); - + // Whenever Nicol Bolas deals damage to an opponent, that player discards his or her hand. this.addAbility(new DealsDamageToOpponentTriggeredAbility(new DiscardHandTargetEffect("that player"), false)); } diff --git a/Mage.Sets/src/mage/sets/magic2010/HypnoticSpecter.java b/Mage.Sets/src/mage/sets/magic2010/HypnoticSpecter.java index c72c755c858..e120011e380 100644 --- a/Mage.Sets/src/mage/sets/magic2010/HypnoticSpecter.java +++ b/Mage.Sets/src/mage/sets/magic2010/HypnoticSpecter.java @@ -27,13 +27,13 @@ */ package mage.sets.magic2010; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import java.util.UUID; @@ -65,4 +65,4 @@ public class HypnoticSpecter extends CardImpl { public HypnoticSpecter copy() { return new HypnoticSpecter(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/ninthedition/ThievingMagpie.java b/Mage.Sets/src/mage/sets/ninthedition/ThievingMagpie.java index e77fb511118..7f6ac26f06c 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/ThievingMagpie.java +++ b/Mage.Sets/src/mage/sets/ninthedition/ThievingMagpie.java @@ -28,13 +28,13 @@ package mage.sets.ninthedition; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/SnakeUmbra.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/SnakeUmbra.java index 5daad05f235..2c50e5be6e6 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/SnakeUmbra.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/SnakeUmbra.java @@ -29,18 +29,18 @@ package mage.sets.riseoftheeldrazi; import java.util.UUID; -import mage.constants.*; import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TotemArmorAbility; import mage.cards.CardImpl; +import mage.constants.*; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -61,17 +61,17 @@ public class SnakeUmbra extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Enchanted creature gets +1/+1 ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield)); - + // and has "Whenever this creature deals damage to an opponent, you may draw a card." Ability gainedAbility = new DealsDamageToOpponentTriggeredAbility(new DrawCardSourceControllerEffect(1), true); Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA); effect.setText("and has \"Whenever this creature deals damage to an opponent, you may draw a card.\""); ability.addEffect(effect); this.addAbility(ability); - + // Totem armor this.addAbility(new TotemArmorAbility()); } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/WitherscaleWurm.java b/Mage.Sets/src/mage/sets/shadowmoor/WitherscaleWurm.java index 505fab69390..bc3e1f3d06c 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/WitherscaleWurm.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/WitherscaleWurm.java @@ -31,9 +31,9 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.WitherAbility; import mage.cards.CardImpl; diff --git a/Mage.Sets/src/mage/sets/timespiral/LooterIlKor.java b/Mage.Sets/src/mage/sets/timespiral/LooterIlKor.java index 50d92657baf..967e8f78d3f 100644 --- a/Mage.Sets/src/mage/sets/timespiral/LooterIlKor.java +++ b/Mage.Sets/src/mage/sets/timespiral/LooterIlKor.java @@ -28,13 +28,13 @@ package mage.sets.timespiral; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; -import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.keyword.ShadowAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * diff --git a/Mage/src/mage/abilities/effects/common/DealsDamageToOpponentTriggeredAbility.java b/Mage/src/mage/abilities/common/DealsDamageToOpponentTriggeredAbility.java similarity index 98% rename from Mage/src/mage/abilities/effects/common/DealsDamageToOpponentTriggeredAbility.java rename to Mage/src/mage/abilities/common/DealsDamageToOpponentTriggeredAbility.java index aa25f2b6e83..2641d757ed9 100644 --- a/Mage/src/mage/abilities/effects/common/DealsDamageToOpponentTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/DealsDamageToOpponentTriggeredAbility.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ -package mage.abilities.effects.common; +package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -46,7 +46,7 @@ public class DealsDamageToOpponentTriggeredAbility extends TriggeredAbilityImpl public DealsDamageToOpponentTriggeredAbility(Effect effect) { this(effect, false, false); } - + public DealsDamageToOpponentTriggeredAbility(Effect effect, boolean optional) { this(effect, optional, false); } From 3991ce08e52d3a62b2d2e6350f7a7e58b489f329 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Wed, 5 Aug 2015 09:03:38 +0300 Subject: [PATCH 14/24] Generalize PutCreatureOnBattlefieldEffect -> PutPermanentOnBattlefieldEffect --- .../src/mage/sets/apocalypse/DragonArch.java | 4 +- .../src/mage/sets/magic2010/ElvishPiper.java | 15 ++-- .../sets/magic2012/QuicksilverAmulet.java | 5 +- .../src/mage/sets/nemesis/BelbesPortal.java | 72 +++---------------- ...a => PutPermanentOnBattlefieldEffect.java} | 23 +++--- 5 files changed, 35 insertions(+), 84 deletions(-) rename Mage/src/mage/abilities/effects/common/{PutCreatureOnBattlefieldEffect.java => PutPermanentOnBattlefieldEffect.java} (67%) diff --git a/Mage.Sets/src/mage/sets/apocalypse/DragonArch.java b/Mage.Sets/src/mage/sets/apocalypse/DragonArch.java index ebf26f8065c..60fe65ac0ee 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/DragonArch.java +++ b/Mage.Sets/src/mage/sets/apocalypse/DragonArch.java @@ -32,7 +32,7 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutCreatureOnBattlefieldEffect; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; @@ -58,7 +58,7 @@ public class DragonArch extends CardImpl { this.expansionSetCode = "APC"; // {2}, {T}: You may put a multicolored creature card from your hand onto the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCreatureOnBattlefieldEffect(filter), + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter), new ManaCostsImpl("{2}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/magic2010/ElvishPiper.java b/Mage.Sets/src/mage/sets/magic2010/ElvishPiper.java index c29ae7ffdd7..2ce8555a73b 100644 --- a/Mage.Sets/src/mage/sets/magic2010/ElvishPiper.java +++ b/Mage.Sets/src/mage/sets/magic2010/ElvishPiper.java @@ -27,17 +27,18 @@ */ package mage.sets.magic2010; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; + +import java.util.UUID; import mage.MageInt; -import mage.abilities.effects.common.PutCreatureOnBattlefieldEffect; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.cards.CardImpl; - -import java.util.UUID; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; /** * @@ -56,7 +57,7 @@ public class ElvishPiper extends CardImpl { // {G}, {tap}: You may put a creature card from your hand onto the battlefield. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCreatureOnBattlefieldEffect(), + new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/magic2012/QuicksilverAmulet.java b/Mage.Sets/src/mage/sets/magic2012/QuicksilverAmulet.java index c220e08f282..5789dcd3403 100644 --- a/Mage.Sets/src/mage/sets/magic2012/QuicksilverAmulet.java +++ b/Mage.Sets/src/mage/sets/magic2012/QuicksilverAmulet.java @@ -30,11 +30,12 @@ package mage.sets.magic2012; import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; -import mage.abilities.effects.common.PutCreatureOnBattlefieldEffect; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.cards.CardImpl; +import mage.filter.common.FilterCreatureCard; import java.util.UUID; @@ -50,7 +51,7 @@ public class QuicksilverAmulet extends CardImpl { // {4}, {tap}: You may put a creature card from your hand onto the battlefield. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCreatureOnBattlefieldEffect(), + new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), new ManaCostsImpl("{4}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java b/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java index 5b3e8c7cb73..8a6bd9a80f4 100644 --- a/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java +++ b/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java @@ -34,24 +34,15 @@ import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseCreatureTypeEffect; -import mage.abilities.effects.common.PutCreatureOnBattlefieldEffect; -import mage.cards.Card; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; +import mage.filter.predicate.mageobject.ChosenSubtypePredicate; /** * @@ -66,8 +57,10 @@ public class BelbesPortal extends CardImpl { // As Belbe's Portal enters the battlefield, choose a creature type. this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.PutCreatureInPlay))); // {3}, {tap}: You may put a creature card of the chosen type from your hand onto the battlefield. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new BelbesPortalPutCreatureOnBattlefieldEffect(), + FilterCreatureCard filter = new FilterCreatureCard("a creature card of the chosen type"); + filter.add(new ChosenSubtypePredicate(this.getId())); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PutPermanentOnBattlefieldEffect(filter), new ManaCostsImpl("{3}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); @@ -82,48 +75,3 @@ public class BelbesPortal extends CardImpl { return new BelbesPortal(this); } } - -class BelbesPortalPutCreatureOnBattlefieldEffect extends OneShotEffect { - BelbesPortalPutCreatureOnBattlefieldEffect() { - super(Outcome.PutCreatureInPlay); - staticText = "You may put a creature card of the chosen type from your hand onto the battlefield"; - } - - BelbesPortalPutCreatureOnBattlefieldEffect(final BelbesPortalPutCreatureOnBattlefieldEffect effect) { - super(effect); - } - - @Override - public BelbesPortalPutCreatureOnBattlefieldEffect copy() { - return new BelbesPortalPutCreatureOnBattlefieldEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { - String subtype = (String) game.getState().getValue(permanent.getId() + "_type"); - if (subtype != null) { - Player player = game.getPlayer(source.getControllerId()); - String choiceText = "Put a " + subtype.toLowerCase() + " creature card from your hand onto the battlefield?"; - - if (player != null) { - if (player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { - FilterCreatureCard creatureTypeFilter = new FilterCreatureCard(); - creatureTypeFilter.add(new SubtypePredicate(subtype)); - - TargetCardInHand target = new TargetCardInHand(creatureTypeFilter); - if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } - } - } - return true; - } - } - } - return false; - } -} \ No newline at end of file diff --git a/Mage/src/mage/abilities/effects/common/PutCreatureOnBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java similarity index 67% rename from Mage/src/mage/abilities/effects/common/PutCreatureOnBattlefieldEffect.java rename to Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java index 822c21199bb..254566a4cd9 100644 --- a/Mage/src/mage/abilities/effects/common/PutCreatureOnBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java @@ -6,7 +6,8 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; +import mage.filter.FilterCard; +import mage.filter.common.FilterPermanentCard; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; @@ -14,34 +15,34 @@ import mage.target.common.TargetCardInHand; /** * @author magenoxx_at_gmail.com */ -public class PutCreatureOnBattlefieldEffect extends OneShotEffect { +public class PutPermanentOnBattlefieldEffect extends OneShotEffect { - private final FilterCreatureCard filter; + private final FilterCard filter; - public PutCreatureOnBattlefieldEffect() { - this(new FilterCreatureCard("a creature card")); + public PutPermanentOnBattlefieldEffect() { + this(new FilterPermanentCard("a permanent card")); } - public PutCreatureOnBattlefieldEffect(FilterCreatureCard filter) { - super(Outcome.PutCreatureInPlay); + public PutPermanentOnBattlefieldEffect(FilterCard filter) { + super(Outcome.PutCardInPlay); this.filter = filter; } - public PutCreatureOnBattlefieldEffect(final PutCreatureOnBattlefieldEffect effect) { + public PutPermanentOnBattlefieldEffect(final PutPermanentOnBattlefieldEffect effect) { super(effect); this.filter = effect.filter.copy(); } @Override - public PutCreatureOnBattlefieldEffect copy() { - return new PutCreatureOnBattlefieldEffect(this); + public PutPermanentOnBattlefieldEffect copy() { + return new PutPermanentOnBattlefieldEffect(this); } @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); String choiceText = "Put " + filter.getMessage() + " from your hand onto the battlefield?"; - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { + if (player == null || !player.chooseUse(Outcome.PutCardInPlay, choiceText, source, game)) { return false; } From bb8b030592c479da524acbf72c8ae9ebdac2db55 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Wed, 5 Aug 2015 09:58:11 +0300 Subject: [PATCH 15/24] Implement cards: Anaba Ancestor, Anaba Spirit Crafter, and Didgeridoo --- .../mage/sets/homelands/AnabaAncestor.java | 81 +++++++++++++++++++ .../sets/homelands/AnabaSpiritCrafter.java | 74 +++++++++++++++++ .../src/mage/sets/homelands/Didgeridoo.java | 69 ++++++++++++++++ .../sets/masterseditioniii/AnabaAncestor.java | 54 +++++++++++++ .../masterseditioniii/AnabaSpiritCrafter.java | 54 +++++++++++++ .../sets/masterseditioniii/Didgeridoo.java | 54 +++++++++++++ 6 files changed, 386 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/homelands/AnabaAncestor.java create mode 100644 Mage.Sets/src/mage/sets/homelands/AnabaSpiritCrafter.java create mode 100644 Mage.Sets/src/mage/sets/homelands/Didgeridoo.java create mode 100644 Mage.Sets/src/mage/sets/masterseditioniii/AnabaAncestor.java create mode 100644 Mage.Sets/src/mage/sets/masterseditioniii/AnabaSpiritCrafter.java create mode 100644 Mage.Sets/src/mage/sets/masterseditioniii/Didgeridoo.java diff --git a/Mage.Sets/src/mage/sets/homelands/AnabaAncestor.java b/Mage.Sets/src/mage/sets/homelands/AnabaAncestor.java new file mode 100644 index 00000000000..5074961e95d --- /dev/null +++ b/Mage.Sets/src/mage/sets/homelands/AnabaAncestor.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.homelands; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class AnabaAncestor extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Another target Minotaur creature"); + + static { + filter.add(new SubtypePredicate("Minotaur")); + filter.add(new AnotherPredicate()); + } + + public AnabaAncestor(UUID ownerId) { + super(ownerId, 81, "Anaba Ancestor", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "HML"; + this.subtype.add("Minotaur"); + this.subtype.add("Spirit"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {T}: Another target Minotaur creature gets +1/+1 until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public AnabaAncestor(final AnabaAncestor card) { + super(card); + } + + @Override + public AnabaAncestor copy() { + return new AnabaAncestor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/homelands/AnabaSpiritCrafter.java b/Mage.Sets/src/mage/sets/homelands/AnabaSpiritCrafter.java new file mode 100644 index 00000000000..53536b05900 --- /dev/null +++ b/Mage.Sets/src/mage/sets/homelands/AnabaSpiritCrafter.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.homelands; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LoneFox + */ +public class AnabaSpiritCrafter extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Minotaur creatures"); + + static { + filter.add(new SubtypePredicate("Minotaur")); + } + + public AnabaSpiritCrafter(UUID ownerId) { + super(ownerId, 86, "Anaba Spirit Crafter", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + this.expansionSetCode = "HML"; + this.subtype.add("Minotaur"); + this.subtype.add("Shaman"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Minotaur creatures get +1/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 0, Duration.WhileOnBattlefield, filter, false))); + } + + public AnabaSpiritCrafter(final AnabaSpiritCrafter card) { + super(card); + } + + @Override + public AnabaSpiritCrafter copy() { + return new AnabaSpiritCrafter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/homelands/Didgeridoo.java b/Mage.Sets/src/mage/sets/homelands/Didgeridoo.java new file mode 100644 index 00000000000..96609bf2e04 --- /dev/null +++ b/Mage.Sets/src/mage/sets/homelands/Didgeridoo.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.homelands; + +import java.util.UUID; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterPermanentCard; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LoneFox + */ +public class Didgeridoo extends CardImpl { + + private static final FilterPermanentCard filter = new FilterPermanentCard("a Minotaur permanent card"); + + static { + filter.add(new SubtypePredicate("Minotaur")); + } + + public Didgeridoo(UUID ownerId) { + super(ownerId, 130, "Didgeridoo", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "HML"; + + // {3}: You may put a Minotaur permanent card from your hand onto the battlefield. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter), new ManaCostsImpl("{3}"))); + } + + public Didgeridoo(final Didgeridoo card) { + super(card); + } + + @Override + public Didgeridoo copy() { + return new Didgeridoo(this); + } +} diff --git a/Mage.Sets/src/mage/sets/masterseditioniii/AnabaAncestor.java b/Mage.Sets/src/mage/sets/masterseditioniii/AnabaAncestor.java new file mode 100644 index 00000000000..be8739bea49 --- /dev/null +++ b/Mage.Sets/src/mage/sets/masterseditioniii/AnabaAncestor.java @@ -0,0 +1,54 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.masterseditioniii; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + */ +public class AnabaAncestor extends mage.sets.homelands.AnabaAncestor { + + public AnabaAncestor(UUID ownerId) { + super(ownerId); + this.cardNumber = 86; + this.expansionSetCode = "ME3"; + this.rarity = Rarity.COMMON; + } + + public AnabaAncestor(final AnabaAncestor card) { + super(card); + } + + @Override + public AnabaAncestor copy() { + return new AnabaAncestor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/masterseditioniii/AnabaSpiritCrafter.java b/Mage.Sets/src/mage/sets/masterseditioniii/AnabaSpiritCrafter.java new file mode 100644 index 00000000000..c4168cb5a36 --- /dev/null +++ b/Mage.Sets/src/mage/sets/masterseditioniii/AnabaSpiritCrafter.java @@ -0,0 +1,54 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.masterseditioniii; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + */ +public class AnabaSpiritCrafter extends mage.sets.homelands.AnabaSpiritCrafter { + + public AnabaSpiritCrafter(UUID ownerId) { + super(ownerId); + this.cardNumber = 87; + this.expansionSetCode = "ME3"; + this.rarity = Rarity.COMMON; + } + + public AnabaSpiritCrafter(final AnabaSpiritCrafter card) { + super(card); + } + + @Override + public AnabaSpiritCrafter copy() { + return new AnabaSpiritCrafter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/masterseditioniii/Didgeridoo.java b/Mage.Sets/src/mage/sets/masterseditioniii/Didgeridoo.java new file mode 100644 index 00000000000..21531411cb9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/masterseditioniii/Didgeridoo.java @@ -0,0 +1,54 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.masterseditioniii; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + */ +public class Didgeridoo extends mage.sets.homelands.Didgeridoo { + + public Didgeridoo(UUID ownerId) { + super(ownerId); + this.cardNumber = 194; + this.expansionSetCode = "ME3"; + this.rarity = Rarity.UNCOMMON; + } + + public Didgeridoo(final Didgeridoo card) { + super(card); + } + + @Override + public Didgeridoo copy() { + return new Didgeridoo(this); + } +} From 5fdc56352e9930c381347ef557bf954f52fbb17f Mon Sep 17 00:00:00 2001 From: LoneFox Date: Wed, 5 Aug 2015 11:03:18 +0300 Subject: [PATCH 16/24] Refactor a few cards to use PutPermanentOnBattlefieldEffect instead of custom effects --- .../mage/sets/conflux/MasterTransmuter.java | 51 ++--------- .../mage/sets/eventide/MindwrackLiege.java | 66 ++------------ .../src/mage/sets/urzassaga/GoblinLackey.java | 90 ++----------------- .../mage/sets/worldwake/StoneforgeMystic.java | 66 ++------------ 4 files changed, 29 insertions(+), 244 deletions(-) diff --git a/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java b/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java index 98fb20c1ff8..fcae2dcac52 100644 --- a/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java +++ b/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java @@ -28,25 +28,19 @@ package mage.sets.conflux; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ReturnToHandTargetPermanentCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInHand; import mage.target.common.TargetControlledPermanent; /** @@ -65,7 +59,7 @@ public class MasterTransmuter extends CardImpl { this.toughness = new MageInt(2); // {U}, {tap}, Return an artifact you control to its owner's hand: You may put an artifact card from your hand onto the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MasterTransmuterEffect(), new ManaCostsImpl("{U}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(new FilterArtifactCard("an artifact card")), new ManaCostsImpl("{U}")); ability.addCost(new TapSourceCost()); ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); this.addAbility(ability); @@ -81,38 +75,3 @@ public class MasterTransmuter extends CardImpl { return new MasterTransmuter(this); } } - -class MasterTransmuterEffect extends OneShotEffect { - - public MasterTransmuterEffect() { - super(Outcome.Benefit); - this.staticText = "You may put an artifact card from your hand onto the battlefield"; - } - - public MasterTransmuterEffect(final MasterTransmuterEffect effect) { - super(effect); - } - - @Override - public MasterTransmuterEffect copy() { - return new MasterTransmuterEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Target target = new TargetCardInHand(new FilterArtifactCard("an artifact card from your hand")); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && controller.chooseUse(outcome, "Put an artifact from your hand to battlefield?", source, game) - && controller.chooseTarget(outcome, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } - } - } - - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java b/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java index eda9db62341..f0d5714b775 100644 --- a/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java +++ b/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java @@ -30,17 +30,14 @@ package mage.sets.eventide; import java.util.UUID; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; @@ -49,9 +46,6 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCardInHand; /** * @@ -59,15 +53,17 @@ import mage.target.common.TargetCardInHand; */ public class MindwrackLiege extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue creatures you control"); private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("red creatures you control"); + private static final FilterCreatureCard filter3 = new FilterCreatureCard("a blue or red creature card"); + static { filter.add(new ColorPredicate(ObjectColor.BLUE)); filter.add(new ControllerPredicate(TargetController.YOU)); - filter2.add(new ColorPredicate(ObjectColor.RED)); filter2.add(new ControllerPredicate(TargetController.YOU)); + filter3.add(Predicates.or(new ColorPredicate(ObjectColor.BLUE), new ColorPredicate(ObjectColor.RED))); } public MindwrackLiege(UUID ownerId) { @@ -80,13 +76,12 @@ public class MindwrackLiege extends CardImpl { // Other blue creatures you control get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); - + // Other red creatures you control get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter2, true))); - + // {UR}{UR}{UR}{UR}: You may put a blue or red creature card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new MindwrackLiegeEffect(), new ManaCostsImpl("{U/R}{U/R}{U/R}{U/R}"))); - + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter3), new ManaCostsImpl("{U/R}{U/R}{U/R}{U/R}"))); } public MindwrackLiege(final MindwrackLiege card) { @@ -98,48 +93,3 @@ public class MindwrackLiege extends CardImpl { return new MindwrackLiege(this); } } - -class MindwrackLiegeEffect extends OneShotEffect { - - private static final String choiceText = "Put a blue or red creature card from your hand onto the battlefield?"; - - private static final FilterCreatureCard filter = new FilterCreatureCard("a blue or red creature card"); - - static { - filter.add(Predicates.or( - new ColorPredicate(ObjectColor.BLUE), - new ColorPredicate(ObjectColor.RED))); - } - - public MindwrackLiegeEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "You may put a blue or red creature card from your hand onto the battlefield"; - } - - public MindwrackLiegeEffect(final MindwrackLiegeEffect effect) { - super(effect); - } - - @Override - public MindwrackLiegeEffect copy() { - return new MindwrackLiegeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { - return false; - } - - TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/urzassaga/GoblinLackey.java b/Mage.Sets/src/mage/sets/urzassaga/GoblinLackey.java index f4f44011f6f..282a8788916 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/GoblinLackey.java +++ b/Mage.Sets/src/mage/sets/urzassaga/GoblinLackey.java @@ -29,22 +29,13 @@ package mage.sets.urzassaga; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; -import mage.target.common.TargetCardInHand; /** * @@ -52,6 +43,12 @@ import mage.target.common.TargetCardInHand; */ public class GoblinLackey extends CardImpl { + private static final FilterPermanentCard filter = new FilterPermanentCard("a Goblin permanent card"); + + static { + filter.add(new SubtypePredicate("Goblin")); + } + public GoblinLackey(UUID ownerId) { super(ownerId, 190, "Goblin Lackey", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{R}"); this.expansionSetCode = "USG"; @@ -61,7 +58,7 @@ public class GoblinLackey extends CardImpl { this.toughness = new MageInt(1); // Whenever Goblin Lackey deals damage to a player, you may put a Goblin permanent card from your hand onto the battlefield. - this.addAbility(new GoblinLackeyTriggeredAbility()); + this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new PutPermanentOnBattlefieldEffect(filter), false)); } public GoblinLackey(final GoblinLackey card) { @@ -73,72 +70,3 @@ public class GoblinLackey extends CardImpl { return new GoblinLackey(this); } } - -class GoblinLackeyTriggeredAbility extends TriggeredAbilityImpl { - - public GoblinLackeyTriggeredAbility() { - super(Zone.BATTLEFIELD, new GoblinLackeyEffect(), true); - } - - public GoblinLackeyTriggeredAbility(final GoblinLackeyTriggeredAbility ability) { - super(ability); - } - - @Override - public GoblinLackeyTriggeredAbility copy() { - return new GoblinLackeyTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - return event.getSourceId().equals(this.sourceId) - && game.getOpponents(this.getControllerId()).contains(event.getTargetId()); - } - - @Override - public String getRule() { - return "Whenever {this} deals damage to an opponent, you may put a Goblin permanent card from your hand onto the battlefield."; - } -} - -class GoblinLackeyEffect extends OneShotEffect { - - public GoblinLackeyEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "you may put a Goblin permanent card from your hand onto the battlefield"; - } - - public GoblinLackeyEffect(final GoblinLackeyEffect effect) { - super(effect); - } - - @Override - public GoblinLackeyEffect copy() { - return new GoblinLackeyEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - FilterPermanentCard filter = new FilterPermanentCard("Goblin permanent card from your hand"); - filter.add(new SubtypePredicate("Goblin")); - TargetCardInHand target = new TargetCardInHand(filter); - if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } else { - return false; - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java b/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java index 6d1f9a9bae8..3a87eb36ce0 100644 --- a/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java +++ b/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. @@ -35,26 +35,16 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.common.FilterArtifactCard; -import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInLibrary; - - /** * * @author BetaSteward_at_googlemail.com @@ -64,7 +54,6 @@ public class StoneforgeMystic extends CardImpl { private static final FilterCard filter = new FilterCard("an Equipment card"); static { - filter.add(new CardTypePredicate(CardType.ARTIFACT)); filter.add(new SubtypePredicate("Equipment")); } @@ -82,7 +71,7 @@ public class StoneforgeMystic extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); // {1}{W}, {T}: You may put an Equipment card from your hand onto the battlefield. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StoneforgeMysticEffect(), new ManaCostsImpl("{1}{W}")); + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter), new ManaCostsImpl("{1}{W}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } @@ -97,44 +86,3 @@ public class StoneforgeMystic extends CardImpl { } } - -class StoneforgeMysticEffect extends OneShotEffect { - - private static final FilterArtifactCard filter = new FilterArtifactCard("an Equipment card from your hand"); - - static { - filter.add(new SubtypePredicate("Equipment")); - } - - public StoneforgeMysticEffect() { - super(Outcome.Benefit); - this.staticText = "You may put an Equipment card from your hand onto the battlefield"; - } - - public StoneforgeMysticEffect(final StoneforgeMysticEffect effect) { - super(effect); - } - - @Override - public StoneforgeMysticEffect copy() { - return new StoneforgeMysticEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Target target = new TargetCardInHand(filter); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && controller.chooseUse(outcome, "Put an Equipment from your hand to battlefield?", source, game) - && controller.chooseTarget(outcome, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } - } - return true; - } - return false; - } -} From 94b9790bb014c5c3056f3ce905b41d673d5fb42a Mon Sep 17 00:00:00 2001 From: LoneFox Date: Wed, 5 Aug 2015 11:10:34 +0300 Subject: [PATCH 17/24] Fix capitalization --- .../effects/common/PutPermanentOnBattlefieldEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java index 254566a4cd9..09a89be1956 100644 --- a/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java @@ -63,6 +63,6 @@ public class PutPermanentOnBattlefieldEffect extends OneShotEffect { return staticText; } - return "You may put " + filter.getMessage() + " from your hand onto the battlefield"; + return "you may put " + filter.getMessage() + " from your hand onto the battlefield"; } } From 56ee85e11f5e9a77d715cf1369ef7241018b6c26 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Wed, 5 Aug 2015 11:51:56 +0300 Subject: [PATCH 18/24] Replace more custom effects with PutPermanentOnBattlefieldEffect --- .../sets/magic2014/GarrukCallerOfBeasts.java | 58 +----------- .../sets/shadowmoor/DramaticEntrance.java | 63 ++----------- .../mage/sets/zendikar/WarrenInstigator.java | 92 +++---------------- 3 files changed, 24 insertions(+), 189 deletions(-) diff --git a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java index a4fc59d7c98..6cf8ee79c45 100644 --- a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java +++ b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java @@ -34,12 +34,11 @@ import mage.abilities.LoyaltyAbility; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -50,11 +49,7 @@ import mage.filter.FilterSpell; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; import mage.game.command.Emblem; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInLibrary; /** @@ -63,7 +58,8 @@ import mage.target.common.TargetCardInLibrary; */ public class GarrukCallerOfBeasts extends CardImpl { - private static final FilterCreatureCard filterGreenCreature = new FilterCreatureCard("a green creature card from your hand"); + private static final FilterCreatureCard filterGreenCreature = new FilterCreatureCard("a green creature card"); + static { filterGreenCreature.add(new ColorPredicate(ObjectColor.GREEN)); } @@ -80,7 +76,7 @@ public class GarrukCallerOfBeasts extends CardImpl { this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(5, new FilterCreatureCard("all creature cards"),true), 1)); // -3: You may put a green creature card from your hand onto the battlefield. - this.addAbility(new LoyaltyAbility(new GarrukCallerOfBeastsPutOntoBattlefieldEffect(), -3)); + this.addAbility(new LoyaltyAbility(new PutPermanentOnBattlefieldEffect(filterGreenCreature), -3)); // -7: You get an emblem with "Whenever you cast a creature spell, you may search your library for a creature card, put it onto the battlefield, then shuffle your library."); this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new GarrukCallerOfBeastsEmblem()), -7)); @@ -96,6 +92,7 @@ public class GarrukCallerOfBeasts extends CardImpl { return new GarrukCallerOfBeasts(this); } } + /** * Emblem: "Whenever you cast a creature spell, you may search your library for a creature card, put it onto the battlefield, then shuffle your library." */ @@ -113,48 +110,3 @@ class GarrukCallerOfBeastsEmblem extends Emblem { this.getAbilities().add(ability); } } - -class GarrukCallerOfBeastsPutOntoBattlefieldEffect extends OneShotEffect { - - private static final FilterCreatureCard filterGreenCreature = new FilterCreatureCard("a green creature card from your hand"); - - static { - filterGreenCreature.add(new ColorPredicate(ObjectColor.GREEN)); - } - - public GarrukCallerOfBeastsPutOntoBattlefieldEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "You may put a green creature card from your hand onto the battlefield"; - } - - public GarrukCallerOfBeastsPutOntoBattlefieldEffect(final GarrukCallerOfBeastsPutOntoBattlefieldEffect effect) { - super(effect); - } - - @Override - public GarrukCallerOfBeastsPutOntoBattlefieldEffect copy() { - return new GarrukCallerOfBeastsPutOntoBattlefieldEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - if (controller.getHand().count(filterGreenCreature, game) > 0) { - - if (controller.chooseUse(Outcome.PutCreatureInPlay, - "Put a green creature card onto the battlefield?", source, game)) { - Target target = new TargetCardInHand(filterGreenCreature); - if (controller.chooseTarget(outcome, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java b/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java index c3c0846ab5d..cf1822e48df 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java @@ -29,20 +29,12 @@ package mage.sets.shadowmoor; import java.util.UUID; import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInHand; /** * @@ -50,13 +42,18 @@ import mage.target.common.TargetCardInHand; */ public class DramaticEntrance extends CardImpl { + private static final FilterCreatureCard filter = new FilterCreatureCard("a green creature card"); + + static { + filter.add(new ColorPredicate(ObjectColor.GREEN)); + } + public DramaticEntrance(UUID ownerId) { super(ownerId, 111, "Dramatic Entrance", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{G}{G}"); this.expansionSetCode = "SHM"; - // You may put a green creature card from your hand onto the battlefield. - this.getSpellAbility().addEffect(new DramaticEntranceEffect()); + this.getSpellAbility().addEffect(new PutPermanentOnBattlefieldEffect(filter)); } @@ -69,47 +66,3 @@ public class DramaticEntrance extends CardImpl { return new DramaticEntrance(this); } } - -class DramaticEntranceEffect extends OneShotEffect { - - private static final FilterCreatureCard filter = new FilterCreatureCard("a green creature card from your hand"); - - static { - filter.add(new ColorPredicate(ObjectColor.GREEN)); - } - - public DramaticEntranceEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "You may put a green creature card from your hand onto the battlefield"; - } - - public DramaticEntranceEffect(final DramaticEntranceEffect effect) { - super(effect); - } - - @Override - public DramaticEntranceEffect copy() { - return new DramaticEntranceEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - if (controller.getHand().count(filter, game) > 0) { - if (controller.chooseUse(Outcome.PutCreatureInPlay, - "Put a green creature card onto the battlefield?", source, game)) { - Target target = new TargetCardInHand(filter); - if (controller.chooseTarget(outcome, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/zendikar/WarrenInstigator.java b/Mage.Sets/src/mage/sets/zendikar/WarrenInstigator.java index 8179345ad2d..7cbe2539675 100644 --- a/Mage.Sets/src/mage/sets/zendikar/WarrenInstigator.java +++ b/Mage.Sets/src/mage/sets/zendikar/WarrenInstigator.java @@ -29,23 +29,14 @@ package mage.sets.zendikar; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.abilities.keyword.DoubleStrikeAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; -import mage.target.common.TargetCardInHand; /** * @@ -53,6 +44,12 @@ import mage.target.common.TargetCardInHand; */ public class WarrenInstigator extends CardImpl { + private static final FilterCreatureCard filter = new FilterCreatureCard("a Goblin creature card"); + + static { + filter.add(new SubtypePredicate("Goblin")); + } + public WarrenInstigator(UUID ownerId) { super(ownerId, 154, "Warren Instigator", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{R}{R}"); this.expansionSetCode = "ZEN"; @@ -63,7 +60,9 @@ public class WarrenInstigator extends CardImpl { this.toughness = new MageInt(1); this.addAbility(DoubleStrikeAbility.getInstance()); - this.addAbility(new WarrenInstigatorTriggeredAbility()); + + // Whenever Warren Instigator deals damage to an opponent, you may put a Goblin creature card from your hand onto the battlefield. + this.addAbility(new DealsDamageToOpponentTriggeredAbility(new PutPermanentOnBattlefieldEffect(filter), false)); } public WarrenInstigator(final WarrenInstigator card) { @@ -75,72 +74,3 @@ public class WarrenInstigator extends CardImpl { return new WarrenInstigator(this); } } - -class WarrenInstigatorTriggeredAbility extends TriggeredAbilityImpl { - - public WarrenInstigatorTriggeredAbility() { - super(Zone.BATTLEFIELD, new WarrenInstigatorEffect(), true); - } - - public WarrenInstigatorTriggeredAbility(final WarrenInstigatorTriggeredAbility ability) { - super(ability); - } - - @Override - public WarrenInstigatorTriggeredAbility copy() { - return new WarrenInstigatorTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - return event.getSourceId().equals(this.sourceId) - && game.getOpponents(this.getControllerId()).contains(event.getTargetId()); - } - - @Override - public String getRule() { - return "Whenever {this} deals damage to an opponent, you may put a Goblin creature card from your hand onto the battlefield."; - } -} - -class WarrenInstigatorEffect extends OneShotEffect { - - public WarrenInstigatorEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "you may put a Goblin creature card from your hand onto the battlefield"; - } - - public WarrenInstigatorEffect(final WarrenInstigatorEffect effect) { - super(effect); - } - - @Override - public WarrenInstigatorEffect copy() { - return new WarrenInstigatorEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - - FilterCreatureCard filter = new FilterCreatureCard("Goblin creature card from your hand"); - filter.add(new SubtypePredicate("Goblin")); - TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); - return true; - } - } - return false; - } -} From 0c9e67377f649712f8769f7c2c2aabe35e1cc3aa Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 5 Aug 2015 11:47:09 +0200 Subject: [PATCH 19/24] * Petalmane Baku - Fixed wrong CounterType (caused by copy & paste). --- Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java index 0e0eca1d7e4..d31abe9b9c1 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PetalmaneBaku.java @@ -75,7 +75,7 @@ public class PetalmaneBaku extends CardImpl { new ManaCostsImpl<>("{1}"), "Add X mana of any one color to your mana pool", true, new CountersCount(CounterType.KI)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.KI.createInstance(), "Remove X ki counters from {this}")); this.addAbility(ability); } From ef1a487dd5d7ede6a5a7d64f99f15966c3fca5b1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 5 Aug 2015 15:35:17 +0200 Subject: [PATCH 20/24] * Melek, Izzet Paragon - Fixed that it also triggered for spells cast from other libraries. --- Mage.Sets/src/mage/sets/dragonsmaze/MelekIzzetParagon.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/MelekIzzetParagon.java b/Mage.Sets/src/mage/sets/dragonsmaze/MelekIzzetParagon.java index f174c83e2f2..f58645d1781 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/MelekIzzetParagon.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/MelekIzzetParagon.java @@ -117,7 +117,7 @@ class MelekIzzetParagonTriggeredAbility extends TriggeredAbilityImpl { if (event.getZone() == Zone.LIBRARY) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null - && spell.getControllerId().equals(super.getControllerId()) + && spell.getOwnerId().equals(super.getControllerId()) && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) { for (Effect effect : this.getEffects()) { From 662ee7ca107a3f6c862e0aff4a430e6d3452bcea Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 5 Aug 2015 17:45:45 +0200 Subject: [PATCH 21/24] * Fixed handling of face down card selection (e.g. for Scroll Rack). --- Mage.Common/src/mage/view/CardView.java | 162 +++++++++++------- Mage.Common/src/mage/view/CardsView.java | 6 + .../src/mage/player/human/HumanPlayer.java | 1 + .../java/mage/server/game/GameController.java | 4 +- .../common/MayTapOrUntapTargetEffect.java | 5 +- Mage/src/mage/game/Exile.java | 66 ++++--- 6 files changed, 142 insertions(+), 102 deletions(-) diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index d0845cd7ae6..6c90e5a66b4 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -1,33 +1,35 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.view; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import mage.MageObject; import mage.ObjectColor; import mage.abilities.Modes; @@ -35,9 +37,14 @@ import mage.abilities.SpellAbility; import mage.abilities.costs.mana.ManaCosts; import mage.cards.Card; import mage.cards.SplitCard; -import mage.constants.*; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.MageObjectType; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.Counter; import mage.counters.CounterType; +import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.Permanent; import mage.game.permanent.PermanentToken; @@ -47,15 +54,11 @@ import mage.game.stack.StackAbility; import mage.target.Target; import mage.target.Targets; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import mage.game.Game; - /** * @author BetaSteward_at_googlemail.com */ public class CardView extends SimpleCardView { + private static final long serialVersionUID = 1L; protected UUID parentId; @@ -88,7 +91,7 @@ public class CardView extends SimpleCardView { protected boolean flipCard; protected boolean faceDown; - + protected String alternateName; protected String originalName; @@ -114,7 +117,7 @@ public class CardView extends SimpleCardView { protected boolean isPlayable; protected boolean isChoosable; protected boolean selected; - protected boolean canAttack; + protected boolean canAttack; public CardView(Card card) { this(card, null, false); @@ -134,13 +137,42 @@ public class CardView extends SimpleCardView { * * @param card * @param game - * @param controlled is the card view created for the card controller - used for morph / face down cards to know which player may see information for the card + * @param controlled is the card view created for the card controller - used + * for morph / face down cards to know which player may see information for + * the card */ public CardView(Card card, Game game, boolean controlled) { + this(card, game, controlled, false); + } + + /** + * + * @param card + * @param game + * @param controlled is the card view created for the card controller - used + * for morph / face down cards to know which player may see information for + * the card + * @param showFaceDownCard if true and the card is not on the battelfield, + * also a face dwon card is shown in the view dwon cards will be shown + */ + public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard) { super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), game != null); // no information available for face down cards as long it's not a controlled face down morph card - // TODO: Better handle this in Framework (but currently I'm not sure how to do it there) LevelX2 - if (game != null && card.isFaceDown(game)) { + // TODO: Better handle this in Framework (but currently I'm not sure how to do it there) LevelX2 + boolean showFaceUp = true; + if (game != null) { + if (card.isFaceDown(game)) { + showFaceUp = false; + if (!Zone.BATTLEFIELD.equals(game.getState().getZone(card.getId()))) { + if (showFaceDownCard) { + showFaceUp = true; + } + } + } + } + // boolean showFaceUp = game == null || !card.isFaceDown(game) || (!game.getState().getZone(card.getId()).equals(Zone.BATTLEFIELD) && showFaceDownCard); + + if (!showFaceUp) { this.fillEmpty(card, controlled); if (card instanceof Spell) { // special handling for casting of Morph cards @@ -151,10 +183,10 @@ public class CardView extends SimpleCardView { } this.power = "2"; this.toughness = "2"; - this.rules.add("You may cast this card as a 2/2 face-down creature, with no text," + - " no name, no subtypes, and no mana cost by paying {3} rather than paying its mana cost."); + this.rules.add("You may cast this card as a 2/2 face-down creature, with no text," + + " no name, no subtypes, and no mana cost by paying {3} rather than paying its mana cost."); return; - } else { + } else { if (card instanceof Permanent) { this.power = Integer.toString(card.getPower().getValue()); this.toughness = Integer.toString(card.getToughness().getValue()); @@ -172,7 +204,7 @@ public class CardView extends SimpleCardView { rotate = true; } else { if (card instanceof Spell) { - switch(((Spell) card).getSpellAbility().getSpellAbilityType()) { + switch (((Spell) card).getSpellAbility().getSpellAbilityType()) { case SPLIT_FUSED: splitCard = (SplitCard) ((Spell) card).getCard(); rotate = true; @@ -206,7 +238,7 @@ public class CardView extends SimpleCardView { if (card instanceof Permanent) { this.mageObjectType = MageObjectType.PERMANENT; - Permanent permanent = (Permanent)card; + Permanent permanent = (Permanent) card; this.loyalty = Integer.toString(permanent.getCounters().getCount(CounterType.LOYALTY)); this.pairedCard = permanent.getPairedCard(); if (!permanent.getControllerId().equals(permanent.getOwnerId())) { @@ -214,7 +246,7 @@ public class CardView extends SimpleCardView { } if (game != null && permanent.getCounters() != null && !permanent.getCounters().isEmpty()) { counters = new ArrayList<>(); - for (Counter counter: permanent.getCounters().values()) { + for (Counter counter : permanent.getCounters().values()) { counters.add(new CounterView(counter)); } } @@ -227,7 +259,7 @@ public class CardView extends SimpleCardView { this.loyalty = ""; if (game != null && card.getCounters(game) != null && !card.getCounters(game).isEmpty()) { counters = new ArrayList<>(); - for (Counter counter: card.getCounters(game).values()) { + for (Counter counter : card.getCounters(game).values()) { counters.add(new CounterView(counter)); } } @@ -240,8 +272,8 @@ public class CardView extends SimpleCardView { this.color = card.getColor(game); this.canTransform = card.canTransform(); this.flipCard = card.isFlipCard(); - this.faceDown = game != null ? card.isFaceDown(game) : false; - + this.faceDown = !showFaceUp; + if (card instanceof PermanentToken) { this.isToken = true; this.mageObjectType = MageObjectType.TOKEN; @@ -257,7 +289,7 @@ public class CardView extends SimpleCardView { // // set code und card number for token copies to get the image this.rules = ((PermanentToken) card).getRules(game); - this.type = ((PermanentToken)card).getToken().getTokenType(); + this.type = ((PermanentToken) card).getToken().getTokenType(); } else { this.rarity = card.getRarity(); this.isToken = false; @@ -269,7 +301,7 @@ public class CardView extends SimpleCardView { this.originalName = card.getName(); } this.flipCard = card.isFlipCard(); - if (card.isFlipCard() && card.getFlipCardName() != null) { + if (card.isFlipCard() && card.getFlipCardName() != null) { this.alternateName = card.getFlipCardName(); this.originalName = card.getName(); } @@ -277,8 +309,8 @@ public class CardView extends SimpleCardView { if (card instanceof Spell) { this.mageObjectType = MageObjectType.SPELL; Spell spell = (Spell) card; - for (SpellAbility spellAbility: spell.getSpellAbilities()) { - for(UUID modeId : spellAbility.getModes().getSelectedModes()) { + for (SpellAbility spellAbility : spell.getSpellAbilities()) { + for (UUID modeId : spellAbility.getModes().getSelectedModes()) { spellAbility.getModes().setActiveMode(modeId); if (spellAbility.getTargets().size() > 0) { setTargets(spellAbility.getTargets()); @@ -288,12 +320,12 @@ public class CardView extends SimpleCardView { // show for modal spell, which mode was choosen if (spell.getSpellAbility().isModal()) { Modes modes = spell.getSpellAbility().getModes(); - for(UUID modeId : modes.getSelectedModes()) { + for (UUID modeId : modes.getSelectedModes()) { modes.setActiveMode(modeId); - this.rules.add("Chosen mode: " + spell.getSpellAbility().getEffects().getText(modes.get(modeId))+""); + this.rules.add("Chosen mode: " + spell.getSpellAbility().getEffects().getText(modes.get(modeId)) + ""); } } - } + } } public CardView(MageObject object) { @@ -330,7 +362,7 @@ public class CardView extends SimpleCardView { this.rules = emblem.getAbilities().getRules(emblem.getName()); } if (this.rarity == null && object instanceof StackAbility) { - StackAbility stackAbility = (StackAbility)object; + StackAbility stackAbility = (StackAbility) object; this.rarity = Rarity.NA; this.rules = new ArrayList<>(); this.rules.add(stackAbility.getRule()); @@ -343,7 +375,7 @@ public class CardView extends SimpleCardView { protected CardView() { super(null, "", 0, false, "", true); } - + public CardView(EmblemView emblem) { this(true); this.gameObject = true; @@ -397,7 +429,7 @@ public class CardView extends SimpleCardView { } else { this.mageObjectType = MageObjectType.CARD; } - } + } if (card instanceof PermanentToken) { this.mageObjectType = MageObjectType.TOKEN; } @@ -410,7 +442,7 @@ public class CardView extends SimpleCardView { CardView(Token token) { super(token.getId(), "", 0, false, ""); - this.isToken = true; + this.isToken = true; this.id = token.getId(); this.name = token.getName(); this.displayName = token.getName(); @@ -517,11 +549,11 @@ public class CardView extends SimpleCardView { public String getExpansionSetCode() { return expansionSetCode; } - + public void setExpansionSetCode(String expansionSetCode) { this.expansionSetCode = expansionSetCode; } - + @Override public UUID getId() { return id; @@ -533,8 +565,7 @@ public class CardView extends SimpleCardView { } /** - * Returns UUIDs for targets. - * Can be null if there is no target selected. + * Returns UUIDs for targets. Can be null if there is no target selected. * * @return */ @@ -595,7 +626,8 @@ public class CardView extends SimpleCardView { } /** - * Stores the name of the original name, to provide it for a flipped or transformed or copying card + * Stores the name of the original name, to provide it for a flipped or + * transformed or copying card * * @return */ @@ -706,7 +738,7 @@ public class CardView extends SimpleCardView { public boolean isChoosable() { return isChoosable; } - + public void setChoosable(boolean isChoosable) { this.isChoosable = isChoosable; } @@ -726,5 +758,5 @@ public class CardView extends SimpleCardView { public void setCanAttack(boolean canAttack) { this.canAttack = canAttack; } - + } diff --git a/Mage.Common/src/mage/view/CardsView.java b/Mage.Common/src/mage/view/CardsView.java index 0107ee0ee03..2b72e78a1c2 100644 --- a/Mage.Common/src/mage/view/CardsView.java +++ b/Mage.Common/src/mage/view/CardsView.java @@ -72,6 +72,12 @@ public class CardsView extends LinkedHashMap { } } + public CardsView(Game game, Collection cards, boolean showFaceDown) { + for (Card card : cards) { + this.put(card.getId(), new CardView(card, game, false, showFaceDown)); + } + } + public CardsView(Collection abilities, Game game) { for (Ability ability : abilities) { MageObject sourceObject = null; diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index c4015dd9b95..2ed5be13a9f 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -431,6 +431,7 @@ public class HumanPlayer extends PlayerImpl { if (!choosable.isEmpty()) { options.put("choosable", (Serializable) choosable); } + game.fireSelectTargetEvent(playerId, target.getMessage(), cards, required, options); waitForResponse(game); if (response.getUUID() != null) { diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 49f8ae0e28b..30fbe4fcd17 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -825,7 +825,9 @@ public class GameController implements GameCallback { @Override public void execute(UUID playerId) { if (cards != null) { - getGameSession(playerId).target(question, new CardsView(game, cards.getCards(game)), targets, required, options); + Zone targetZone = (Zone) options.get("targetZone"); + boolean showFaceDown = targetZone != null && targetZone.equals(Zone.PICK); + getGameSession(playerId).target(question, new CardsView(game, cards.getCards(game), showFaceDown), targets, required, options); } else if (perms != null) { CardsView permsView = new CardsView(); for (Permanent perm : perms) { diff --git a/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java b/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java index 9e2c9523a66..f107f2e0a1c 100644 --- a/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java @@ -12,6 +12,7 @@ import mage.players.Player; * @author Loki */ public class MayTapOrUntapTargetEffect extends OneShotEffect { + public MayTapOrUntapTargetEffect() { super(Outcome.Benefit); } @@ -47,9 +48,9 @@ public class MayTapOrUntapTargetEffect extends OneShotEffect { @Override public String getText(Mode mode) { if (mode.getTargets().isEmpty()) { - return "You may tap or untap it"; + return "you may tap or untap it"; } else { - return "You may tap or untap target " + mode.getTargets().get(0).getTargetName(); + return "you may tap or untap target " + mode.getTargets().get(0).getTargetName(); } } } diff --git a/Mage/src/mage/game/Exile.java b/Mage/src/mage/game/Exile.java index 821afc8d9a0..688a2727586 100644 --- a/Mage/src/mage/game/Exile.java +++ b/Mage/src/mage/game/Exile.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.game; import java.io.Serializable; @@ -39,7 +38,6 @@ import java.util.UUID; import mage.cards.Card; import mage.util.Copyable; - /** * * @author BetaSteward_at_googlemail.com @@ -48,14 +46,14 @@ public class Exile implements Serializable, Copyable { private static final UUID PERMANENT = UUID.randomUUID(); - private Map exileZones = new HashMap(); + private Map exileZones = new HashMap<>(); public Exile() { createZone(PERMANENT, "Permanent"); } public Exile(final Exile exile) { - for (Entry entry: exile.exileZones.entrySet()) { + for (Entry entry : exile.exileZones.entrySet()) { exileZones.put(entry.getKey(), entry.getValue().copy()); } } @@ -93,7 +91,7 @@ public class Exile implements Serializable, Copyable { } public Card getCard(UUID cardId, Game game) { - for (ExileZone exile: exileZones.values()) { + for (ExileZone exile : exileZones.values()) { if (exile.contains(cardId)) { return game.getCard(cardId); } @@ -103,14 +101,14 @@ public class Exile implements Serializable, Copyable { public List getAllCards(Game game) { List cards = new ArrayList(); - for (ExileZone exile: exileZones.values()) { + for (ExileZone exile : exileZones.values()) { cards.addAll(exile.getCards(game)); } return cards; } public void removeCard(Card card, Game game) { - for (ExileZone exile: exileZones.values()) { + for (ExileZone exile : exileZones.values()) { if (exile.contains(card.getId())) { exile.remove(card); } @@ -123,7 +121,7 @@ public class Exile implements Serializable, Copyable { } public void clear() { - for (ExileZone exile: exileZones.values()) { + for (ExileZone exile : exileZones.values()) { exile.clear(); } } From 78ff4e58e74d4d4e9c50947dac7dfbf62b35c933 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 5 Aug 2015 17:46:26 +0200 Subject: [PATCH 22/24] * Fixed handling of face down card selection (e.g. for Scroll Rack). --- .../src/mage/sets/tempest/ScrollRack.java | 51 +++++-------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/Mage.Sets/src/mage/sets/tempest/ScrollRack.java b/Mage.Sets/src/mage/sets/tempest/ScrollRack.java index c675affb015..4d5ece41394 100644 --- a/Mage.Sets/src/mage/sets/tempest/ScrollRack.java +++ b/Mage.Sets/src/mage/sets/tempest/ScrollRack.java @@ -27,7 +27,6 @@ */ package mage.sets.tempest; -import java.util.List; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; @@ -37,15 +36,14 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; -import mage.target.common.TargetCardInExile; import mage.target.common.TargetCardInHand; /** @@ -91,54 +89,31 @@ class ScrollRackEffect extends OneShotEffect { MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { FilterCard filter = new FilterCard("card in your hand to exile"); - FilterCard filter2 = new FilterCard("(move the window) card exiled by " + sourceObject.getLogName() + " to put on top of library"); +// FilterCard filter2 = new FilterCard("(move the window) card exiled by " + sourceObject.getIdName() + " to put on top of library"); TargetCardInHand target = new TargetCardInHand(0, controller.getHand().size(), filter); target.setRequired(false); int amountExiled = 0; if (target.canChoose(source.getControllerId(), game) && target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) { if (!target.getTargets().isEmpty()) { - List targets = target.getTargets(); - for (UUID targetId : targets) { + for (UUID targetId : target.getTargets()) { Card card = game.getCard(targetId); if (card != null) { - if (card.moveToExile(source.getSourceId(), sourceObject.getName(), source.getSourceId(), game)) { - card.setFaceDown(true, game); - amountExiled++; - } + card.setFaceDown(true, game); + amountExiled++; } } + controller.moveCardsToExile(new CardsImpl(target.getTargets()).getCards(game), source, game, false, source.getSourceId(), sourceObject.getIdName()); + for (Card card : game.getExile().getExileZone(source.getSourceId()).getCards(game)) { + card.setFaceDown(true, game); + } } } - game.informPlayers(controller.getLogName() + " exiles " + amountExiled + " card" + (amountExiled == 1 ? " ":"s ") + "face down from his or her hand"); + // Put that many cards from the top of your library into your hand. if (amountExiled > 0) { - int count = Math.min(controller.getLibrary().size(), amountExiled); - for (int i = 0; i < count; i++) { - Card card = controller.getLibrary().removeFromTop(game); - if (card != null) { - card.moveToZone(Zone.HAND, source.getSourceId(), game, false); - } - } - } - game.informPlayers(controller.getLogName() + " moves " + amountExiled + " card" + (amountExiled == 1 ? " ":"s ") + "from library to hand"); - - TargetCardInExile target2 = new TargetCardInExile(filter2, source.getSourceId()); - ExileZone scrollRackExileZone = game.getExile().getExileZone(source.getSourceId()); - if (scrollRackExileZone != null) { - while (controller.canRespond() && scrollRackExileZone.count(filter, game) > 1) { - controller.lookAtCards("exiled cards with " + sourceObject.getName(), scrollRackExileZone, game); - controller.choose(Outcome.Neutral, scrollRackExileZone, target2, game); - Card card = game.getCard(target2.getFirstTarget()); - if (card != null) { - game.getExile().removeCard(card, game); - controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, true, false); - } - target2.clearChosen(); - } - if (scrollRackExileZone.count(filter, game) == 1) { - Card card = scrollRackExileZone.get(scrollRackExileZone.iterator().next(), game); - controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, true, false); - } + controller.moveCards(controller.getLibrary().getTopCards(game, amountExiled), null, Zone.HAND, source, game, false); } + // Then look at the exiled cards and put them on top of your library in any order + controller.putCardsOnTopOfLibrary(game.getExile().getExileZone(source.getSourceId()), game, source, true); return true; } return false; From 55fe68d718600abc45e03ac727ed881048cdafac Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 5 Aug 2015 17:46:56 +0200 Subject: [PATCH 23/24] * Some more rework of card mobement handling. --- .../sets/dragonsoftarkir/CommuneWithLava.java | 15 ++- .../mage/sets/eventide/SanityGrinding.java | 20 ++-- .../sets/innistrad/HereticsPunishment.java | 19 ++-- .../NarsetEnlightenedMaster.java | 21 ++--- .../mage/sets/magic2014/JacesMindseeker.java | 20 ++-- .../mage/sets/magic2015/HushwingGryff.java | 13 +-- .../magicorigins/TalentOfTheTelepath.java | 4 +- .../sets/shadowmoor/AdviceFromTheFae.java | 16 +--- .../java/org/mage/test/player/TestPlayer.java | 11 ++- .../effects/keyword/ManifestEffect.java | 10 +- .../keyword/ManifestTargetPlayerEffect.java | 17 ++-- Mage/src/mage/cards/Cards.java | 68 ++++++++------ Mage/src/mage/cards/CardsImpl.java | 94 ++++++++++--------- .../game/events/ZoneChangeGroupEvent.java | 66 ++++++------- Mage/src/mage/players/Library.java | 88 +++++++++-------- Mage/src/mage/players/Player.java | 9 +- Mage/src/mage/players/PlayerImpl.java | 32 +++++-- .../target/common/TargetCardInLibrary.java | 59 ++++++------ 18 files changed, 298 insertions(+), 284 deletions(-) diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java index 4487794cdf5..89fe50de8f2 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java @@ -27,7 +27,7 @@ */ package mage.sets.dragonsoftarkir; -import java.util.List; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.AsThoughEffectImpl; @@ -94,14 +94,13 @@ class CommuneWithLavaEffect extends OneShotEffect { Card sourceCard = game.getCard(source.getSourceId()); if (controller != null) { int amount = source.getManaCostsToPay().getX(); - List cards = controller.getLibrary().getTopCards(game, amount); + Set cards = controller.getLibrary().getTopCards(game, amount); + controller.moveCardsToExile(cards, source, game, true, CardUtil.getCardExileZoneId(game, source), sourceCard.getIdName()); + for (Card card : cards) { - if (card != null) { - controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourceCard.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); - ContinuousEffect effect = new CommuneWithLavaMayPlayEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - } + ContinuousEffect effect = new CommuneWithLavaMayPlayEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); } return true; diff --git a/Mage.Sets/src/mage/sets/eventide/SanityGrinding.java b/Mage.Sets/src/mage/sets/eventide/SanityGrinding.java index 063228b681a..3ee98ec4d43 100644 --- a/Mage.Sets/src/mage/sets/eventide/SanityGrinding.java +++ b/Mage.Sets/src/mage/sets/eventide/SanityGrinding.java @@ -27,6 +27,8 @@ */ package mage.sets.eventide; +import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; @@ -43,8 +45,6 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * * @author jeffwadsworth @@ -56,7 +56,6 @@ public class SanityGrinding extends CardImpl { super(ownerId, 29, "Sanity Grinding", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{U}{U}{U}"); this.expansionSetCode = "EVE"; - // Chroma - Reveal the top ten cards of your library. For each blue mana symbol in the mana costs of the revealed cards, target opponent puts the top card of his or her library into his or her graveyard. Then put the cards you revealed this way on the bottom of your library in any order. this.getSpellAbility().addEffect(new SanityGrindingEffect()); this.getSpellAbility().addTarget(new TargetOpponent()); @@ -86,18 +85,15 @@ class SanityGrindingEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player targetOpponent = game.getPlayer(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); - Cards revealed = new CardsImpl(); - int amount; - if (controller == null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { return false; } - amount = (Math.min(10, controller.getLibrary().size())); - for (int i = 0; i < amount; i++) { - revealed.add(controller.getLibrary().removeFromTop(game)); - } - controller.revealCards("Sanity Grinding", revealed, game); + Cards revealed = new CardsImpl(); + revealed.addAll(controller.getLibrary().getTopCards(game, 10)); + controller.revealCards(sourceObject.getIdName(), revealed, game); + Player targetOpponent = game.getPlayer(source.getFirstTarget()); if (targetOpponent != null) { targetOpponent.moveCards(targetOpponent.getLibrary().getTopCards(game, new ChromaSanityGrindingCount(revealed).calculate(game, source, this)), Zone.LIBRARY, Zone.GRAVEYARD, source, game); diff --git a/Mage.Sets/src/mage/sets/innistrad/HereticsPunishment.java b/Mage.Sets/src/mage/sets/innistrad/HereticsPunishment.java index bfd17fe119d..770680727cc 100644 --- a/Mage.Sets/src/mage/sets/innistrad/HereticsPunishment.java +++ b/Mage.Sets/src/mage/sets/innistrad/HereticsPunishment.java @@ -27,18 +27,18 @@ */ package mage.sets.innistrad; -import java.util.List; +import java.util.Set; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -54,7 +54,6 @@ public class HereticsPunishment extends CardImpl { super(ownerId, 147, "Heretic's Punishment", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{R}"); this.expansionSetCode = "ISD"; - // {3}{R}: Choose target creature or player, then put the top three cards of your library into your graveyard. Heretic's Punishment deals damage to that creature or player equal to the highest converted mana cost among those cards. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HereticsPunishmentEffect(), new ManaCostsImpl("{3}{R}")); ability.addTarget(new TargetCreatureOrPlayer()); @@ -87,12 +86,12 @@ class HereticsPunishmentEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { int maxCost = 0; - List cardList = controller.getLibrary().getTopCards(game, 3); - for (Card card: cardList) { + Set cardList = controller.getLibrary().getTopCards(game, 3); + for (Card card : cardList) { int test = card.getManaCost().convertedManaCost(); if (test > maxCost) { maxCost = test; - } + } } controller.moveCards(cardList, Zone.LIBRARY, Zone.GRAVEYARD, source, game); Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); @@ -114,4 +113,4 @@ class HereticsPunishmentEffect extends OneShotEffect { return new HereticsPunishmentEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/NarsetEnlightenedMaster.java b/Mage.Sets/src/mage/sets/khansoftarkir/NarsetEnlightenedMaster.java index 70d9517368d..a5093dcec42 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/NarsetEnlightenedMaster.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/NarsetEnlightenedMaster.java @@ -27,7 +27,7 @@ */ package mage.sets.khansoftarkir; -import java.util.List; +import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.MageObject; @@ -49,7 +49,6 @@ import mage.constants.Zone; import mage.game.Game; import mage.players.Player; import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; /** * @@ -89,12 +88,12 @@ public class NarsetEnlightenedMaster extends CardImpl { class NarsetEnlightenedMasterExileEffect extends OneShotEffect { public NarsetEnlightenedMasterExileEffect() { - super(Outcome.Discard); - staticText = "exile the top four cards of your library. Until end of turn, you may cast noncreature cards exiled with {this} this turn without paying their mana costs"; + super(Outcome.Discard); + staticText = "exile the top four cards of your library. Until end of turn, you may cast noncreature cards exiled with {this} this turn without paying their mana costs"; } public NarsetEnlightenedMasterExileEffect(final NarsetEnlightenedMasterExileEffect effect) { - super(effect); + super(effect); } @Override @@ -102,16 +101,16 @@ class NarsetEnlightenedMasterExileEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (player != null && sourceObject != null) { - List cards = player.getLibrary().getTopCards(game, 4); + Set cards = player.getLibrary().getTopCards(game, 4); player.moveCards(cards, Zone.LIBRARY, Zone.EXILED, source, game); for (Card card : cards) { - if (game.getState().getZone(card.getId()) == Zone.EXILED && - !card.getCardType().contains(CardType.CREATURE) && - !card.getCardType().contains(CardType.LAND)) { + if (game.getState().getZone(card.getId()) == Zone.EXILED + && !card.getCardType().contains(CardType.CREATURE) + && !card.getCardType().contains(CardType.LAND)) { ContinuousEffect effect = new NarsetEnlightenedMasterCastFromExileEffect(); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); - } + } } return true; } @@ -120,7 +119,7 @@ class NarsetEnlightenedMasterExileEffect extends OneShotEffect { @Override public NarsetEnlightenedMasterExileEffect copy() { - return new NarsetEnlightenedMasterExileEffect(this); + return new NarsetEnlightenedMasterExileEffect(this); } } diff --git a/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java b/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java index bf8354a2869..9877bd2dfbc 100644 --- a/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java +++ b/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java @@ -27,7 +27,7 @@ */ package mage.sets.magic2014; -import java.util.List; +import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; @@ -66,7 +66,7 @@ public class JacesMindseeker extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - // When Jace's Mindseeker enters the battlefield, target opponent puts the top five cards of his or her library into his or her graveyard. + // When Jace's Mindseeker enters the battlefield, target opponent puts the top five cards of his or her library into his or her graveyard. // You may cast an instant or sorcery card from among them without paying its mana cost. Ability ability = new EntersBattlefieldTriggeredAbility(new JaceMindseekerEffect()); ability.addTarget(new TargetOpponent()); @@ -106,17 +106,17 @@ class JaceMindseekerEffect extends OneShotEffect { Cards cardsToCast = new CardsImpl(); Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source)); if (targetOpponent != null) { - List allCards = targetOpponent.getLibrary().getTopCards(game, 5); + Set allCards = targetOpponent.getLibrary().getTopCards(game, 5); targetOpponent.moveCards(allCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game); - for(Card card : allCards) { + for (Card card : allCards) { if (filter.match(card, game)) { Zone zone = game.getState().getZone(card.getId()); - // If the five cards are put into a public zone such as exile instead of a graveyard (perhaps due to the ability of Rest in Peace), - // you can cast one of those instant or sorcery cards from that zone. - if (zone.equals(Zone.GRAVEYARD) || zone.equals(Zone.EXILED)) { + // If the five cards are put into a public zone such as exile instead of a graveyard (perhaps due to the ability of Rest in Peace), + // you can cast one of those instant or sorcery cards from that zone. + if (zone.equals(Zone.GRAVEYARD) || zone.equals(Zone.EXILED)) { cardsToCast.add(card); } - } + } } } @@ -127,14 +127,14 @@ class JaceMindseekerEffect extends OneShotEffect { TargetCard target = new TargetCard(Zone.GRAVEYARD, filter); // zone should be ignored here target.setNotTarget(true); if (controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", source, game) - && controller.choose(outcome, cardsToCast, target, game)) { + && controller.choose(outcome, cardsToCast, target, game)) { Card card = cardsToCast.get(target.getFirstTarget(), game); if (card != null) { controller.cast(card.getSpellAbility(), game, true); } } } - + } return false; diff --git a/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java b/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java index 3cbc4aba1c6..c644c080918 100644 --- a/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java +++ b/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java @@ -98,28 +98,23 @@ class HushwingGryffEffect extends ContinuousRuleModifyingEffectImpl { } return null; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - @Override + @Override public boolean applies(GameEvent event, Ability source, Game game) { Ability ability = (Ability) getValue("targetAbility"); if (ability != null && AbilityType.TRIGGERED.equals(ability.getAbilityType())) { - Permanent p = game.getPermanent(event.getTargetId()); - if (p != null && p.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } return false; } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } @Override public HushwingGryffEffect copy() { diff --git a/Mage.Sets/src/mage/sets/magicorigins/TalentOfTheTelepath.java b/Mage.Sets/src/mage/sets/magicorigins/TalentOfTheTelepath.java index 3614a8974e2..3ece67c3790 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/TalentOfTheTelepath.java +++ b/Mage.Sets/src/mage/sets/magicorigins/TalentOfTheTelepath.java @@ -27,7 +27,7 @@ */ package mage.sets.magicorigins; -import java.util.List; +import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; @@ -100,7 +100,7 @@ class TalentOfTheTelepathEffect extends OneShotEffect { Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = source.getSourceObject(game); if (targetOpponent != null && sourceObject != null) { - List allCards = targetOpponent.getLibrary().getTopCards(game, 7); + Set allCards = targetOpponent.getLibrary().getTopCards(game, 7); Cards cards = new CardsImpl(Zone.LIBRARY, allCards); targetOpponent.revealCards(sourceObject.getIdName() + " - " + targetOpponent.getName() + "'s top library cards", cards, game); for (Card card : allCards) { diff --git a/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java b/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java index 99251d9485a..bf1ed806de7 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/AdviceFromTheFae.java @@ -27,12 +27,10 @@ */ package mage.sets.shadowmoor; -import java.util.List; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; @@ -95,12 +93,8 @@ class AdviceFromTheFaeEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject mageObject = game.getObject(source.getSourceId()); if (controller != null) { - List cardsFromTopLibrary = controller.getLibrary().getTopCards(game, 5); - Cards cards = new CardsImpl(Zone.LIBRARY); - for (Card card : cardsFromTopLibrary) { - cards.add(card); - } - controller.lookAtCards(mageObject.getIdName(), cards, game); + Cards cardsFromLibrary = new CardsImpl(Zone.LIBRARY, controller.getLibrary().getTopCards(game, 5)); + controller.lookAtCards(mageObject.getIdName(), cardsFromLibrary, game); int max = 0; for (UUID playerId : controller.getInRange()) { FilterCreaturePermanent filter = new FilterCreaturePermanent(); @@ -113,11 +107,11 @@ class AdviceFromTheFaeEffect extends OneShotEffect { } boolean moreCreatures = game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), controller.getId(), game) > max; TargetCard target = new TargetCard(moreCreatures ? 2 : 1, Zone.LIBRARY, new FilterCard()); - if (controller.choose(Outcome.DrawCard, cards, target, game)) { - cards.removeAll(target.getTargets()); + if (controller.choose(Outcome.DrawCard, cardsFromLibrary, target, game)) { + cardsFromLibrary.removeAll(target.getTargets()); controller.moveCards(new CardsImpl(target.getTargets()), null, Zone.HAND, source, game); } - controller.putCardsOnBottomOfLibrary(cards, game, source, true); + controller.putCardsOnBottomOfLibrary(cardsFromLibrary, game, source, true); return true; } return false; diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index eac8d92bc10..e76f6cc21ea 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1673,7 +1673,7 @@ public class TestPlayer implements Player { } @Override - public boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game) { + public boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game) { return computerPlayer.moveCards(cards, fromZone, toZone, source, game); } @@ -1688,7 +1688,7 @@ public class TestPlayer implements Player { } @Override - public boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { + public boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { return computerPlayer.moveCards(cards, fromZone, toZone, source, game); } @@ -1703,7 +1703,12 @@ public class TestPlayer implements Player { } @Override - public boolean moveCardsToGraveyardWithInfo(List allCards, Ability source, Game game, Zone fromZone) { + public boolean moveCardsToExile(Set cards, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName) { + return computerPlayer.moveCardsToExile(cards, source, game, withName, exileId, exileZoneName); + } + + @Override + public boolean moveCardsToGraveyardWithInfo(Set allCards, Ability source, Game game, Zone fromZone) { return computerPlayer.moveCardsToGraveyardWithInfo(allCards, source, game, fromZone); } diff --git a/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java b/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java index 7fbb96ce7cd..71e6293628d 100644 --- a/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java +++ b/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java @@ -27,7 +27,7 @@ */ package mage.abilities.effects.keyword; -import java.util.List; +import java.util.Set; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCosts; @@ -53,7 +53,7 @@ public class ManifestEffect extends OneShotEffect { private final int amount; - public ManifestEffect(int amount) { + public ManifestEffect(int amount) { super(Outcome.PutCreatureInPlay); this.amount = amount; this.staticText = setText(); @@ -75,8 +75,8 @@ public class ManifestEffect extends OneShotEffect { if (controller != null) { Ability newSource = source.copy(); newSource.setWorksFaceDown(true); - List cards = controller.getLibrary().getTopCards(game, amount); - for (Card card: cards) { + Set cards = controller.getLibrary().getTopCards(game, amount); + for (Card card : cards) { ManaCosts manaCosts = null; if (card.getCardType().contains(CardType.CREATURE)) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -84,7 +84,7 @@ public class ManifestEffect extends OneShotEffect { manaCosts = new ManaCostsImpl("{0}"); } } - MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) +1, game); + MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true); Permanent permanent = game.getPermanent(card.getId()); diff --git a/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java index f860993f4a4..897ff83f235 100644 --- a/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java +++ b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java @@ -27,12 +27,11 @@ */ package mage.abilities.effects.keyword; -import java.util.List; +import java.util.Set; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect; import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect.FaceDownType; @@ -44,20 +43,18 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; /** * * @author LevelX2 */ - public class ManifestTargetPlayerEffect extends OneShotEffect { private final int amount; private final String prefix; - public ManifestTargetPlayerEffect(int amount, String prefix) { + public ManifestTargetPlayerEffect(int amount, String prefix) { super(Outcome.PutCreatureInPlay); this.amount = amount; this.prefix = prefix; @@ -81,8 +78,8 @@ public class ManifestTargetPlayerEffect extends OneShotEffect { if (targetPlayer != null) { Ability newSource = source.copy(); newSource.setWorksFaceDown(true); - List cards = targetPlayer.getLibrary().getTopCards(game, amount); - for (Card card: cards) { + Set cards = targetPlayer.getLibrary().getTopCards(game, amount); + for (Card card : cards) { ManaCosts manaCosts = null; if (card.getCardType().contains(CardType.CREATURE)) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -90,13 +87,13 @@ public class ManifestTargetPlayerEffect extends OneShotEffect { manaCosts = new ManaCostsImpl("{0}"); } } - MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) +1, game); - game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); + MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game); + game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true); Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { permanent.setManifested(true); - } + } } return true; } diff --git a/Mage/src/mage/cards/Cards.java b/Mage/src/mage/cards/Cards.java index fffc342824a..313f183d6ad 100644 --- a/Mage/src/mage/cards/Cards.java +++ b/Mage/src/mage/cards/Cards.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.cards; import java.io.Serializable; @@ -39,18 +38,33 @@ import mage.game.Game; public interface Cards extends Set, Serializable { void add(Card card); + Card get(UUID cardId, Game game); + void remove(Card card); + void setOwner(UUID ownerId, Game game); + void addAll(List createCards); + + void addAll(Set createCards); + Set getCards(Game game); + Set getCards(FilterCard filter, Game game); + Set getCards(FilterCard filter, UUID sourceId, UUID playerId, Game game); + String getValue(Game game); + Collection getUniqueCards(Game game); + Card getRandom(Game game); + int count(FilterCard filter, Game game); + int count(FilterCard filter, UUID playerId, Game game); + int count(FilterCard filter, UUID sourceId, UUID playerId, Game game); Cards copy(); diff --git a/Mage/src/mage/cards/CardsImpl.java b/Mage/src/mage/cards/CardsImpl.java index c06e6db5f9a..d7799289e23 100644 --- a/Mage/src/mage/cards/CardsImpl.java +++ b/Mage/src/mage/cards/CardsImpl.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.cards; import java.io.Serializable; @@ -44,20 +43,20 @@ import mage.filter.FilterCard; import mage.game.Game; import mage.util.ThreadLocalStringBuilder; - /** * * @author BetaSteward_at_googlemail.com */ public class CardsImpl extends LinkedHashSet implements Cards, Serializable { - + private static final transient ThreadLocalStringBuilder threadLocalBuilder = new ThreadLocalStringBuilder(200); private static Random rnd = new Random(); private UUID ownerId; private Zone zone; - public CardsImpl() { } + public CardsImpl() { + } public CardsImpl(Card card) { if (card != null) { @@ -74,10 +73,10 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl public CardsImpl(Zone zone) { this.zone = zone; } - + public CardsImpl(Zone zone, Collection cards) { this(zone); - for (Card card: cards) { + for (Card card : cards) { this.add(card.getId()); } } @@ -117,7 +116,7 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public void setOwner(UUID ownerId, Game game) { this.ownerId = ownerId; - for (UUID card: this) { + for (UUID card : this) { game.getCard(card).setOwnerId(ownerId); } } @@ -134,7 +133,7 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public int count(FilterCard filter, Game game) { int result = 0; - for (UUID cardId: this) { + for (UUID cardId : this) { if (filter.match(game.getCard(cardId), game)) { result++; } @@ -145,7 +144,7 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public int count(FilterCard filter, UUID playerId, Game game) { int result = 0; - for (UUID card: this) { + for (UUID card : this) { if (filter.match(game.getCard(card), playerId, game)) { result++; } @@ -159,7 +158,7 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl return count(filter, playerId, game); } int result = 0; - for (UUID card: this) { + for (UUID card : this) { if (filter.match(game.getCard(card), sourceId, playerId, game)) { result++; } @@ -170,7 +169,7 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public Set getCards(FilterCard filter, UUID sourceId, UUID playerId, Game game) { Set cards = new LinkedHashSet<>(); - for (UUID card: this) { + for (UUID card : this) { boolean match = filter.match(game.getCard(card), sourceId, playerId, game); if (match) { cards.add(game.getCard(card)); @@ -182,7 +181,7 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public Set getCards(FilterCard filter, Game game) { Set cards = new LinkedHashSet<>(); - for (UUID card: this) { + for (UUID card : this) { boolean match = filter.match(game.getCard(card), game); if (match) { cards.add(game.getCard(card)); @@ -194,11 +193,11 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public Set getCards(Game game) { Set cards = new LinkedHashSet<>(); - for (UUID cardId: this) { + for (UUID cardId : this) { Card card = game.getCard(cardId); if (card != null) { // this can happen during the cancelation (player concedes) of a game cards.add(card); - } + } } return cards; } @@ -207,12 +206,12 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl public String getValue(Game game) { StringBuilder sb = threadLocalBuilder.get(); List cards = new ArrayList<>(); - for (UUID cardId: this) { + for (UUID cardId : this) { Card card = game.getCard(cardId); cards.add(card.getName()); } Collections.sort(cards); - for (String name: cards) { + for (String name : cards) { sb.append(name).append(":"); } return sb.toString(); @@ -220,7 +219,14 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public void addAll(List cards) { - for (Card card: cards) { + for (Card card : cards) { + add(card.getId()); + } + } + + @Override + public void addAll(Set cards) { + for (Card card : cards) { add(card.getId()); } } @@ -228,7 +234,7 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public Collection getUniqueCards(Game game) { Map cards = new HashMap<>(); - for(UUID cardId: this) { + for (UUID cardId : this) { Card card = game.getCard(cardId); if (!cards.containsKey(card.getName())) { cards.put(card.getName(), card); diff --git a/Mage/src/mage/game/events/ZoneChangeGroupEvent.java b/Mage/src/mage/game/events/ZoneChangeGroupEvent.java index adb3e8cbc4b..fa36abb663e 100644 --- a/Mage/src/mage/game/events/ZoneChangeGroupEvent.java +++ b/Mage/src/mage/game/events/ZoneChangeGroupEvent.java @@ -1,33 +1,33 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.game.events; -import java.util.List; +import java.util.Set; import java.util.UUID; import mage.cards.Card; import mage.constants.Zone; @@ -37,18 +37,18 @@ import mage.constants.Zone; * @author LevelX2 */ public class ZoneChangeGroupEvent extends GameEvent { - + private final Zone fromZone; private final Zone toZone; - private final List cards; + private final Set cards; - public ZoneChangeGroupEvent(List cards, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) { + public ZoneChangeGroupEvent(Set cards, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) { super(EventType.ZONE_CHANGE_GROUP, null, sourceId, playerId); this.fromZone = fromZone; this.toZone = toZone; this.cards = cards; - } - + } + public Zone getFromZone() { return fromZone; } @@ -57,7 +57,7 @@ public class ZoneChangeGroupEvent extends GameEvent { return toZone; } - public List getCards() { + public Set getCards() { return cards; } diff --git a/Mage/src/mage/players/Library.java b/Mage/src/mage/players/Library.java index 190d01782d8..ec7cfc1942a 100644 --- a/Mage/src/mage/players/Library.java +++ b/Mage/src/mage/players/Library.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.players; import java.io.Serializable; @@ -35,6 +34,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Deque; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -65,14 +65,13 @@ public class Library implements Serializable { public Library(final Library lib) { this.emptyDraw = lib.emptyDraw; this.playerId = lib.playerId; - for (UUID id: lib.library) { + for (UUID id : lib.library) { this.library.addLast(id); } } /** - * Don't use this directly. - * Use instead. + * Don't use this directly. Use instead. */ public void shuffle() { UUID[] shuffled = library.toArray(new UUID[0]); @@ -88,7 +87,7 @@ public class Library implements Serializable { /** * Removes the top card of the Library and returns it - * + * * @param game * @return Card * @see Card @@ -133,8 +132,7 @@ public class Library implements Serializable { if (card.getOwnerId().equals(playerId)) { card.setZone(Zone.LIBRARY, game); library.addFirst(card.getId()); - } - else { + } else { game.getPlayer(card.getOwnerId()).getLibrary().putOnTop(card, game); } } @@ -146,8 +144,7 @@ public class Library implements Serializable { library.remove(card.getId()); } library.add(card.getId()); - } - else { + } else { game.getPlayer(card.getOwnerId()).getLibrary().putOnBottom(card, game); } } @@ -166,7 +163,7 @@ public class Library implements Serializable { public void set(Library newLibrary) { library.clear(); - for (UUID card: newLibrary.getCardList()) { + for (UUID card : newLibrary.getCardList()) { library.add(card); } } @@ -177,17 +174,17 @@ public class Library implements Serializable { public List getCards(Game game) { List cards = new ArrayList<>(); - for (UUID cardId: library) { + for (UUID cardId : library) { cards.add(game.getCard(cardId)); } return cards; } - public List getTopCards(Game game, int amount) { - List cards = new ArrayList<>(); + public Set getTopCards(Game game, int amount) { + Set cards = new HashSet<>(); Iterator it = library.iterator(); int count = 0; - while(it.hasNext() && count < amount) { + while (it.hasNext() && count < amount) { UUID cardId = it.next(); Card card = game.getCard(cardId); if (card != null) { @@ -200,7 +197,7 @@ public class Library implements Serializable { public Collection getUniqueCards(Game game) { Map cards = new HashMap<>(); - for (UUID cardId: library) { + for (UUID cardId : library) { Card card = game.getCard(cardId); if (!cards.containsKey(card.getName())) { cards.put(card.getName(), card); @@ -211,7 +208,7 @@ public class Library implements Serializable { public int count(FilterCard filter, Game game) { int result = 0; - for (UUID card: library) { + for (UUID card : library) { if (filter.match(game.getCard(card), game)) { result++; } @@ -219,20 +216,19 @@ public class Library implements Serializable { return result; } - public boolean isEmptyDraw() { return emptyDraw; } public void addAll(Set cards, Game game) { - for (Card card: cards) { + for (Card card : cards) { card.setZone(Zone.LIBRARY, game); library.add(card.getId()); } } public Card getCard(UUID cardId, Game game) { - for (UUID card: library) { + for (UUID card : library) { if (card.equals(cardId)) { return game.getCard(card); } @@ -242,7 +238,7 @@ public class Library implements Serializable { public Card remove(UUID cardId, Game game) { Iterator it = library.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { UUID card = it.next(); if (card.equals(cardId)) { it.remove(); diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index cf94a946082..88aa373b59c 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -626,9 +626,11 @@ public interface Player extends MageItem, Copyable { boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName); - boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game); + boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game); - boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName); + boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName); + + boolean moveCardsToExile(Set cards, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName); /** * Uses card.moveToZone and posts a inform message about moving the card @@ -637,7 +639,6 @@ public interface Player extends MageItem, Copyable { * @param card * @param sourceId * @param game - * @param fromZone if null, this info isn't postet * @return */ boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game); @@ -687,7 +688,7 @@ public interface Player extends MageItem, Copyable { * @param fromZone if null, this info isn't postet * @return */ - boolean moveCardsToGraveyardWithInfo(List cards, Ability source, Game game, Zone fromZone); + boolean moveCardsToGraveyardWithInfo(Set cards, Ability source, Game game, Zone fromZone); /** * Uses card.moveToZone and posts a inform message about moving the card to diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index cbe259f9655..b5b2029a92e 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -859,14 +859,16 @@ public abstract class PlayerImpl implements Player, Serializable { /** * Can be cards or permanents that go to library * - * @param cards + * @param cardsToLibrary * @param game * @param source * @param anyOrder * @return */ @Override - public boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) { + public boolean putCardsOnTopOfLibrary(Cards cardsToLibrary, Game game, Ability source, boolean anyOrder) { + Cards cards = new CardsImpl(cardsToLibrary); // prevent possible ConcurrentModificationException + cards.addAll(cardsToLibrary); if (cards.size() != 0) { if (!anyOrder) { for (UUID cardId : cards) { @@ -2879,7 +2881,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { - ArrayList cardList = new ArrayList<>(); + Set cardList = new HashSet<>(); for (UUID cardId : cards) { if (fromZone == null) { fromZone = game.getState().getZone(cardId); @@ -2906,7 +2908,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { - ArrayList cardList = new ArrayList<>(); + Set cardList = new HashSet<>(); if (card != null) { cardList.add(card); } @@ -2914,12 +2916,12 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game) { + public boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game) { return moveCards(cards, fromZone, toZone, source, game, true); } @Override - public boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { + public boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { if (cards.isEmpty()) { return true; } @@ -2960,6 +2962,20 @@ public abstract class PlayerImpl implements Player, Serializable { } } + @Override + public boolean moveCardsToExile(Set cards, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName) { + if (cards.isEmpty()) { + return true; + } + game.fireEvent(new ZoneChangeGroupEvent(cards, source == null ? null : source.getSourceId(), this.getId(), null, Zone.EXILED)); + boolean result = false; + for (Card card : cards) { + Zone fromZone = game.getState().getZone(card.getId()); + result |= moveCardToExileWithInfo(card, exileId, exileZoneName, source == null ? null : source.getSourceId(), game, fromZone, withName); + } + return result; + } + @Override public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game) { return this.moveCardToHandWithInfo(card, sourceId, game, true); @@ -2974,7 +2990,7 @@ public abstract class PlayerImpl implements Player, Serializable { card = game.getCard(card.getId()); } if (!game.isSimulation()) { - StringBuilder sb = new StringBuilder(this.getLogName()).append(" puts ").append(withName ? card.getLogName() : "a face down card"); + StringBuilder sb = new StringBuilder(this.getLogName()).append(" puts ").append(withName ? card.getLogName() : (card.isFaceDown(game) ? "a face down card" : "a card")); switch (fromZone) { case EXILED: sb.append(" from exile zone "); @@ -2992,7 +3008,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean moveCardsToGraveyardWithInfo(List allCards, Ability source, Game game, Zone fromZone) { + public boolean moveCardsToGraveyardWithInfo(Set allCards, Ability source, Game game, Zone fromZone) { boolean result = true; UUID sourceId = source == null ? null : source.getSourceId(); while (!allCards.isEmpty()) { diff --git a/Mage/src/mage/target/common/TargetCardInLibrary.java b/Mage/src/mage/target/common/TargetCardInLibrary.java index 69221dc3d8e..5d6205e80d3 100644 --- a/Mage/src/mage/target/common/TargetCardInLibrary.java +++ b/Mage/src/mage/target/common/TargetCardInLibrary.java @@ -1,33 +1,33 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.target.common; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -42,7 +42,6 @@ import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; - /** * * @author BetaSteward_at_googlemail.com @@ -86,8 +85,7 @@ public class TargetCardInLibrary extends TargetCard { if (librarySearchLimit == Integer.MAX_VALUE) { cards = targetPlayer.getLibrary().getCards(game); } else { - int maxCards = Math.min(librarySearchLimit, targetPlayer.getLibrary().size()); - cards = targetPlayer.getLibrary().getTopCards(game, maxCards); + cards = new ArrayList<>(targetPlayer.getLibrary().getTopCards(game, librarySearchLimit)); } Collections.sort(cards, new CardNameComparator()); while (!isChosen() && !doneChosing()) { @@ -124,7 +122,6 @@ public class TargetCardInLibrary extends TargetCard { this.librarySearchLimit = librarySearchLimit; } - } class CardNameComparator implements Comparator { From 48195629c9715e678980197eea22917f1b36c60c Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 5 Aug 2015 17:50:47 +0200 Subject: [PATCH 24/24] * Some more rework of card mobement handling. --- Mage.Sets/src/mage/sets/tempest/Lobotomy.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/Mage.Sets/src/mage/sets/tempest/Lobotomy.java b/Mage.Sets/src/mage/sets/tempest/Lobotomy.java index 38c80b50163..f96e3c8b7bb 100644 --- a/Mage.Sets/src/mage/sets/tempest/Lobotomy.java +++ b/Mage.Sets/src/mage/sets/tempest/Lobotomy.java @@ -33,6 +33,8 @@ import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -96,10 +98,10 @@ class LobotomyEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (targetPlayer != null && sourceObject != null && controller != null) { - - // reveal hand of target player + + // reveal hand of target player targetPlayer.revealCards(sourceObject.getName(), targetPlayer.getHand(), game); - + // You choose card other than a basic land card TargetCardInHand target = new TargetCardInHand(filter); target.setNotTarget(true); @@ -107,51 +109,53 @@ class LobotomyEffect extends OneShotEffect { if (controller.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { chosenCard = game.getCard(target.getFirstTarget()); } - - + // Exile all cards with the same name // Building a card filter with the name FilterCard filterNamedCards = new FilterCard(); if (chosenCard != null) { - filterNamedCards.add(new NamePredicate(chosenCard.getName())); + filterNamedCards.add(new NamePredicate(chosenCard.getName())); } else { filterNamedCards.add(new NamePredicate("----")); // so no card matches } - + Cards cardsToExile = new CardsImpl(); // The cards you're searching for must be found and exiled if they're in the graveyard because it's a public zone. // Finding those cards in the hand and library is optional, because those zones are hidden (even if the hand is temporarily revealed). // search cards in graveyard if (chosenCard != null) { for (Card checkCard : targetPlayer.getGraveyard().getCards(game)) { if (checkCard.getName().equals(chosenCard.getName())) { - controller.moveCardToExileWithInfo(checkCard, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); + cardsToExile.add(checkCard); } } - // search cards in hand TargetCardInHand targetCardsHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterNamedCards); controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsHand, source, game); - for(UUID cardId: targetCardsHand.getTargets()) { + for (UUID cardId : targetCardsHand.getTargets()) { Card card = game.getCard(cardId); if (card != null) { - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND, true); + cardsToExile.add(card); } } - } + } // search cards in Library // If the player has no nonland cards in his or her hand, you can still search that player's library and have him or her shuffle it. if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", source, game)) { TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId()); - for(UUID cardId: targetCardsLibrary.getTargets()) { + for (UUID cardId : targetCardsLibrary.getTargets()) { Card card = game.getCard(cardId); if (card != null) { - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); + cardsToExile.add(card); } } - targetPlayer.shuffleLibrary(game); + } + if (!cardsToExile.isEmpty()) { + controller.moveCards(cardsToExile, null, Zone.EXILED, source, game, true); + } + targetPlayer.shuffleLibrary(game); return true; } return false;