From 2d6bcd83f4c6f4acb60f1027afaf5206266861fb Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 16:55:58 +0200 Subject: [PATCH 01/27] xmage 1.4.26V4 --- Mage.Common/src/main/java/mage/utils/MageVersion.java | 2 +- .../src/mage/player/human/HumanPlayer.java | 6 ++++-- .../src/main/java/mage/cards/repository/CardRepository.java | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 0b45f8ca40a..e0c0a9435a3 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/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 = 26; - public final static String MAGE_VERSION_MINOR_PATCH = "V3"; + public final static String MAGE_VERSION_MINOR_PATCH = "V4"; public final static String MAGE_VERSION_INFO = ""; private final int major; 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 751e1739d29..69e89b0c08e 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 @@ -1112,8 +1112,10 @@ public class HumanPlayer extends PlayerImpl { // attack selected default defender declareAttacker(attacker.getId(), attackedDefender, game, false); } -// } else if (response.getInteger() != null) { // Ok or F-Key - + } else if (response.getInteger() != null) { // F-Key + if (checkIfAttackersValid(game)) { + return; + } } else if (response.getBoolean() != null) { // ok button if (checkIfAttackersValid(game)) { return; diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 82248406626..36a866cf23a 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -58,7 +58,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 90; + private static final long CARD_CONTENT_VERSION = 91; private Dao cardDao; private Set classNames; From e15f0206677bb5660ce6f65a37e7a4a52dc45f45 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 22:51:12 +0200 Subject: [PATCH 02/27] Deathgorge Scavenger - Fixed triggered ability. --- .../src/mage/cards/d/DeathgorgeScavenger.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java index 13b6ae13b3f..868409cd850 100644 --- a/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java +++ b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java @@ -34,12 +34,12 @@ import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.Card; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -92,14 +92,16 @@ class DeathgorgeScavengerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Card card = game.getCard(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && card != null) { - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); - if (card.isCreature()) { - controller.gainLife(2, game); - } else { - new BoostSourceEffect(1, 1, Duration.EndOfTurn).apply(game, source); + if (controller != null) { + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (card != null) { + controller.moveCards(card, Zone.EXILED, source, game); + if (card.isCreature()) { + controller.gainLife(2, game); + } else { + game.addEffect(new BoostSourceEffect(1, 1, Duration.EndOfTurn), source); + } } return true; } From 01e4ce2c42836458b418c16d54e53d5c13543485 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 22:56:03 +0200 Subject: [PATCH 03/27] * Marauding Looter - Fixed that the draw discard effect was not optional. --- Mage.Sets/src/mage/cards/m/MaraudingLooter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java index 317c96ced25..c87a6297a66 100644 --- a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java +++ b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java @@ -57,7 +57,7 @@ public class MaraudingLooter extends CardImpl { // Raid - At the beginning of your end step, if you attacked with a creature this turn, you may draw a card. If you do, discard a card. Ability ability = new ConditionalTriggeredAbility( - new BeginningOfEndStepTriggeredAbility(new DrawDiscardControllerEffect(1, 1), TargetController.YOU, false), + new BeginningOfEndStepTriggeredAbility(new DrawDiscardControllerEffect(1, 1, true), TargetController.YOU, false), RaidCondition.instance, "Raid — At the beginning of your end step, " + "if you attacked with a creature this turn, " From c4a342ffcb0fbf7538e2308ab2fd97f1da07aa92 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:41:31 -0400 Subject: [PATCH 04/27] Fixed Fell Flagship (#4002) --- Mage.Sets/src/mage/cards/f/FellFlagship.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/cards/f/FellFlagship.java b/Mage.Sets/src/mage/cards/f/FellFlagship.java index 1726fc2bdcb..c518dd75a15 100644 --- a/Mage.Sets/src/mage/cards/f/FellFlagship.java +++ b/Mage.Sets/src/mage/cards/f/FellFlagship.java @@ -28,6 +28,7 @@ package mage.cards.f; import java.util.UUID; +import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.continuous.BoostControlledEffect; @@ -58,6 +59,8 @@ public class FellFlagship extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.VEHICLE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); // Pirates you control get +1/+0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, filter))); From b819803a4f1fe6dd0c0274cf3f72023667b0c021 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:45:32 -0400 Subject: [PATCH 05/27] Fixed Search for Azcanta --- Mage.Sets/src/mage/cards/s/SearchForAzcanta.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java index 70389391b7c..1fe5f694a8d 100644 --- a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java +++ b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java @@ -64,7 +64,7 @@ public class SearchForAzcanta extends CardImpl { this.addSuperType(SuperType.LEGENDARY); // At the beginning of your upkeep, look at the top card of your library. You may put it into your graveyard. Then if you have seven or more cards in your graveyard, you may transform Search for Azcanta. - Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SearchForAzcantaLookLibraryEffect(), TargetController.YOU, false); + Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SearchForAzcantaLookLibraryEffect(), TargetController.YOU, true); ability.addEffect(new ConditionalOneShotEffect(new TransformSourceEffect(true), new CardsInControllerGraveCondition(7), "Then if you have seven or more cards in your graveyard, you may transform {this}")); this.addAbility(ability); From e646c75487239ea98afe8ed89f1e254d501d0830 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:46:12 -0400 Subject: [PATCH 06/27] Fixed Dowsing Dagger token --- .../main/java/mage/game/permanent/token/DefenderPlantToken.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java b/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java index 046b1daab95..b1915879c10 100644 --- a/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java @@ -52,7 +52,7 @@ public class DefenderPlantToken extends Token { cardType.add(CardType.CREATURE); subtype.add(SubType.PLANT); power = new MageInt(0); - toughness = new MageInt(1); + toughness = new MageInt(2); this.addAbility(DefenderAbility.getInstance()); } From 573f247393aeb25b96bd6055e95ad9a6fc917cb0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:48:12 -0400 Subject: [PATCH 07/27] Fixed Gilded Sentinel --- Mage.Sets/src/mage/cards/g/GildedSentinel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage.Sets/src/mage/cards/g/GildedSentinel.java b/Mage.Sets/src/mage/cards/g/GildedSentinel.java index 060dd11be00..1175fab4a72 100644 --- a/Mage.Sets/src/mage/cards/g/GildedSentinel.java +++ b/Mage.Sets/src/mage/cards/g/GildedSentinel.java @@ -28,6 +28,7 @@ package mage.cards.g; import java.util.UUID; +import mage.MageInt; import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -43,6 +44,9 @@ public class GildedSentinel extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); this.subtype.add(SubType.GOLEM); + + this.power = new MageInt(3); + this.toughness = new MageInt(3); } public GildedSentinel(final GildedSentinel card) { From ff567ed20a1590007907290ef5544468ed48d8da Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:48:35 -0400 Subject: [PATCH 08/27] Fixed Dive Down --- Mage.Sets/src/mage/cards/d/DiveDown.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DiveDown.java b/Mage.Sets/src/mage/cards/d/DiveDown.java index d094dade725..8ce6392e1c8 100644 --- a/Mage.Sets/src/mage/cards/d/DiveDown.java +++ b/Mage.Sets/src/mage/cards/d/DiveDown.java @@ -48,7 +48,7 @@ public class DiveDown extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); // Target creature you control gets +0/+3 and gains hexproof until end of turn. - Effect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn); + Effect effect = new BoostTargetEffect(0, 3, Duration.EndOfTurn); effect.setText("Target creature you control gets +0/+3"); this.getSpellAbility().addEffect(effect); effect = new GainAbilityTargetEffect(HexproofAbility.getInstance(), Duration.EndOfTurn); From c07eedf7522accee83060da99d65bf3da82a6eda Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:50:44 -0400 Subject: [PATCH 09/27] Fixed Entrancing Melody --- Mage.Sets/src/mage/cards/e/EntrancingMelody.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java index b84395188be..8a49d375f06 100644 --- a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java +++ b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java @@ -37,7 +37,6 @@ import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.Duration; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; @@ -65,8 +64,8 @@ public class EntrancingMelody extends CardImpl { if (ability instanceof SpellAbility) { ability.getTargets().clear(); int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X or less"); - filter.add(Predicates.not(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue))); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); ability.addTarget(new TargetCreaturePermanent(filter)); } } From 49f047f70056b2f102d70e17f7cecd12661d2214 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 22:07:48 -0400 Subject: [PATCH 10/27] Fixed Deadeye Tracker possibly giving an error --- Mage.Sets/src/mage/cards/d/DeadeyeTracker.java | 13 ++----------- Mage.Sets/src/mage/cards/n/NullmageAdvocate.java | 6 +++--- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java b/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java index 5915342b3df..405263345ef 100644 --- a/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java +++ b/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java @@ -40,12 +40,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.other.OwnerPredicate; -import mage.target.common.TargetCardInASingleGraveyard; +import mage.target.common.TargetCardInOpponentsGraveyard; /** * @@ -53,12 +50,6 @@ import mage.target.common.TargetCardInASingleGraveyard; */ public class DeadeyeTracker extends CardImpl { - private static final FilterCard filter = new FilterCard("cards from an opponent's graveyard"); - - static { - filter.add(Predicates.not(new OwnerPredicate(TargetController.YOU))); - } - public DeadeyeTracker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); @@ -73,7 +64,7 @@ public class DeadeyeTracker extends CardImpl { Effect effect = new ExploreSourceEffect(); effect.setText("{this} explores"); ability.addEffect(effect); - ability.addTarget(new TargetCardInASingleGraveyard(2, 2, filter)); + ability.addTarget(new TargetCardInOpponentsGraveyard(2, 2, new FilterCard("cards from an opponent's graveyard"), true)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java b/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java index 74edc354117..951a8c5ad04 100644 --- a/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java +++ b/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java @@ -54,7 +54,7 @@ import java.util.UUID; public class NullmageAdvocate extends CardImpl { public NullmageAdvocate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.INSECT); this.subtype.add(SubType.DRUID); this.power = new MageInt(2); @@ -64,11 +64,11 @@ public class NullmageAdvocate extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return two target cards from an opponent's graveyard to his or her hand"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); - + effect = new DestroyTargetEffect("Destroy target artifact or enchantment"); effect.setTargetPointer(new SecondTargetPointer()); ability.addEffect(effect); - ability.addTarget(new TargetCardInOpponentsGraveyard(2,2, new FilterCard("two target cards from an opponent's graveyard"), true)); + ability.addTarget(new TargetCardInOpponentsGraveyard(2, 2, new FilterCard("cards from an opponent's graveyard"), true)); ability.addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); this.addAbility(ability); } From 77110bbc5a50c9312781957c2e5b9e560f4e3dfe Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 23:07:33 -0400 Subject: [PATCH 11/27] Fixed Admiral Beckett Brass trigger (#4006) --- .../src/mage/cards/a/AdmiralBeckettBrass.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java index 77f6f600259..84b6dcd8c19 100644 --- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -53,6 +53,7 @@ import mage.filter.predicate.Predicate; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetNonlandPermanent; @@ -85,9 +86,8 @@ public class AdmiralBeckettBrass extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); // At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn. - Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom) - .setText("gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"), TargetController.YOU, false); - ability.addTarget(new TargetNonlandPermanent()); + Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom), TargetController.YOU, false); + ability.addTarget(new TargetNonlandPermanent(new FilterNonlandPermanent("nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"))); originalId = ability.getOriginalId(); this.addAbility(ability, new DamagedByPiratesWatcher()); } @@ -138,15 +138,17 @@ class DamagedByPiratesWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER && event.getFlag()) { - Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (creature != null && creature.getSubtype(game).contains(SubType.PIRATE)) { - if (damageSourceIds.keySet().contains(event.getTargetId())) { - damageSourceIds.get(event.getTargetId()).add(creature.getId()); - } else { - Set creatureSet = new HashSet(); - creatureSet.add(creature.getId()); - damageSourceIds.put(event.getTargetId(), creatureSet); + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { + if (((DamagedPlayerEvent) event).isCombatDamage()) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null && creature.getSubtype(game).contains(SubType.PIRATE)) { + if (damageSourceIds.keySet().contains(event.getTargetId())) { + damageSourceIds.get(event.getTargetId()).add(creature.getId()); + } else { + Set creatureSet = new HashSet(); + creatureSet.add(creature.getId()); + damageSourceIds.put(event.getTargetId(), creatureSet); + } } } } From 60f7b5bcbf9f0c4952a5ab46d058b03acc54319c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 23:18:08 -0400 Subject: [PATCH 12/27] Fixed Sunrise Seeker --- Mage.Sets/src/mage/cards/s/SunriseSeeker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SunriseSeeker.java b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java index 66deabb826a..c5194fb74aa 100644 --- a/Mage.Sets/src/mage/cards/s/SunriseSeeker.java +++ b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.keyword.ExploreSourceEffect; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; @@ -55,7 +55,7 @@ public class SunriseSeeker extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // When Sunrise Seeker enters the battlefield, it explores. - this.addAbility(new EntersBattlefieldAbility(new ExploreSourceEffect())); + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); } public SunriseSeeker(final SunriseSeeker card) { From 1d5d201d296a5c7ec8d681fdd522f1f9c42d3ad0 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 11:01:04 +0200 Subject: [PATCH 13/27] * Iconic Masters - Fixed some wrong rarities. --- Mage.Sets/src/mage/sets/IconicMasters.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/sets/IconicMasters.java b/Mage.Sets/src/mage/sets/IconicMasters.java index 129666276b3..835ea5dd440 100644 --- a/Mage.Sets/src/mage/sets/IconicMasters.java +++ b/Mage.Sets/src/mage/sets/IconicMasters.java @@ -24,8 +24,7 @@ * 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; import mage.cards.ExpansionSet; @@ -54,9 +53,9 @@ public class IconicMasters extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - + cards.add(new SetCardInfo("Scion of Ugin", 1, Rarity.COMMON, mage.cards.s.ScionOfUgin.class)); - cards.add(new SetCardInfo("Abzan Battle Priest", 2, Rarity.COMMON, mage.cards.a.AbzanBattlePriest.class)); + cards.add(new SetCardInfo("Abzan Battle Priest", 2, Rarity.UNCOMMON, mage.cards.a.AbzanBattlePriest.class)); cards.add(new SetCardInfo("Abzan Falconer", 3, Rarity.UNCOMMON, mage.cards.a.AbzanFalconer.class)); cards.add(new SetCardInfo("Ainok Bond-Kin", 4, Rarity.COMMON, mage.cards.a.AinokBondKin.class)); cards.add(new SetCardInfo("Ajani's Pridemate", 5, Rarity.UNCOMMON, mage.cards.a.AjanisPridemate.class)); @@ -197,7 +196,7 @@ public class IconicMasters extends ExpansionSet { cards.add(new SetCardInfo("Monastery Swiftspear", 140, Rarity.UNCOMMON, mage.cards.m.MonasterySwiftspear.class)); cards.add(new SetCardInfo("Pillar of Flame", 141, Rarity.COMMON, mage.cards.p.PillarOfFlame.class)); cards.add(new SetCardInfo("Prodigal Pyromancer", 142, Rarity.UNCOMMON, mage.cards.p.ProdigalPyromancer.class)); - cards.add(new SetCardInfo("Rift Bolt", 143, Rarity.COMMON, mage.cards.r.RiftBolt.class)); + cards.add(new SetCardInfo("Rift Bolt", 143, Rarity.UNCOMMON, mage.cards.r.RiftBolt.class)); cards.add(new SetCardInfo("Ryusei, the Falling Star", 144, Rarity.RARE, mage.cards.r.RyuseiTheFallingStar.class)); cards.add(new SetCardInfo("Scourge of Valkas", 145, Rarity.RARE, mage.cards.s.ScourgeOfValkas.class)); cards.add(new SetCardInfo("Splatter Thug", 146, Rarity.COMMON, mage.cards.s.SplatterThug.class)); @@ -227,7 +226,7 @@ public class IconicMasters extends ExpansionSet { cards.add(new SetCardInfo("Ivy Elemental", 170, Rarity.COMMON, mage.cards.i.IvyElemental.class)); cards.add(new SetCardInfo("Jaddi Offshoot", 171, Rarity.COMMON, mage.cards.j.JaddiOffshoot.class)); cards.add(new SetCardInfo("Jugan, the Rising Star", 172, Rarity.RARE, mage.cards.j.JuganTheRisingStar.class)); - cards.add(new SetCardInfo("Lead the Stampede", 173, Rarity.UNCOMMON, mage.cards.l.LeadTheStampede.class)); + cards.add(new SetCardInfo("Lead the Stampede", 173, Rarity.COMMON, mage.cards.l.LeadTheStampede.class)); cards.add(new SetCardInfo("Lotus Cobra", 174, Rarity.RARE, mage.cards.l.LotusCobra.class)); cards.add(new SetCardInfo("Lure", 175, Rarity.UNCOMMON, mage.cards.l.Lure.class)); cards.add(new SetCardInfo("Nantuko Shaman", 176, Rarity.COMMON, mage.cards.n.NantukoShaman.class)); From ae0d87b7ecf2d245125e877450a2282dd1e01145 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 11:33:16 +0200 Subject: [PATCH 14/27] * Image download - added Ixalan & Iconic Masters to Scryfall and mythicspoilers.com. --- .../card/dl/sources/MythicspoilerComSource.java | 1 + .../card/dl/sources/ScryfallImageSource.java | 16 +++++++++++++++- .../plugins/card/images/CardDownloadData.java | 6 +++--- .../plugins/card/images/DownloadPictures.java | 8 ++++++-- .../src/main/resources/image.url.properties | 2 +- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index 9fc3658775a..03ba31aac40 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -251,6 +251,7 @@ public enum MythicspoilerComSource implements CardImageSource { supportedSets.add("E01"); supportedSets.add("HOU"); supportedSets.add("C17"); + supportedSets.add("IMA"); supportedSets.add("XLN"); sets = new LinkedHashMap<>(); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index a54e5c0118f..759a9bdacf4 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -199,11 +199,25 @@ public enum ScryfallImageSource implements CardImageSource { supportedSets.add("E01"); supportedSets.add("HOU"); supportedSets.add("C17"); + supportedSets.add("XLN"); +// supportedSets.add("DDT"); + supportedSets.add("IMA"); +// supportedSets.add("E02"); +// supportedSets.add("V17"); +// supportedSets.add("UST"); +// supportedSets.add("RIX"); +// supportedSets.add("A25"); +// supportedSets.add("DOM"); +// supportedSets.add("M19"); + } @Override public String generateURL(CardDownloadData card) throws Exception { - return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/" + card.getCollectorId() + "?format=image"; + return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/" + + card.getCollectorId() + + (card.isSecondSide() ? "b" : "") + + "?format=image"; } @Override diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java index 6c70b198107..9956f8e10ff 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java @@ -40,7 +40,7 @@ public class CardDownloadData { } public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token, boolean twoFacedCard, boolean secondSide) { - this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, token, false, false, ""); + this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, token, twoFacedCard, secondSide, ""); } public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token, boolean twoFacedCard, boolean secondSide, String tokenClassName) { @@ -72,7 +72,7 @@ public class CardDownloadData { this.usesVariousArt = card.usesVariousArt; this.tokenSetCode = card.tokenSetCode; this.tokenDescriptor = card.tokenDescriptor; - this.tokenClassName = tokenClassName; + this.tokenClassName = card.tokenClassName; this.fileName = card.fileName; } @@ -163,7 +163,7 @@ public class CardDownloadData { public String getTokenDescriptor() { return tokenDescriptor; } - + public void setTokenClassName(String tokenClassName) { this.tokenClassName = tokenClassName; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index d993eec652d..5de6018be06 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -429,9 +429,13 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (card.getSecondSideName() == null || card.getSecondSideName().trim().isEmpty()) { throw new IllegalStateException("Second side card can't have empty name."); } + url = new CardDownloadData(card.getSecondSideName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), true); url.setType2(isType2); allCardsUrls.add(url); + if (card.getSetCode().equals("XLN")) { + logger.info(card.getSetCode() + "second side: " + card.getSecondSideName() + " -name: " + card.getName()); + } } if (card.isFlipCard()) { if (card.getFlipCardName() == null || card.getFlipCardName().trim().isEmpty()) { @@ -444,11 +448,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab allCardsUrls.add(cardDownloadData); } } else if (card.getCardNumber().isEmpty() || "0".equals(card.getCardNumber())) { - System.err.println("There was a critical error!"); logger.error("Card has no collector ID and won't be sent to client: " + card.getName()); } else if (card.getSetCode().isEmpty()) { - System.err.println("There was a critical error!"); logger.error("Card has no set name and won't be sent to client:" + card.getName()); + } else { + logger.info("Card was not selected: " + card.getName()); } }); allCardsUrls.addAll(getTokenCardUrls()); diff --git a/Mage.Client/src/main/resources/image.url.properties b/Mage.Client/src/main/resources/image.url.properties index 8b2b31bb074..0ded050d87f 100644 --- a/Mage.Client/src/main/resources/image.url.properties +++ b/Mage.Client/src/main/resources/image.url.properties @@ -74,6 +74,6 @@ dd3evg=ddaevg dd3gvl=ddagvl dd3jvc=ddajvc # Remove setname as soon as the images can be downloaded -ignore.urls=TOK,DDT,V17,IMA,RIX,E02,M19,M25,DOM,UST,H17 +ignore.urls=TOK,DDT,V17,RIX,E02,M19,M25,DOM,UST,H17 # sets ordered by release time (newest goes first) token.lookup.order=M19,M25,DOM,E02,RIX,UST,XLN,IMA,H17,C17,V17,E01,DDT,CMA,HOU,MM3,DDS,AKH,DD3DVD,DD3EVG,DD3GVL,DD3JVC,H09,AER,PCA,C16,V16,MPS,KLD,DDR,CN2,EMN,EMA,SOI,DDQ,CP,CMA,ARENA,SUS,APAC,EURO,UGIN,C15,OGW,EXP,DDP,BFZ,DRB,V09,V10,V11,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC \ No newline at end of file From 3622206cf1ad9dc1f378b6b3c62b3323785e176a Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 11:34:50 +0200 Subject: [PATCH 15/27] * Image download - added Ixalan & Iconic Masters to Scryfall and mythicspoilers.com. --- .../java/org/mage/plugins/card/images/DownloadPictures.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 5de6018be06..0895b792198 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -433,9 +433,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab url = new CardDownloadData(card.getSecondSideName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), true); url.setType2(isType2); allCardsUrls.add(url); - if (card.getSetCode().equals("XLN")) { - logger.info(card.getSetCode() + "second side: " + card.getSecondSideName() + " -name: " + card.getName()); - } } if (card.isFlipCard()) { if (card.getFlipCardName() == null || card.getFlipCardName().trim().isEmpty()) { From cab5919203adcba0119e262b86f81af4bfda6ab8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 09:02:00 -0400 Subject: [PATCH 16/27] Fixed Duskborne Skymarcher targeting non-attackers --- Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java index 32423191b86..4eb31fefe5b 100644 --- a/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java +++ b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java @@ -71,7 +71,7 @@ public class DuskborneSkymarcher extends CardImpl { // {W}, {T}: Target attacking vampire gets +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{W}")); ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetCreaturePermanent()); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } From 3a3ca3ba96117b5dd68f14a2c96432cbef39fddb Mon Sep 17 00:00:00 2001 From: spjspj Date: Sun, 17 Sep 2017 23:26:23 +1000 Subject: [PATCH 17/27] Fix Sunbird's Invocation --- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index aca1f428e36..41cf909e38e 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -111,7 +111,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { public SunbirdsInvocationEffect() { super(Outcome.PutCardInPlay); - staticText = "reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; } public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { @@ -139,10 +139,9 @@ class SunbirdsInvocationEffect extends OneShotEffect { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { if (controller.chooseUse(outcome, "Do you wish to cast " + card.getName(), source, game)) { - Card copy = game.copyCard(card, source, source.getControllerId()); - controller.cast(copy.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true); + cards.remove(card); } - return true; } } } From 8b1ec81c7a8fd95bdbfa4476c629cf4ff802ae4c Mon Sep 17 00:00:00 2001 From: spjspj Date: Sun, 17 Sep 2017 23:29:24 +1000 Subject: [PATCH 18/27] Fix Sunbird's Invocation --- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 41cf909e38e..aa541a7d06b 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -111,7 +111,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { public SunbirdsInvocationEffect() { super(Outcome.PutCardInPlay); - staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + staticText = "reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; } public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { From d5166f60410b516d516f20bc84d49141fa5405ee Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 10:28:44 -0400 Subject: [PATCH 19/27] Fixed Imperial Aerosaur double pumping --- Mage.Sets/src/mage/cards/i/ImperialAerosaur.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java index 5fbffa9852b..a40cf227aae 100644 --- a/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java +++ b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java @@ -72,7 +72,6 @@ public class ImperialAerosaur extends CardImpl { Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); effect.setText("another target creature you control gets +1/+1"); EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(effect); - ability.addEffect(effect); effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); effect.setText("and gains flying until end of turn"); ability.addEffect(effect); From b8d24883e831dc948db8f5a51d1403ec094433eb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 10:33:12 -0400 Subject: [PATCH 20/27] Fixed Sun-Crowned Hunters text --- Mage.Sets/src/mage/cards/s/SunCrownedHunters.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java b/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java index d9fa321f933..a433bbd376a 100644 --- a/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java +++ b/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java @@ -53,7 +53,9 @@ public class SunCrownedHunters extends CardImpl { this.toughness = new MageInt(4); // Enrage — Whenever Sun-Crowned Hunters is dealt damage, it deals 3 damage to target opponent. - Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3, true, "it"), false, true); + Ability ability = new DealtDamageToSourceTriggeredAbility( + Zone.BATTLEFIELD, new DamageTargetEffect(3).setText("it deals 3 damage to target opponent"), false, true + ); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } From 9a57480f4b32231cdae497a3a3d8db7db6cfd69f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:42:59 -0400 Subject: [PATCH 21/27] Fixed Dual Nature --- Mage.Sets/src/mage/cards/d/DualNature.java | 234 ++++++++++++++++++ Mage.Sets/src/mage/sets/Prophecy.java | 1 + .../LeavesBattlefieldAllTriggeredAbility.java | 25 +- Utils/keywords.txt | 2 +- 4 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/d/DualNature.java diff --git a/Mage.Sets/src/mage/cards/d/DualNature.java b/Mage.Sets/src/mage/cards/d/DualNature.java new file mode 100644 index 00000000000..23da3a36382 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DualNature.java @@ -0,0 +1,234 @@ +/* + * 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.d; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility; +import mage.abilities.common.ZoneChangeTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.ExileAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class DualNature extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature"); + + static { + filter.add(Predicates.not(new TokenPredicate())); + } + + public DualNature(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}"); + + // Whenever a nontoken creature enters the battlefield, its controller creates a token that's a copy of that creature. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new DualNatureCreateTokenEffect(), filter, false, SetTargetPointer.PERMANENT, + "Whenever a nontoken creature enters the battlefield, its controller creates a token that's a copy of that creature." + )); + + // Whenever a nontoken creature leaves the battlefield, exile all tokens with the same name as that creature. + this.addAbility(new LeavesBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new DualNatureCreatureLeavesEffect(), filter, false, SetTargetPointer.PERMANENT + )); + + // When Dual Nature leaves the battlefield, exile all tokens created with Dual Nature. + this.addAbility(new DualNatureLeavesBattlefieldTriggeredAbility()); + } + + public DualNature(final DualNature card) { + super(card); + } + + @Override + public DualNature copy() { + return new DualNature(this); + } +} + +class DualNatureCreateTokenEffect extends OneShotEffect { + + DualNatureCreateTokenEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "its controller creates a token that's a copy of that creature"; + } + + DualNatureCreateTokenEffect(final DualNatureCreateTokenEffect effect) { + super(effect); + } + + @Override + public DualNatureCreateTokenEffect copy() { + return new DualNatureCreateTokenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(permanent.getControllerId()); + effect.setTargetPointer(targetPointer); + effect.apply(game, source); + Object object = game.getState().getValue(CardUtil.getCardZoneString("_tokensCreated", source.getSourceId(), game)); + Set tokensCreated; + if (object != null) { + tokensCreated = (Set) object; + } else { + tokensCreated = new HashSet<>(); + } + for (Permanent perm : effect.getAddedPermanent()) { + if (perm != null) { + tokensCreated.add(perm.getId()); + } + } + game.getState().setValue(CardUtil.getCardZoneString("_tokensCreated", source.getSourceId(), game), tokensCreated); + } + return true; + } +} + +class DualNatureCreatureLeavesEffect extends OneShotEffect { + + DualNatureCreatureLeavesEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "exile all tokens with the same name as that creature"; + } + + DualNatureCreatureLeavesEffect(final DualNatureCreatureLeavesEffect effect) { + super(effect); + } + + @Override + public DualNatureCreatureLeavesEffect copy() { + return new DualNatureCreatureLeavesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); + if (creature != null) { + FilterPermanent filter = new FilterPermanent(); + filter.add(new TokenPredicate()); + filter.add(new NamePredicate(creature.getName())); + new ExileAllEffect(filter).apply(game, source); + return true; + } + return false; + } +} + +class DualNatureLeavesBattlefieldTriggeredAbility extends ZoneChangeTriggeredAbility { + + DualNatureLeavesBattlefieldTriggeredAbility() { + super(Zone.BATTLEFIELD, null, new DualNatureExileEffect(), "When {this} leaves the battlefield, ", false); + } + + DualNatureLeavesBattlefieldTriggeredAbility(DualNatureLeavesBattlefieldTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (super.checkTrigger(event, game)) { + for (Effect effect : this.getEffects()) { + if (effect instanceof DualNatureExileEffect) { + ((DualNatureExileEffect) effect).setCardZoneString(CardUtil.getCardZoneString("_tokensCreated", this.getSourceId(), game, true)); + } + } + return true; + } + return false; + } + + @Override + public DualNatureLeavesBattlefieldTriggeredAbility copy() { + return new DualNatureLeavesBattlefieldTriggeredAbility(this); + } +} + +class DualNatureExileEffect extends OneShotEffect { + + private String cardZoneString; + + DualNatureExileEffect() { + super(Outcome.Benefit); + this.staticText = "exile all tokens created with {this}."; + } + + DualNatureExileEffect(final DualNatureExileEffect effect) { + super(effect); + this.cardZoneString = effect.cardZoneString; + } + + @Override + public DualNatureExileEffect copy() { + return new DualNatureExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Object object = game.getState().getValue(cardZoneString); + if (object != null) { + Set tokensCreated = (Set) object; + for (UUID tokenId : tokensCreated) { + Permanent token = game.getPermanent(tokenId); + if (token != null) { + token.destroy(source.getSourceId(), game, true); + } + } + } + return true; + } + + public void setCardZoneString(String cardZoneString) { + this.cardZoneString = cardZoneString; + } +} diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 0a6bea024a9..b238baeb123 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -81,6 +81,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Despoil", 62, Rarity.COMMON, mage.cards.d.Despoil.class)); cards.add(new SetCardInfo("Devastate", 87, Rarity.COMMON, mage.cards.d.Devastate.class)); cards.add(new SetCardInfo("Diving Griffin", 6, Rarity.COMMON, mage.cards.d.DivingGriffin.class)); + cards.add(new SetCardInfo("Dual Nature", 112, Rarity.RARE, mage.cards.d.DualNature.class)); cards.add(new SetCardInfo("Entangler", 7, Rarity.UNCOMMON, mage.cards.e.Entangler.class)); cards.add(new SetCardInfo("Excavation", 33, Rarity.UNCOMMON, mage.cards.e.Excavation.class)); cards.add(new SetCardInfo("Fault Riders", 88, Rarity.COMMON, mage.cards.f.FaultRiders.class)); diff --git a/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java index 2c056774679..5ed3b300b7b 100644 --- a/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java @@ -30,12 +30,14 @@ package mage.abilities.common; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -44,6 +46,7 @@ import mage.game.permanent.Permanent; public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { protected FilterPermanent filter; + protected SetTargetPointer setTargetPointer; public LeavesBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter) { this(effect, filter, false); @@ -54,13 +57,19 @@ public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { } public LeavesBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional) { + this(zone, effect, filter, optional, SetTargetPointer.NONE); + } + + public LeavesBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, SetTargetPointer setTargetPointer) { super(zone, effect, optional); this.filter = filter; + this.setTargetPointer = setTargetPointer; } public LeavesBattlefieldAllTriggeredAbility(final LeavesBattlefieldAllTriggeredAbility ability) { super(ability); filter = ability.filter; + setTargetPointer = ability.setTargetPointer; } @Override @@ -79,8 +88,20 @@ public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { if (zEvent.getFromZone() == Zone.BATTLEFIELD) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); - if (permanent != null) { - return filter.match(permanent, getSourceId(), getControllerId(), game); + if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) { + if (setTargetPointer != SetTargetPointer.NONE) { + for (Effect effect : this.getEffects()) { + switch (setTargetPointer) { + case PERMANENT: + effect.setTargetPointer(new FixedTarget(permanent.getId())); + break; + case PLAYER: + effect.setTargetPointer(new FixedTarget(permanent.getControllerId())); + break; + } + } + } + return true; } } return false; diff --git a/Utils/keywords.txt b/Utils/keywords.txt index fa26cf29240..f2c980846b1 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -54,7 +54,7 @@ Lifelink|instance| Living weapon|new| Madness|card, cost| Melee|new| -Menace|instance| +Menace|new| Miracle|cost| Mountaincycling|cost| Mountainwalk|new| From f58cd9ef3d9564684b9b09746301398d914ba1ef Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:50:31 -0400 Subject: [PATCH 22/27] Fixed Angrath's Marauders not doubling damage --- Mage.Sets/src/mage/cards/a/AngrathsMarauders.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java index a08e15a0738..e6e12b2eec5 100644 --- a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java +++ b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java @@ -50,7 +50,7 @@ public class AngrathsMarauders extends CardImpl { public AngrathsMarauders(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); - + this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.PIRATE); this.power = new MageInt(4); @@ -69,6 +69,7 @@ public class AngrathsMarauders extends CardImpl { return new AngrathsMarauders(this); } } + class AngrathsMaraudersEffect extends ReplacementEffectImpl { public AngrathsMaraudersEffect() { @@ -96,11 +97,11 @@ class AngrathsMaraudersEffect extends ReplacementEffectImpl { return true; } return false; - } - + } + @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getSourceId().equals(source.getControllerId()); + return game.getControllerId(event.getSourceId()).equals(source.getControllerId()); } @Override From 4385aae8deafa236db22d0bd69f5af97579063e1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:54:32 -0400 Subject: [PATCH 23/27] Fixed Belligerent Brontodon to only affect your creatures --- .../mage/cards/b/BelligerentBrontodon.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java index f1a1b50e254..df036bce3bf 100644 --- a/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java +++ b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java @@ -37,7 +37,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; /** @@ -54,7 +54,7 @@ public class BelligerentBrontodon extends CardImpl { this.toughness = new MageInt(6); // Each creature you control assigns combat damage equal to its toughness rather than its power. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MilitantDinosaurCombatDamageRuleEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BelligerentBrontodonCombatDamageRuleEffect())); } public BelligerentBrontodon(final BelligerentBrontodon card) { @@ -67,31 +67,27 @@ public class BelligerentBrontodon extends CardImpl { } } -class MilitantDinosaurCombatDamageRuleEffect extends ContinuousEffectImpl { +class BelligerentBrontodonCombatDamageRuleEffect extends ContinuousEffectImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); - - static { - filter.add(new ControllerPredicate(TargetController.YOU)); - } - - public MilitantDinosaurCombatDamageRuleEffect() { + public BelligerentBrontodonCombatDamageRuleEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment); staticText = "Each creature you control assigns combat damage equal to its toughness rather than its power"; } - public MilitantDinosaurCombatDamageRuleEffect(final MilitantDinosaurCombatDamageRuleEffect effect) { + public BelligerentBrontodonCombatDamageRuleEffect(final BelligerentBrontodonCombatDamageRuleEffect effect) { super(effect); } @Override - public MilitantDinosaurCombatDamageRuleEffect copy() { - return new MilitantDinosaurCombatDamageRuleEffect(this); + public BelligerentBrontodonCombatDamageRuleEffect copy() { + return new BelligerentBrontodonCombatDamageRuleEffect(this); } @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { // Change the rule + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ControllerIdPredicate(source.getControllerId())); game.getCombat().setUseToughnessForDamage(true); game.getCombat().addUseToughnessForDamageFilter(filter); return true; From ff4445d1812b71e44bf835b998ac7bc10bb375dc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:56:01 -0400 Subject: [PATCH 24/27] Fixed Deadeye Quartermaster not searching for vehicles --- Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java index c99d19e5e60..049f6915fad 100644 --- a/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java +++ b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java @@ -49,7 +49,10 @@ public class DeadeyeQuartermaster extends CardImpl { private static final FilterCard filter = new FilterCard("an Equipment or Vehicle card"); static { - filter.add(Predicates.or(new SubtypePredicate(SubType.EQUIPMENT), new SubtypePredicate(SubType.EQUIPMENT))); + filter.add(Predicates.or( + new SubtypePredicate(SubType.EQUIPMENT), + new SubtypePredicate(SubType.VEHICLE) + )); } public DeadeyeQuartermaster(UUID ownerId, CardSetInfo setInfo) { From 0b5bd900a6875069debc8dcc5867dc8eefa972c1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 13:22:42 -0400 Subject: [PATCH 25/27] Fixed Primal Wellspring and Pyromancer's Goggles being optional triggers --- Mage.Sets/src/mage/cards/p/PrimalWellspring.java | 2 +- Mage.Sets/src/mage/cards/p/PyromancersGoggles.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java index fc8793547e8..cbdbae5b85c 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java +++ b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java @@ -81,7 +81,7 @@ class PyrimalWellspringTriggeredAbility extends TriggeredAbilityImpl { String abilityOriginalId; public PyrimalWellspringTriggeredAbility(UUID abilityOriginalId, Effect effect) { - super(Zone.ALL, effect, true); + super(Zone.ALL, effect, false); this.abilityOriginalId = abilityOriginalId.toString(); } diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java index 742d616a057..fd658c276eb 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java @@ -54,7 +54,7 @@ import mage.target.targetpointer.FixedTarget; public class PyromancersGoggles extends CardImpl { public PyromancersGoggles(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); addSuperType(SuperType.LEGENDARY); // {T}: Add {R} to your mana pool. @@ -89,7 +89,7 @@ class PyromancersGogglesTriggeredAbility extends TriggeredAbilityImpl { String abilityOriginalId; public PyromancersGogglesTriggeredAbility(UUID abilityOriginalId, Effect effect) { - super(Zone.ALL, effect, true); + super(Zone.ALL, effect, false); this.abilityOriginalId = abilityOriginalId.toString(); } From ea4ff44ed78d57da84b0f854744966864a367433 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 14:04:42 -0400 Subject: [PATCH 26/27] Implemented Iridescent Drake --- .../src/mage/cards/i/IridescentDrake.java | 117 ++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 1 + 2 files changed, 118 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/IridescentDrake.java diff --git a/Mage.Sets/src/mage/cards/i/IridescentDrake.java b/Mage.Sets/src/mage/cards/i/IridescentDrake.java new file mode 100644 index 00000000000..223ddb3276e --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IridescentDrake.java @@ -0,0 +1,117 @@ +/* + * 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.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.predicate.other.AuraCardCanAttachToPermanentId; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInGraveyard; + +/** + * + * @author TheElk801 + */ +public class IridescentDrake extends CardImpl { + + public IridescentDrake(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.DRAKE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Iridescent Drake enters the battlefield, put target Aura card from a graveyard onto the battlefield under your control attached to Iridescent Drake. + Ability ability = new EntersBattlefieldTriggeredAbility(new IridescentDrakeEffect()); + ability.addTarget(new TargetCardInGraveyard()); + this.addAbility(ability); + } + + public IridescentDrake(final IridescentDrake card) { + super(card); + } + + @Override + public IridescentDrake copy() { + return new IridescentDrake(this); + } +} + +class IridescentDrakeEffect extends OneShotEffect { + + public IridescentDrakeEffect() { + super(Outcome.Benefit); + this.staticText = "put target Aura card from a graveyard onto the battlefield under your control attached to {this}"; + } + + public IridescentDrakeEffect(final IridescentDrakeEffect effect) { + super(effect); + } + + @Override + public IridescentDrakeEffect copy() { + return new IridescentDrakeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + Card targetAuraCard = game.getCard(source.getFirstTarget()); + if (controller != null + && permanent != null + && controller.canRespond() + && targetAuraCard != null + && new AuraCardCanAttachToPermanentId(permanent.getId()).apply(targetAuraCard, game)) { + Target target = targetAuraCard.getSpellAbility().getTargets().get(0); + if (target != null) { + game.getState().setValue("attachTo:" + targetAuraCard.getId(), permanent); + controller.moveCards(targetAuraCard, Zone.BATTLEFIELD, source, game); + return permanent.addAttachment(targetAuraCard.getId(), game); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 87ed6e299a5..e05b5e775aa 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -104,6 +104,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Hunting Moa", 109, Rarity.UNCOMMON, mage.cards.h.HuntingMoa.class)); cards.add(new SetCardInfo("Illuminated Wings", 34, Rarity.COMMON, mage.cards.i.IlluminatedWings.class)); cards.add(new SetCardInfo("Impatience", 88, Rarity.RARE, mage.cards.i.Impatience.class)); + cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); cards.add(new SetCardInfo("Junk Diver", 132, Rarity.RARE, mage.cards.j.JunkDiver.class)); cards.add(new SetCardInfo("Keldon Champion", 90, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); cards.add(new SetCardInfo("Keldon Vandals", 91, Rarity.COMMON, mage.cards.k.KeldonVandals.class)); From 1fb37a3834d96b373bd5ac5130a6cc5b27767e04 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 14:49:30 -0400 Subject: [PATCH 27/27] fixed Sunbird's Invocation not using LKI --- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index aa541a7d06b..e451faaa090 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -92,7 +92,7 @@ class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbi if (spell != null && spell.getFromZone() == Zone.HAND) { if (spell.getCard() != null) { for (Effect effect : getEffects()) { - effect.setTargetPointer(new FixedTarget(spell.getId())); + effect.setTargetPointer(new FixedTarget(spell.getId(), spell.getZoneChangeCounter(game))); } return true; } @@ -126,7 +126,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { return false; } Cards cards = new CardsImpl(); - int xValue = game.getStack().getSpell(getTargetPointer().getFirst(game, source)).getConvertedManaCost(); + int xValue = game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.STACK).getConvertedManaCost(); cards.addAll(controller.getLibrary().getTopCards(game, xValue)); if (!cards.isEmpty()) { controller.revealCards(sourceObject.getIdName(), cards, game);