From e52e7f23e9483fa525bb1b45379755c9f0e86ee2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 27 Aug 2017 14:09:03 -0400 Subject: [PATCH 1/8] Fixed bug #3491 --- .../src/mage/cards/d/DetentionSphere.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DetentionSphere.java b/Mage.Sets/src/mage/cards/d/DetentionSphere.java index aabef80c95..835f494d8c 100644 --- a/Mage.Sets/src/mage/cards/d/DetentionSphere.java +++ b/Mage.Sets/src/mage/cards/d/DetentionSphere.java @@ -33,7 +33,7 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.effects.common.ReturnFromExileForSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -48,8 +48,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; - - +import mage.util.CardUtil; +import org.apache.log4j.Logger; /** * @@ -58,13 +58,13 @@ import mage.target.TargetPermanent; public class DetentionSphere extends CardImpl { static final protected FilterPermanent filter = new FilterNonlandPermanent("nonland permanent not named Detention Sphere"); + static { filter.add(Predicates.not(new NamePredicate("Detention Sphere"))); } public DetentionSphere(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{U}"); // When Detention Sphere enters the battlefield, you may exile // target nonland permanent not named Detention Sphere and all @@ -73,7 +73,6 @@ public class DetentionSphere extends CardImpl { ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); - // When Detention Sphere leaves the battlefield, return the exiled // cards to the battlefield under their owner's control. this.addAbility(new LeavesBattlefieldTriggeredAbility(new DetentionSphereLeavesEffect(), false)); @@ -91,7 +90,6 @@ public class DetentionSphere extends CardImpl { class DetentionSphereEntersEffect extends OneShotEffect { - public DetentionSphereEntersEffect() { super(Outcome.Exile); staticText = "you may exile target nonland permanent not named Detention Sphere and all other permanents with the same name as that permanent"; @@ -103,7 +101,7 @@ class DetentionSphereEntersEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - UUID exileId = source.getSourceId(); + UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); @@ -143,15 +141,18 @@ class DetentionSphereLeavesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - UUID exileId = source.getSourceId(); - ExileZone exile = game.getExile().getExileZone(exileId); - if (exile != null) { - exile = exile.copy(); - for (UUID cardId : exile) { - Card card = game.getCard(cardId); - card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), card.getOwnerId()); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null && controller != null) { + Permanent permanentLeftBattlefield = (Permanent) getValue("permanentLeftBattlefield"); + if (permanentLeftBattlefield == null) { + Logger.getLogger(ReturnFromExileForSourceEffect.class).error("Permanent not found: " + sourceObject.getName()); + return false; + } + ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), permanentLeftBattlefield.getZoneChangeCounter(game))); + if (exile != null) { + controller.moveCards(exile.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); } - game.getExile().getExileZone(exileId).clear(); return true; } return false; @@ -161,4 +162,4 @@ class DetentionSphereLeavesEffect extends OneShotEffect { public DetentionSphereLeavesEffect copy() { return new DetentionSphereLeavesEffect(this); } -} \ No newline at end of file +} From 6cd18246dee34210d3b367a92d58d66ecc0d246e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 27 Aug 2017 16:14:48 -0400 Subject: [PATCH 2/8] fixed goad effect --- .../effects/common/combat/GoadAllEffect.java | 12 ++++++++---- .../effects/common/combat/GoadTargetEffect.java | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java index 47b7305421..fab77b1eae 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java @@ -28,8 +28,9 @@ package mage.abilities.effects.common.combat; import mage.abilities.Ability; -import mage.abilities.effects.Effect; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.constants.Duration; import mage.constants.Outcome; import mage.filter.StaticFilters; import mage.game.Game; @@ -60,9 +61,12 @@ public class GoadAllEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) { if (!creature.getControllerId().equals(source.getControllerId())) { - Effect effect = new GoadTargetEffect(); - effect.setTargetPointer(new FixedTarget(creature, game)); - effect.apply(game, source); + ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(creature.getId())); + game.addEffect(effect, source); + effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); + effect.setTargetPointer(new FixedTarget(creature.getId())); + game.addEffect(effect, source); } } return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java index 38364d4d81..e32d2e35c6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java @@ -59,9 +59,9 @@ public class GoadTargetEffect extends OneShotEffect { ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); game.addEffect(effect, source); - effect = new CantAttackYouEffect(Duration.EndOfTurn, true); + effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); game.addEffect(effect, source); return true; } -} \ No newline at end of file +} From 29471f9bd508853926c87bf5633f4798bc89a9f0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 28 Aug 2017 11:41:37 -0400 Subject: [PATCH 3/8] Implemented Portal Mage --- Mage.Sets/src/mage/cards/p/PortalMage.java | 166 ++++++++++++++++++ Mage.Sets/src/mage/sets/Commander2017.java | 1 + .../common/FilterPermanentOrPlayer.java | 12 +- 3 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/p/PortalMage.java diff --git a/Mage.Sets/src/mage/cards/p/PortalMage.java b/Mage.Sets/src/mage/cards/p/PortalMage.java new file mode 100644 index 0000000000..33f9158071 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PortalMage.java @@ -0,0 +1,166 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.filter.FilterPlayer; +import mage.filter.common.FilterPermanentOrPlayer; +import mage.filter.common.FilterPlaneswalkerPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.PlayerIdPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetAttackingCreature; +import mage.target.common.TargetPermanentOrPlayer; + +/** + * + * @author TheElk801 + */ +public class PortalMage extends CardImpl { + + public PortalMage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or planeswalker target attacking creature is attacking. + Ability ability = new PortalMageTriggeredAbility(new PortalMageEffect()); + ability.addTarget(new TargetAttackingCreature()); + this.addAbility(ability); + } + + public PortalMage(final PortalMage card) { + super(card); + } + + @Override + public PortalMage copy() { + return new PortalMage(this); + } +} + +class PortalMageTriggeredAbility extends TriggeredAbilityImpl { + + PortalMageTriggeredAbility(Effect effect) { + super(Zone.ALL, effect, true); + } + + PortalMageTriggeredAbility(final PortalMageTriggeredAbility ability) { + super(ability); + } + + @Override + public PortalMageTriggeredAbility copy() { + return new PortalMageTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getStep().getType().equals(PhaseStep.DECLARE_ATTACKERS)) { + return event.getTargetId().equals(getSourceId()); + } + return false; + } + + @Override + public String getRule() { + return "When {this} enters the battlefield during the declare attackers step, " + super.getRule(); + } +} + +class PortalMageEffect extends OneShotEffect { + + PortalMageEffect() { + super(Outcome.Benefit); + this.staticText = "you may reselect which player or planeswalker target attacking creature is attacking"; + } + + PortalMageEffect(final PortalMageEffect effect) { + super(effect); + } + + @Override + public PortalMageEffect copy() { + return new PortalMageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanent(source.getFirstTarget()); + Player you = game.getPlayer(source.getControllerId()); + if (creature != null && you != null && game.getCombat().getAttackers().contains(creature.getId())) { + Player controller = game.getPlayer(creature.getControllerId()); + if (controller != null) { + FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer("player or planeswalker it can attack"); + FilterPlaneswalkerPermanent pwalkerFilter = new FilterPlaneswalkerPermanent(); + pwalkerFilter.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); + filter.setPermanentFilter(pwalkerFilter); + FilterPlayer playerFilter = new FilterPlayer(); + playerFilter.add(Predicates.not(new PlayerIdPredicate(controller.getId()))); + filter.setPlayerFilter(playerFilter); + TargetPermanentOrPlayer target = new TargetPermanentOrPlayer(1, 1, true); + target.setFilter(filter); + if (you.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + if (game.getCombat().canDefenderBeAttacked(creature.getId(), target.getFirstTarget(), game)) { + game.getCombat().removeFromCombat(creature.getId(), game, false); + game.getCombat().addAttackerToCombat(creature.getId(), target.getFirstTarget(), game); + return true; + } + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Commander2017.java b/Mage.Sets/src/mage/sets/Commander2017.java index 85676e74e0..5b4e4740b5 100644 --- a/Mage.Sets/src/mage/sets/Commander2017.java +++ b/Mage.Sets/src/mage/sets/Commander2017.java @@ -87,6 +87,7 @@ public class Commander2017 extends ExpansionSet { cards.add(new SetCardInfo("O-Kagachi, Vengeful Kami", 45, Rarity.MYTHIC, mage.cards.o.OKagachiVengefulKami.class)); cards.add(new SetCardInfo("Path of Ancestry", 56, Rarity.COMMON, mage.cards.p.PathOfAncestry.class)); cards.add(new SetCardInfo("Patron of the Vein", 20, Rarity.RARE, mage.cards.p.PatronOfTheVein.class)); + cards.add(new SetCardInfo("Portal Mage", 13, Rarity.RARE, mage.cards.p.PortalMage.class)); cards.add(new SetCardInfo("Qasali Slingers", 33, Rarity.RARE, mage.cards.q.QasaliSlingers.class)); cards.add(new SetCardInfo("Ramos, Dragon Engine", 55, Rarity.MYTHIC, mage.cards.r.RamosDragonEngine.class)); cards.add(new SetCardInfo("Scalelord Reckoner", 6, Rarity.RARE, mage.cards.s.ScalelordReckoner.class)); diff --git a/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java b/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java index d4e024f476..207da7eda9 100644 --- a/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java +++ b/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java @@ -42,8 +42,8 @@ import mage.players.Player; */ public class FilterPermanentOrPlayer extends FilterImpl implements FilterInPlay { - protected final FilterPermanent permanentFilter; - protected final FilterPlayer playerFilter; + protected FilterPermanent permanentFilter; + protected FilterPlayer playerFilter; public FilterPermanentOrPlayer() { this("player or permanent"); @@ -90,10 +90,18 @@ public class FilterPermanentOrPlayer extends FilterImpl implements Fil return this.permanentFilter; } + public void setPermanentFilter(FilterPermanent permanentFilter) { + this.permanentFilter = permanentFilter; + } + public FilterPlayer getPlayerFilter() { return this.playerFilter; } + public void setPlayerFilter(FilterPlayer playerFilter) { + this.playerFilter = playerFilter; + } + @Override public FilterPermanentOrPlayer copy() { return new FilterPermanentOrPlayer(this); From aa0487708e7c24b4fdd32e75911bbf1c22377a7d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 28 Aug 2017 12:26:29 -0400 Subject: [PATCH 4/8] resolve issues --- Mage.Sets/src/mage/cards/p/PortalMage.java | 166 ------------------ Mage.Sets/src/mage/sets/Commander2017.java | 104 ----------- .../effects/common/combat/GoadAllEffect.java | 74 -------- .../common/combat/GoadTargetEffect.java | 67 ------- 4 files changed, 411 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/p/PortalMage.java delete mode 100644 Mage.Sets/src/mage/sets/Commander2017.java delete mode 100644 Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java delete mode 100644 Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/p/PortalMage.java b/Mage.Sets/src/mage/cards/p/PortalMage.java deleted file mode 100644 index 33f9158071..0000000000 --- a/Mage.Sets/src/mage/cards/p/PortalMage.java +++ /dev/null @@ -1,166 +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.cards.p; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.FlashAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.PhaseStep; -import mage.constants.Zone; -import mage.filter.FilterPlayer; -import mage.filter.common.FilterPermanentOrPlayer; -import mage.filter.common.FilterPlaneswalkerPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.other.PlayerIdPredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetAttackingCreature; -import mage.target.common.TargetPermanentOrPlayer; - -/** - * - * @author TheElk801 - */ -public class PortalMage extends CardImpl { - - public PortalMage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); - - this.subtype.add("Human"); - this.subtype.add("Wizard"); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - // Flash - this.addAbility(FlashAbility.getInstance()); - - // When Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or planeswalker target attacking creature is attacking. - Ability ability = new PortalMageTriggeredAbility(new PortalMageEffect()); - ability.addTarget(new TargetAttackingCreature()); - this.addAbility(ability); - } - - public PortalMage(final PortalMage card) { - super(card); - } - - @Override - public PortalMage copy() { - return new PortalMage(this); - } -} - -class PortalMageTriggeredAbility extends TriggeredAbilityImpl { - - PortalMageTriggeredAbility(Effect effect) { - super(Zone.ALL, effect, true); - } - - PortalMageTriggeredAbility(final PortalMageTriggeredAbility ability) { - super(ability); - } - - @Override - public PortalMageTriggeredAbility copy() { - return new PortalMageTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (game.getStep().getType().equals(PhaseStep.DECLARE_ATTACKERS)) { - return event.getTargetId().equals(getSourceId()); - } - return false; - } - - @Override - public String getRule() { - return "When {this} enters the battlefield during the declare attackers step, " + super.getRule(); - } -} - -class PortalMageEffect extends OneShotEffect { - - PortalMageEffect() { - super(Outcome.Benefit); - this.staticText = "you may reselect which player or planeswalker target attacking creature is attacking"; - } - - PortalMageEffect(final PortalMageEffect effect) { - super(effect); - } - - @Override - public PortalMageEffect copy() { - return new PortalMageEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(source.getFirstTarget()); - Player you = game.getPlayer(source.getControllerId()); - if (creature != null && you != null && game.getCombat().getAttackers().contains(creature.getId())) { - Player controller = game.getPlayer(creature.getControllerId()); - if (controller != null) { - FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer("player or planeswalker it can attack"); - FilterPlaneswalkerPermanent pwalkerFilter = new FilterPlaneswalkerPermanent(); - pwalkerFilter.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); - filter.setPermanentFilter(pwalkerFilter); - FilterPlayer playerFilter = new FilterPlayer(); - playerFilter.add(Predicates.not(new PlayerIdPredicate(controller.getId()))); - filter.setPlayerFilter(playerFilter); - TargetPermanentOrPlayer target = new TargetPermanentOrPlayer(1, 1, true); - target.setFilter(filter); - if (you.choose(Outcome.Benefit, target, source.getSourceId(), game)) { - if (game.getCombat().canDefenderBeAttacked(creature.getId(), target.getFirstTarget(), game)) { - game.getCombat().removeFromCombat(creature.getId(), game, false); - game.getCombat().addAttackerToCombat(creature.getId(), target.getFirstTarget(), game); - return true; - } - } - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/Commander2017.java b/Mage.Sets/src/mage/sets/Commander2017.java deleted file mode 100644 index 5b4e4740b5..0000000000 --- a/Mage.Sets/src/mage/sets/Commander2017.java +++ /dev/null @@ -1,104 +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.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author fireshoes - */ -public class Commander2017 extends ExpansionSet { - - private static final Commander2017 instance = new Commander2017(); - - public static Commander2017 getInstance() { - return instance; - } - - private Commander2017() { - super("Commander 2017 Edition", "C17", ExpansionSet.buildDate(2017, 8, 25), SetType.SUPPLEMENTAL); - this.blockName = "Command Zone"; - - cards.add(new SetCardInfo("Arahbo, Roar of the World", 35, Rarity.MYTHIC, mage.cards.a.ArahboRoarOfTheWorld.class)); - cards.add(new SetCardInfo("Balan, Wandering Knight", 2, Rarity.RARE, mage.cards.b.BalanWanderingKnight.class)); - cards.add(new SetCardInfo("Bloodforged Battle-Axe", 50, Rarity.RARE, mage.cards.b.BloodforgedBattleAxe.class)); - cards.add(new SetCardInfo("Bloodline Necromancer", 14, Rarity.UNCOMMON, mage.cards.b.BloodlineNecromancer.class)); - cards.add(new SetCardInfo("Bloodsworn Steward", 22, Rarity.RARE, mage.cards.b.BloodswornSteward.class)); - cards.add(new SetCardInfo("Boneyard Scourge", 15, Rarity.RARE, mage.cards.b.BoneyardScourge.class)); - cards.add(new SetCardInfo("Crimson Honor Guard", 23, Rarity.RARE, mage.cards.c.CrimsonHonorGuard.class)); - cards.add(new SetCardInfo("Curse of Bounty", 30, Rarity.UNCOMMON, mage.cards.c.CurseOfBounty.class)); - cards.add(new SetCardInfo("Curse of Disturbance", 16, Rarity.UNCOMMON, mage.cards.c.CurseOfDisturbance.class)); - cards.add(new SetCardInfo("Curse of Opulence", 24, Rarity.UNCOMMON, mage.cards.c.CurseOfOpulence.class)); - cards.add(new SetCardInfo("Curse of Verbosity", 9, Rarity.UNCOMMON, mage.cards.c.CurseOfVerbosity.class)); - cards.add(new SetCardInfo("Curse of Vitality", 3, Rarity.UNCOMMON, mage.cards.c.CurseOfVitality.class)); - cards.add(new SetCardInfo("Disrupt Decorum", 25, Rarity.RARE, mage.cards.d.DisruptDecorum.class)); - cards.add(new SetCardInfo("Edgar Markov", 36, Rarity.MYTHIC, mage.cards.e.EdgarMarkov.class)); - cards.add(new SetCardInfo("Fortunate Few", 4, Rarity.RARE, mage.cards.f.FortunateFew.class)); - cards.add(new SetCardInfo("Fractured Identity", 37, Rarity.RARE, mage.cards.f.FracturedIdentity.class)); - cards.add(new SetCardInfo("Galecaster Colossus", 10, Rarity.RARE, mage.cards.g.GalecasterColossus.class)); - cards.add(new SetCardInfo("Hammer of Nazahn", 51, Rarity.RARE, mage.cards.h.HammerOfNazahn.class)); - cards.add(new SetCardInfo("Herald's Horn", 53, Rarity.UNCOMMON, mage.cards.h.HeraldsHorn.class)); - cards.add(new SetCardInfo("Heirloom Blade", 52, Rarity.UNCOMMON, mage.cards.h.HeirloomBlade.class)); - cards.add(new SetCardInfo("Hungry Lynx", 31, Rarity.RARE, mage.cards.h.HungryLynx.class)); - cards.add(new SetCardInfo("Inalla, Archmage Ritualist", 38, Rarity.MYTHIC, mage.cards.i.InallaArchmageRitualist.class)); - cards.add(new SetCardInfo("Izzet Chemister", 26, Rarity.RARE, mage.cards.i.IzzetChemister.class)); - cards.add(new SetCardInfo("Kess, Dissident Mage", 39, Rarity.MYTHIC, mage.cards.k.KessDissidentMage.class)); - cards.add(new SetCardInfo("Kheru Mind-Eater", 17, Rarity.RARE, mage.cards.k.KheruMindEater.class)); - cards.add(new SetCardInfo("Kindred Boon", 5, Rarity.RARE, mage.cards.k.KindredBoon.class)); - cards.add(new SetCardInfo("Kindred Charge", 27, Rarity.RARE, mage.cards.k.KindredCharge.class)); - cards.add(new SetCardInfo("Kindred Discovery", 11, Rarity.RARE, mage.cards.k.KindredDiscovery.class)); - cards.add(new SetCardInfo("Kindred Dominance", 18, Rarity.RARE, mage.cards.k.KindredDominance.class)); - cards.add(new SetCardInfo("Kindred Summons", 32, Rarity.RARE, mage.cards.k.KindredSummons.class)); - cards.add(new SetCardInfo("Licia, Sanguine Tribune", 40, Rarity.MYTHIC, mage.cards.l.LiciaSanguineTribune.class)); - cards.add(new SetCardInfo("Magus of the Mind", 12, Rarity.RARE, mage.cards.m.MagusOfTheMind.class)); - cards.add(new SetCardInfo("Mairsil, the Pretender", 41, Rarity.MYTHIC, mage.cards.m.MairsilThePretender.class)); - cards.add(new SetCardInfo("Mathas, Fiend Seeker", 42, Rarity.MYTHIC, mage.cards.m.MathasFiendSeeker.class)); - cards.add(new SetCardInfo("Mirri, Weatherlight Duelist", 43, Rarity.MYTHIC, mage.cards.m.MirriWeatherlightDuelist.class)); - cards.add(new SetCardInfo("Mirror of the Forebears", 54, Rarity.UNCOMMON, mage.cards.m.MirrorOfTheForebears.class)); - cards.add(new SetCardInfo("Nazahn, Revered Bladesmith", 44, Rarity.MYTHIC, mage.cards.n.NazahnReveredBladesmith.class)); - cards.add(new SetCardInfo("O-Kagachi, Vengeful Kami", 45, Rarity.MYTHIC, mage.cards.o.OKagachiVengefulKami.class)); - cards.add(new SetCardInfo("Path of Ancestry", 56, Rarity.COMMON, mage.cards.p.PathOfAncestry.class)); - cards.add(new SetCardInfo("Patron of the Vein", 20, Rarity.RARE, mage.cards.p.PatronOfTheVein.class)); - cards.add(new SetCardInfo("Portal Mage", 13, Rarity.RARE, mage.cards.p.PortalMage.class)); - cards.add(new SetCardInfo("Qasali Slingers", 33, Rarity.RARE, mage.cards.q.QasaliSlingers.class)); - cards.add(new SetCardInfo("Ramos, Dragon Engine", 55, Rarity.MYTHIC, mage.cards.r.RamosDragonEngine.class)); - cards.add(new SetCardInfo("Scalelord Reckoner", 6, Rarity.RARE, mage.cards.s.ScalelordReckoner.class)); - cards.add(new SetCardInfo("Shifting Shadow", 28, Rarity.RARE, mage.cards.s.ShiftingShadow.class)); - cards.add(new SetCardInfo("Taigam, Ojutai Master", 46, Rarity.MYTHIC, mage.cards.t.TaigamOjutaiMaster.class)); - cards.add(new SetCardInfo("Taigam, Sidisi's Hand", 47, Rarity.RARE, mage.cards.t.TaigamSidisisHand.class)); - cards.add(new SetCardInfo("Teferi's Protection", 8, Rarity.RARE, mage.cards.t.TeferisProtection.class)); - cards.add(new SetCardInfo("Territorial Hellkite", 29, Rarity.RARE, mage.cards.t.TerritorialHellkite.class)); - cards.add(new SetCardInfo("The Ur-Dragon", 48, Rarity.MYTHIC, mage.cards.t.TheUrDragon.class)); - cards.add(new SetCardInfo("Traverse the Outlands", 34, Rarity.RARE, mage.cards.t.TraverseTheOutlands.class)); - cards.add(new SetCardInfo("Vindictive Lich", 21, Rarity.RARE, mage.cards.v.VindictiveLich.class)); - cards.add(new SetCardInfo("Wasitora, Nekoru Queen", 49, Rarity.MYTHIC, mage.cards.w.WasitoraNekoruQueen.class)); - } -} diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java deleted file mode 100644 index fab77b1eae..0000000000 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java +++ /dev/null @@ -1,74 +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.combat; - -import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.OneShotEffect; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; - -/** - * - * @author TheElk801 - */ -public class GoadAllEffect extends OneShotEffect { - - public GoadAllEffect() { - super(Outcome.Benefit); - staticText = "Goad all creatures you don't control."; - } - - public GoadAllEffect(final GoadAllEffect effect) { - super(effect); - } - - @Override - public GoadAllEffect copy() { - return new GoadAllEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) { - if (!creature.getControllerId().equals(source.getControllerId())) { - ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); - effect.setTargetPointer(new FixedTarget(creature.getId())); - game.addEffect(effect, source); - effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); - effect.setTargetPointer(new FixedTarget(creature.getId())); - game.addEffect(effect, source); - } - } - return true; - } -} diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java deleted file mode 100644 index e32d2e35c6..0000000000 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java +++ /dev/null @@ -1,67 +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.combat; - -import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.OneShotEffect; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.game.Game; -import mage.target.targetpointer.FixedTarget; - -/** - * - * @author TheElk801 - */ -public class GoadTargetEffect extends OneShotEffect { - - public GoadTargetEffect() { - super(Outcome.Benefit); - } - - public GoadTargetEffect(final GoadTargetEffect effect) { - super(effect); - } - - @Override - public GoadTargetEffect copy() { - return new GoadTargetEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); - game.addEffect(effect, source); - effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); - game.addEffect(effect, source); - return true; - } -} From 75934f5513eb01dee48f33dcc5991a7ae1de3f83 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 28 Aug 2017 12:28:14 -0400 Subject: [PATCH 5/8] Revert "resolve issues" This reverts commit aa0487708e7c24b4fdd32e75911bbf1c22377a7d. --- Mage.Sets/src/mage/cards/p/PortalMage.java | 166 ++++++++++++++++++ Mage.Sets/src/mage/sets/Commander2017.java | 104 +++++++++++ .../effects/common/combat/GoadAllEffect.java | 74 ++++++++ .../common/combat/GoadTargetEffect.java | 67 +++++++ 4 files changed, 411 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PortalMage.java create mode 100644 Mage.Sets/src/mage/sets/Commander2017.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/p/PortalMage.java b/Mage.Sets/src/mage/cards/p/PortalMage.java new file mode 100644 index 0000000000..33f9158071 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PortalMage.java @@ -0,0 +1,166 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.filter.FilterPlayer; +import mage.filter.common.FilterPermanentOrPlayer; +import mage.filter.common.FilterPlaneswalkerPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.PlayerIdPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetAttackingCreature; +import mage.target.common.TargetPermanentOrPlayer; + +/** + * + * @author TheElk801 + */ +public class PortalMage extends CardImpl { + + public PortalMage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or planeswalker target attacking creature is attacking. + Ability ability = new PortalMageTriggeredAbility(new PortalMageEffect()); + ability.addTarget(new TargetAttackingCreature()); + this.addAbility(ability); + } + + public PortalMage(final PortalMage card) { + super(card); + } + + @Override + public PortalMage copy() { + return new PortalMage(this); + } +} + +class PortalMageTriggeredAbility extends TriggeredAbilityImpl { + + PortalMageTriggeredAbility(Effect effect) { + super(Zone.ALL, effect, true); + } + + PortalMageTriggeredAbility(final PortalMageTriggeredAbility ability) { + super(ability); + } + + @Override + public PortalMageTriggeredAbility copy() { + return new PortalMageTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getStep().getType().equals(PhaseStep.DECLARE_ATTACKERS)) { + return event.getTargetId().equals(getSourceId()); + } + return false; + } + + @Override + public String getRule() { + return "When {this} enters the battlefield during the declare attackers step, " + super.getRule(); + } +} + +class PortalMageEffect extends OneShotEffect { + + PortalMageEffect() { + super(Outcome.Benefit); + this.staticText = "you may reselect which player or planeswalker target attacking creature is attacking"; + } + + PortalMageEffect(final PortalMageEffect effect) { + super(effect); + } + + @Override + public PortalMageEffect copy() { + return new PortalMageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanent(source.getFirstTarget()); + Player you = game.getPlayer(source.getControllerId()); + if (creature != null && you != null && game.getCombat().getAttackers().contains(creature.getId())) { + Player controller = game.getPlayer(creature.getControllerId()); + if (controller != null) { + FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer("player or planeswalker it can attack"); + FilterPlaneswalkerPermanent pwalkerFilter = new FilterPlaneswalkerPermanent(); + pwalkerFilter.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); + filter.setPermanentFilter(pwalkerFilter); + FilterPlayer playerFilter = new FilterPlayer(); + playerFilter.add(Predicates.not(new PlayerIdPredicate(controller.getId()))); + filter.setPlayerFilter(playerFilter); + TargetPermanentOrPlayer target = new TargetPermanentOrPlayer(1, 1, true); + target.setFilter(filter); + if (you.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + if (game.getCombat().canDefenderBeAttacked(creature.getId(), target.getFirstTarget(), game)) { + game.getCombat().removeFromCombat(creature.getId(), game, false); + game.getCombat().addAttackerToCombat(creature.getId(), target.getFirstTarget(), game); + return true; + } + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Commander2017.java b/Mage.Sets/src/mage/sets/Commander2017.java new file mode 100644 index 0000000000..5b4e4740b5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/Commander2017.java @@ -0,0 +1,104 @@ +/* + * 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; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author fireshoes + */ +public class Commander2017 extends ExpansionSet { + + private static final Commander2017 instance = new Commander2017(); + + public static Commander2017 getInstance() { + return instance; + } + + private Commander2017() { + super("Commander 2017 Edition", "C17", ExpansionSet.buildDate(2017, 8, 25), SetType.SUPPLEMENTAL); + this.blockName = "Command Zone"; + + cards.add(new SetCardInfo("Arahbo, Roar of the World", 35, Rarity.MYTHIC, mage.cards.a.ArahboRoarOfTheWorld.class)); + cards.add(new SetCardInfo("Balan, Wandering Knight", 2, Rarity.RARE, mage.cards.b.BalanWanderingKnight.class)); + cards.add(new SetCardInfo("Bloodforged Battle-Axe", 50, Rarity.RARE, mage.cards.b.BloodforgedBattleAxe.class)); + cards.add(new SetCardInfo("Bloodline Necromancer", 14, Rarity.UNCOMMON, mage.cards.b.BloodlineNecromancer.class)); + cards.add(new SetCardInfo("Bloodsworn Steward", 22, Rarity.RARE, mage.cards.b.BloodswornSteward.class)); + cards.add(new SetCardInfo("Boneyard Scourge", 15, Rarity.RARE, mage.cards.b.BoneyardScourge.class)); + cards.add(new SetCardInfo("Crimson Honor Guard", 23, Rarity.RARE, mage.cards.c.CrimsonHonorGuard.class)); + cards.add(new SetCardInfo("Curse of Bounty", 30, Rarity.UNCOMMON, mage.cards.c.CurseOfBounty.class)); + cards.add(new SetCardInfo("Curse of Disturbance", 16, Rarity.UNCOMMON, mage.cards.c.CurseOfDisturbance.class)); + cards.add(new SetCardInfo("Curse of Opulence", 24, Rarity.UNCOMMON, mage.cards.c.CurseOfOpulence.class)); + cards.add(new SetCardInfo("Curse of Verbosity", 9, Rarity.UNCOMMON, mage.cards.c.CurseOfVerbosity.class)); + cards.add(new SetCardInfo("Curse of Vitality", 3, Rarity.UNCOMMON, mage.cards.c.CurseOfVitality.class)); + cards.add(new SetCardInfo("Disrupt Decorum", 25, Rarity.RARE, mage.cards.d.DisruptDecorum.class)); + cards.add(new SetCardInfo("Edgar Markov", 36, Rarity.MYTHIC, mage.cards.e.EdgarMarkov.class)); + cards.add(new SetCardInfo("Fortunate Few", 4, Rarity.RARE, mage.cards.f.FortunateFew.class)); + cards.add(new SetCardInfo("Fractured Identity", 37, Rarity.RARE, mage.cards.f.FracturedIdentity.class)); + cards.add(new SetCardInfo("Galecaster Colossus", 10, Rarity.RARE, mage.cards.g.GalecasterColossus.class)); + cards.add(new SetCardInfo("Hammer of Nazahn", 51, Rarity.RARE, mage.cards.h.HammerOfNazahn.class)); + cards.add(new SetCardInfo("Herald's Horn", 53, Rarity.UNCOMMON, mage.cards.h.HeraldsHorn.class)); + cards.add(new SetCardInfo("Heirloom Blade", 52, Rarity.UNCOMMON, mage.cards.h.HeirloomBlade.class)); + cards.add(new SetCardInfo("Hungry Lynx", 31, Rarity.RARE, mage.cards.h.HungryLynx.class)); + cards.add(new SetCardInfo("Inalla, Archmage Ritualist", 38, Rarity.MYTHIC, mage.cards.i.InallaArchmageRitualist.class)); + cards.add(new SetCardInfo("Izzet Chemister", 26, Rarity.RARE, mage.cards.i.IzzetChemister.class)); + cards.add(new SetCardInfo("Kess, Dissident Mage", 39, Rarity.MYTHIC, mage.cards.k.KessDissidentMage.class)); + cards.add(new SetCardInfo("Kheru Mind-Eater", 17, Rarity.RARE, mage.cards.k.KheruMindEater.class)); + cards.add(new SetCardInfo("Kindred Boon", 5, Rarity.RARE, mage.cards.k.KindredBoon.class)); + cards.add(new SetCardInfo("Kindred Charge", 27, Rarity.RARE, mage.cards.k.KindredCharge.class)); + cards.add(new SetCardInfo("Kindred Discovery", 11, Rarity.RARE, mage.cards.k.KindredDiscovery.class)); + cards.add(new SetCardInfo("Kindred Dominance", 18, Rarity.RARE, mage.cards.k.KindredDominance.class)); + cards.add(new SetCardInfo("Kindred Summons", 32, Rarity.RARE, mage.cards.k.KindredSummons.class)); + cards.add(new SetCardInfo("Licia, Sanguine Tribune", 40, Rarity.MYTHIC, mage.cards.l.LiciaSanguineTribune.class)); + cards.add(new SetCardInfo("Magus of the Mind", 12, Rarity.RARE, mage.cards.m.MagusOfTheMind.class)); + cards.add(new SetCardInfo("Mairsil, the Pretender", 41, Rarity.MYTHIC, mage.cards.m.MairsilThePretender.class)); + cards.add(new SetCardInfo("Mathas, Fiend Seeker", 42, Rarity.MYTHIC, mage.cards.m.MathasFiendSeeker.class)); + cards.add(new SetCardInfo("Mirri, Weatherlight Duelist", 43, Rarity.MYTHIC, mage.cards.m.MirriWeatherlightDuelist.class)); + cards.add(new SetCardInfo("Mirror of the Forebears", 54, Rarity.UNCOMMON, mage.cards.m.MirrorOfTheForebears.class)); + cards.add(new SetCardInfo("Nazahn, Revered Bladesmith", 44, Rarity.MYTHIC, mage.cards.n.NazahnReveredBladesmith.class)); + cards.add(new SetCardInfo("O-Kagachi, Vengeful Kami", 45, Rarity.MYTHIC, mage.cards.o.OKagachiVengefulKami.class)); + cards.add(new SetCardInfo("Path of Ancestry", 56, Rarity.COMMON, mage.cards.p.PathOfAncestry.class)); + cards.add(new SetCardInfo("Patron of the Vein", 20, Rarity.RARE, mage.cards.p.PatronOfTheVein.class)); + cards.add(new SetCardInfo("Portal Mage", 13, Rarity.RARE, mage.cards.p.PortalMage.class)); + cards.add(new SetCardInfo("Qasali Slingers", 33, Rarity.RARE, mage.cards.q.QasaliSlingers.class)); + cards.add(new SetCardInfo("Ramos, Dragon Engine", 55, Rarity.MYTHIC, mage.cards.r.RamosDragonEngine.class)); + cards.add(new SetCardInfo("Scalelord Reckoner", 6, Rarity.RARE, mage.cards.s.ScalelordReckoner.class)); + cards.add(new SetCardInfo("Shifting Shadow", 28, Rarity.RARE, mage.cards.s.ShiftingShadow.class)); + cards.add(new SetCardInfo("Taigam, Ojutai Master", 46, Rarity.MYTHIC, mage.cards.t.TaigamOjutaiMaster.class)); + cards.add(new SetCardInfo("Taigam, Sidisi's Hand", 47, Rarity.RARE, mage.cards.t.TaigamSidisisHand.class)); + cards.add(new SetCardInfo("Teferi's Protection", 8, Rarity.RARE, mage.cards.t.TeferisProtection.class)); + cards.add(new SetCardInfo("Territorial Hellkite", 29, Rarity.RARE, mage.cards.t.TerritorialHellkite.class)); + cards.add(new SetCardInfo("The Ur-Dragon", 48, Rarity.MYTHIC, mage.cards.t.TheUrDragon.class)); + cards.add(new SetCardInfo("Traverse the Outlands", 34, Rarity.RARE, mage.cards.t.TraverseTheOutlands.class)); + cards.add(new SetCardInfo("Vindictive Lich", 21, Rarity.RARE, mage.cards.v.VindictiveLich.class)); + cards.add(new SetCardInfo("Wasitora, Nekoru Queen", 49, Rarity.MYTHIC, mage.cards.w.WasitoraNekoruQueen.class)); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java new file mode 100644 index 0000000000..fab77b1eae --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.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.abilities.effects.common.combat; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class GoadAllEffect extends OneShotEffect { + + public GoadAllEffect() { + super(Outcome.Benefit); + staticText = "Goad all creatures you don't control."; + } + + public GoadAllEffect(final GoadAllEffect effect) { + super(effect); + } + + @Override + public GoadAllEffect copy() { + return new GoadAllEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) { + if (!creature.getControllerId().equals(source.getControllerId())) { + ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(creature.getId())); + game.addEffect(effect, source); + effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); + effect.setTargetPointer(new FixedTarget(creature.getId())); + game.addEffect(effect, source); + } + } + return true; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java new file mode 100644 index 0000000000..e32d2e35c6 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java @@ -0,0 +1,67 @@ +/* + * 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.combat; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class GoadTargetEffect extends OneShotEffect { + + public GoadTargetEffect() { + super(Outcome.Benefit); + } + + public GoadTargetEffect(final GoadTargetEffect effect) { + super(effect); + } + + @Override + public GoadTargetEffect copy() { + return new GoadTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); + game.addEffect(effect, source); + effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); + effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); + game.addEffect(effect, source); + return true; + } +} From f1cfc8ca5cd3cd22099b072f17e4ac986cc436e0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 28 Aug 2017 12:29:02 -0400 Subject: [PATCH 6/8] Revert "Implemented Portal Mage" This reverts commit 29471f9bd508853926c87bf5633f4798bc89a9f0. --- Mage.Sets/src/mage/cards/p/PortalMage.java | 166 ------------------ Mage.Sets/src/mage/sets/Commander2017.java | 1 - .../common/FilterPermanentOrPlayer.java | 12 +- 3 files changed, 2 insertions(+), 177 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/p/PortalMage.java diff --git a/Mage.Sets/src/mage/cards/p/PortalMage.java b/Mage.Sets/src/mage/cards/p/PortalMage.java deleted file mode 100644 index 33f9158071..0000000000 --- a/Mage.Sets/src/mage/cards/p/PortalMage.java +++ /dev/null @@ -1,166 +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.cards.p; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.FlashAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.PhaseStep; -import mage.constants.Zone; -import mage.filter.FilterPlayer; -import mage.filter.common.FilterPermanentOrPlayer; -import mage.filter.common.FilterPlaneswalkerPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.other.PlayerIdPredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetAttackingCreature; -import mage.target.common.TargetPermanentOrPlayer; - -/** - * - * @author TheElk801 - */ -public class PortalMage extends CardImpl { - - public PortalMage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); - - this.subtype.add("Human"); - this.subtype.add("Wizard"); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - // Flash - this.addAbility(FlashAbility.getInstance()); - - // When Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or planeswalker target attacking creature is attacking. - Ability ability = new PortalMageTriggeredAbility(new PortalMageEffect()); - ability.addTarget(new TargetAttackingCreature()); - this.addAbility(ability); - } - - public PortalMage(final PortalMage card) { - super(card); - } - - @Override - public PortalMage copy() { - return new PortalMage(this); - } -} - -class PortalMageTriggeredAbility extends TriggeredAbilityImpl { - - PortalMageTriggeredAbility(Effect effect) { - super(Zone.ALL, effect, true); - } - - PortalMageTriggeredAbility(final PortalMageTriggeredAbility ability) { - super(ability); - } - - @Override - public PortalMageTriggeredAbility copy() { - return new PortalMageTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (game.getStep().getType().equals(PhaseStep.DECLARE_ATTACKERS)) { - return event.getTargetId().equals(getSourceId()); - } - return false; - } - - @Override - public String getRule() { - return "When {this} enters the battlefield during the declare attackers step, " + super.getRule(); - } -} - -class PortalMageEffect extends OneShotEffect { - - PortalMageEffect() { - super(Outcome.Benefit); - this.staticText = "you may reselect which player or planeswalker target attacking creature is attacking"; - } - - PortalMageEffect(final PortalMageEffect effect) { - super(effect); - } - - @Override - public PortalMageEffect copy() { - return new PortalMageEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(source.getFirstTarget()); - Player you = game.getPlayer(source.getControllerId()); - if (creature != null && you != null && game.getCombat().getAttackers().contains(creature.getId())) { - Player controller = game.getPlayer(creature.getControllerId()); - if (controller != null) { - FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer("player or planeswalker it can attack"); - FilterPlaneswalkerPermanent pwalkerFilter = new FilterPlaneswalkerPermanent(); - pwalkerFilter.add(Predicates.not(new ControllerIdPredicate(controller.getId()))); - filter.setPermanentFilter(pwalkerFilter); - FilterPlayer playerFilter = new FilterPlayer(); - playerFilter.add(Predicates.not(new PlayerIdPredicate(controller.getId()))); - filter.setPlayerFilter(playerFilter); - TargetPermanentOrPlayer target = new TargetPermanentOrPlayer(1, 1, true); - target.setFilter(filter); - if (you.choose(Outcome.Benefit, target, source.getSourceId(), game)) { - if (game.getCombat().canDefenderBeAttacked(creature.getId(), target.getFirstTarget(), game)) { - game.getCombat().removeFromCombat(creature.getId(), game, false); - game.getCombat().addAttackerToCombat(creature.getId(), target.getFirstTarget(), game); - return true; - } - } - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/Commander2017.java b/Mage.Sets/src/mage/sets/Commander2017.java index 5b4e4740b5..85676e74e0 100644 --- a/Mage.Sets/src/mage/sets/Commander2017.java +++ b/Mage.Sets/src/mage/sets/Commander2017.java @@ -87,7 +87,6 @@ public class Commander2017 extends ExpansionSet { cards.add(new SetCardInfo("O-Kagachi, Vengeful Kami", 45, Rarity.MYTHIC, mage.cards.o.OKagachiVengefulKami.class)); cards.add(new SetCardInfo("Path of Ancestry", 56, Rarity.COMMON, mage.cards.p.PathOfAncestry.class)); cards.add(new SetCardInfo("Patron of the Vein", 20, Rarity.RARE, mage.cards.p.PatronOfTheVein.class)); - cards.add(new SetCardInfo("Portal Mage", 13, Rarity.RARE, mage.cards.p.PortalMage.class)); cards.add(new SetCardInfo("Qasali Slingers", 33, Rarity.RARE, mage.cards.q.QasaliSlingers.class)); cards.add(new SetCardInfo("Ramos, Dragon Engine", 55, Rarity.MYTHIC, mage.cards.r.RamosDragonEngine.class)); cards.add(new SetCardInfo("Scalelord Reckoner", 6, Rarity.RARE, mage.cards.s.ScalelordReckoner.class)); diff --git a/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java b/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java index 207da7eda9..d4e024f476 100644 --- a/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java +++ b/Mage/src/main/java/mage/filter/common/FilterPermanentOrPlayer.java @@ -42,8 +42,8 @@ import mage.players.Player; */ public class FilterPermanentOrPlayer extends FilterImpl implements FilterInPlay { - protected FilterPermanent permanentFilter; - protected FilterPlayer playerFilter; + protected final FilterPermanent permanentFilter; + protected final FilterPlayer playerFilter; public FilterPermanentOrPlayer() { this("player or permanent"); @@ -90,18 +90,10 @@ public class FilterPermanentOrPlayer extends FilterImpl implements Fil return this.permanentFilter; } - public void setPermanentFilter(FilterPermanent permanentFilter) { - this.permanentFilter = permanentFilter; - } - public FilterPlayer getPlayerFilter() { return this.playerFilter; } - public void setPlayerFilter(FilterPlayer playerFilter) { - this.playerFilter = playerFilter; - } - @Override public FilterPermanentOrPlayer copy() { return new FilterPermanentOrPlayer(this); From 2f9ece1a41fc1abfdefaa92235d6672da3b202ed Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 28 Aug 2017 12:29:25 -0400 Subject: [PATCH 7/8] Revert "fixed goad effect" This reverts commit 6cd18246dee34210d3b367a92d58d66ecc0d246e. --- .../effects/common/combat/GoadAllEffect.java | 12 ++++-------- .../effects/common/combat/GoadTargetEffect.java | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java index fab77b1eae..47b7305421 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java @@ -28,9 +28,8 @@ package mage.abilities.effects.common.combat; import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.constants.Duration; import mage.constants.Outcome; import mage.filter.StaticFilters; import mage.game.Game; @@ -61,12 +60,9 @@ public class GoadAllEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) { if (!creature.getControllerId().equals(source.getControllerId())) { - ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); - effect.setTargetPointer(new FixedTarget(creature.getId())); - game.addEffect(effect, source); - effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); - effect.setTargetPointer(new FixedTarget(creature.getId())); - game.addEffect(effect, source); + Effect effect = new GoadTargetEffect(); + effect.setTargetPointer(new FixedTarget(creature, game)); + effect.apply(game, source); } } return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java index e32d2e35c6..38364d4d81 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java @@ -59,9 +59,9 @@ public class GoadTargetEffect extends OneShotEffect { ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); game.addEffect(effect, source); - effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); + effect = new CantAttackYouEffect(Duration.EndOfTurn, true); effect.setTargetPointer(new FixedTarget(source.getFirstTarget())); game.addEffect(effect, source); return true; } -} +} \ No newline at end of file From 44b37cd5c96acc60bbf7f58b6406a6343bf17fc3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 28 Aug 2017 12:33:52 -0400 Subject: [PATCH 8/8] fixed Portal Mage text --- Mage.Sets/src/mage/cards/p/PortalMage.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PortalMage.java b/Mage.Sets/src/mage/cards/p/PortalMage.java index 0d311349b8..7fa82ce8f2 100644 --- a/Mage.Sets/src/mage/cards/p/PortalMage.java +++ b/Mage.Sets/src/mage/cards/p/PortalMage.java @@ -68,11 +68,11 @@ public class PortalMage extends CardImpl { // Flash this.addAbility(FlashAbility.getInstance()); - // If Portal Mage enters the battlefield during the declare attackers step, you may reselect the player or planeswalker that the target attacking creature attacks. + // When Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or planeswalker target attacking creature is attacking. Ability ability = new ConditionalTriggeredAbility( new EntersBattlefieldTriggeredAbility(new PortalMageEffect(), true), new IsStepCondition(PhaseStep.DECLARE_ATTACKERS, false), - "If {this} enters the battlefield during the declare attackers step, you may reselect the player or planeswalker that the target attacking creature attacks. " + "When {this} enters the battlefield during the declare attackers step, you may reselect which player or planeswalker target attacking creature is attacking. " + "(It can't attack its controller or its controller's planeswalkers.)"); ability.addTarget(new TargetCreaturePermanent(new FilterAttackingCreature())); this.addAbility(ability); @@ -92,7 +92,7 @@ class PortalMageEffect extends OneShotEffect { public PortalMageEffect() { super(Outcome.Benefit); - this.staticText = "you may reselect the player or planeswalker that the target attacking creature attacks"; + this.staticText = "you may reselect which player or planeswalker target attacking creature is attacking"; } public PortalMageEffect(final PortalMageEffect effect) { @@ -147,7 +147,7 @@ class PortalMageEffect extends OneShotEffect { attacked = permanent.getLogName(); } } - game.informPlayers(attackingCreature.getLogName() + " attacks now " + attacked); + game.informPlayers(attackingCreature.getLogName() + " now attacks " + attacked); return true; } }