From 77bd944d8212dec8762f534a332a158c67172b8d Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 13 Jun 2014 14:02:03 +0200 Subject: [PATCH 1/4] * Unstoppable Ash - Fixed that the boost effect did not work. --- .../mage/sets/morningtide/UnstoppableAsh.java | 32 +++---------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/Mage.Sets/src/mage/sets/morningtide/UnstoppableAsh.java b/Mage.Sets/src/mage/sets/morningtide/UnstoppableAsh.java index a46d7d65b3..72d7ae4002 100644 --- a/Mage.Sets/src/mage/sets/morningtide/UnstoppableAsh.java +++ b/Mage.Sets/src/mage/sets/morningtide/UnstoppableAsh.java @@ -31,6 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesBlockedAllTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continious.BoostTargetEffect; import mage.abilities.keyword.ChampionAbility; @@ -76,7 +77,9 @@ public class UnstoppableAsh extends CardImpl { this.addAbility(new ChampionAbility(this, new String[]{"Treefolk", "Warrior"})); // Whenever a creature you control becomes blocked, it gets +0/+5 until end of turn. - this.addAbility(new BecomesBlockedAllTriggeredAbility(new UnstoppableAshEffect(), false, filter, true)); + Effect effect = new BoostTargetEffect(0, 5, Duration.EndOfTurn); + effect.setText("it gets +0/+5 until end of turn"); + this.addAbility(new BecomesBlockedAllTriggeredAbility(effect, false, filter, true)); } @@ -89,30 +92,3 @@ public class UnstoppableAsh extends CardImpl { return new UnstoppableAsh(this); } } - -class UnstoppableAshEffect extends OneShotEffect { - - UnstoppableAshEffect() { - super(Outcome.Neutral); - staticText = "it gets +0/+5 until end of turn"; - } - - UnstoppableAshEffect(final UnstoppableAshEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (creature != null) { - game.addEffect(new BoostTargetEffect(0, 5, Duration.EndOfTurn), source); - return true; - } - return false; - } - - @Override - public UnstoppableAshEffect copy() { - return new UnstoppableAshEffect(this); - } -} From 2305cc52744e9dcf2e7de7ff01190c75559a8d76 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 13 Jun 2014 14:02:56 +0200 Subject: [PATCH 2/4] * LogName - Changed some more messages to use the logName instead of name. --- .../abilities/abilityword/KinshipAbility.java | 6 +++--- .../abilities/common/CastCommanderAbility.java | 2 +- Mage/src/mage/game/combat/Combat.java | 18 +++++++++--------- Mage/src/mage/game/combat/CombatGroup.java | 14 +++++++------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Mage/src/mage/abilities/abilityword/KinshipAbility.java b/Mage/src/mage/abilities/abilityword/KinshipAbility.java index 2acd057b14..9f34633cae 100644 --- a/Mage/src/mage/abilities/abilityword/KinshipAbility.java +++ b/Mage/src/mage/abilities/abilityword/KinshipAbility.java @@ -120,10 +120,10 @@ class KinshipBaseEffect extends OneShotEffect { Card card = controller.getLibrary().getFromTop(game); if (card != null) { Cards cards = new CardsImpl(card); - controller.lookAtCards(sourcePermanent.getName(), cards, game); + controller.lookAtCards(sourcePermanent.getLogName(), cards, game); if (CardUtil.shareSubtypes(sourcePermanent, card)) { - if (controller.chooseUse(outcome,new StringBuilder("Kinship - Reveal ").append(card.getName()).append("?").toString(), game)) { - controller.revealCards(sourcePermanent.getName(), cards, game); + if (controller.chooseUse(outcome,new StringBuilder("Kinship - Reveal ").append(card.getLogName()).append("?").toString(), game)) { + controller.revealCards(sourcePermanent.getLogName(), cards, game); for (Effect effect: kinshipEffects) { effect.setTargetPointer(new FixedTarget(card.getId())); if (effect.getEffectType().equals(EffectType.ONESHOT)) { diff --git a/Mage/src/mage/abilities/common/CastCommanderAbility.java b/Mage/src/mage/abilities/common/CastCommanderAbility.java index faaf804a0e..daaeee63ce 100644 --- a/Mage/src/mage/abilities/common/CastCommanderAbility.java +++ b/Mage/src/mage/abilities/common/CastCommanderAbility.java @@ -42,7 +42,7 @@ import mage.game.Game; public class CastCommanderAbility extends SpellAbility { public CastCommanderAbility(Card card) { - super(card.getManaCost(), card.getName(), Zone.COMMAND, SpellAbilityType.BASE); + super(card.getManaCost(), card.getLogName(), Zone.COMMAND, SpellAbilityType.BASE); this.timing = TimingRule.SORCERY; this.usesStack = true; this.controllerId = card.getOwnerId(); diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java index c17c66f26b..034f30ffbb 100644 --- a/Mage/src/mage/game/combat/Combat.java +++ b/Mage/src/mage/game/combat/Combat.java @@ -260,7 +260,7 @@ public class Combat implements Serializable, Copyable { for (UUID attackingCreatureId : group.getAttackers()) { Permanent attacker = game.getPermanent(attackingCreatureId); if (count > 1 && attacker != null && attacker.getAbilities().containsKey(CanAttackOnlyAloneAbility.getInstance().getId())) { - game.informPlayers(attacker.getName() + " can only attack alone. Removing it from combat."); + game.informPlayers(attacker.getLogName() + " can only attack alone. Removing it from combat."); tobeRemoved.add(attackingCreatureId); count--; } @@ -277,7 +277,7 @@ public class Combat implements Serializable, Copyable { for (UUID attackingCreatureId : group.getAttackers()) { Permanent attacker = game.getPermanent(attackingCreatureId); if (attacker != null && attacker.getAbilities().containsKey(CantAttackAloneAbility.getInstance().getId())) { - game.informPlayers(attacker.getName() + " can't attack alone. Removing it from combat."); + game.informPlayers(attacker.getLogName() + " can't attack alone. Removing it from combat."); tobeRemoved.add(attackingCreatureId); } } @@ -358,13 +358,13 @@ public class Combat implements Serializable, Copyable { Permanent attackingCreature = game.getPermanent(attackingCreatureId); if (attackingCreature != null) { sb.append("Attacker: "); - sb.append(attackingCreature.getName()).append(" ("); + sb.append(attackingCreature.getLogName()).append(" ("); sb.append(attackingCreature.getPower().getValue()).append("/").append(attackingCreature.getToughness().getValue()).append(") "); } else { // creature left battlefield attackingCreature = (Permanent) game.getLastKnownInformation(attackingCreatureId, Zone.BATTLEFIELD); if (attackingCreature != null) { - sb.append(attackingCreature.getName()).append(" [left battlefield)] "); + sb.append(attackingCreature.getLogName()).append(" [left battlefield)] "); } } } @@ -374,7 +374,7 @@ public class Combat implements Serializable, Copyable { for (UUID blockingCreatureId : group.getBlockers()) { Permanent blockingCreature = game.getPermanent(blockingCreatureId); if (blockingCreature != null) { - sb.append(blockingCreature.getName()).append(" ("); + sb.append(blockingCreature.getLogName()).append(" ("); sb.append(blockingCreature.getPower().getValue()).append("/").append(blockingCreature.getToughness().getValue()).append(") "); } } @@ -554,7 +554,7 @@ public class Combat implements Serializable, Copyable { // if so inform human player or set block for AI player if (mayBlock) { if (controller.isHuman()) { - game.informPlayer(controller, "Creature should block this turn: " + creature.getName()); + game.informPlayer(controller, "Creature should block this turn: " + creature.getLogName()); } else { Player defender = game.getPlayer(creature.getControllerId()); if (defender != null) { @@ -622,7 +622,7 @@ public class Combat implements Serializable, Copyable { } } if (possibleBlockerAvailable) { - game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getName()).append(" has to be blocked by at least one creature.").toString()); + game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getLogName()).append(" has to be blocked by at least one creature.").toString()); return false; } } @@ -681,7 +681,7 @@ public class Combat implements Serializable, Copyable { } if (!blockIsValid) { - sb.append(" ").append(creatureForcedToBlock.getName()); + sb.append(" ").append(creatureForcedToBlock.getLogName()); } } if (sb.length() > 0) { @@ -711,7 +711,7 @@ public class Combat implements Serializable, Copyable { for (Ability ability : entry.getValue()) { if (!effect.canBeBlockedCheckAfter(attackingCreature, ability, game)) { if (controller.isHuman()) { - game.informPlayer(controller, new StringBuilder(attackingCreature.getName()).append(" can't be blocked this way.").toString()); + game.informPlayer(controller, new StringBuilder(attackingCreature.getLogName()).append(" can't be blocked this way.").toString()); return false; } else { // remove blocking creatures for AI diff --git a/Mage/src/mage/game/combat/CombatGroup.java b/Mage/src/mage/game/combat/CombatGroup.java index 465f543286..9d0c92e2e8 100644 --- a/Mage/src/mage/game/combat/CombatGroup.java +++ b/Mage/src/mage/game/combat/CombatGroup.java @@ -143,7 +143,7 @@ public class CombatGroup implements Serializable, Copyable { Permanent attacker = game.getPermanent(attackers.get(0)); if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { Player player = game.getPlayer(attacker.getControllerId()); - if (player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + attacker.getName() + " as though it weren't blocked?", game)) { + if (player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + attacker.getLogName() + " as though it weren't blocked?", game)) { blocked = false; unblockedDamage(first, game); } @@ -244,7 +244,7 @@ public class CombatGroup implements Serializable, Copyable { } else { Player player = game.getPlayer(attacker.getControllerId()); - int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); + int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getLogName(), game); blocker.markDamage(damageAssigned, attacker.getId(), game, true, true); damage -= damageAssigned; if (damage > 0) { @@ -298,7 +298,7 @@ public class CombatGroup implements Serializable, Copyable { damage = 0; break; } - int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); + int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getLogName(), game); assigned.put(blockerId, damageAssigned); damage -= damageAssigned; } @@ -378,7 +378,7 @@ public class CombatGroup implements Serializable, Copyable { assigned.put(attackerId, damage); break; } - int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + attacker.getName(), game); + int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + attacker.getLogName(), game); assigned.put(attackerId, damageAssigned); damage -= damageAssigned; } @@ -537,7 +537,7 @@ public class CombatGroup implements Serializable, Copyable { Permanent blocker = game.getPermanent(blockerId); if (blocker != null && blocker.getAbilities().containsKey(CantBlockAloneAbility.getInstance().getId())) { blockWasLegal = false; - game.informPlayers(blocker.getName() + " can't block alone. Removing it from combat."); + game.informPlayers(blocker.getLogName() + " can't block alone. Removing it from combat."); toBeRemoved.add(blockerId); } } @@ -563,7 +563,7 @@ public class CombatGroup implements Serializable, Copyable { blockers.clear(); blockerOrder.clear(); this.blocked = false; - game.informPlayers(attacker.getName() + " can't be blocked except by " + attacker.getMinBlockedBy() + " or more creatures. Blockers discarded."); + game.informPlayers(attacker.getLogName() + " can't be blocked except by " + attacker.getMinBlockedBy() + " or more creatures. Blockers discarded."); blockWasLegal = false; } // Check if there are to many blockers (maxBlockedBy = 0 means no restrictions) @@ -577,7 +577,7 @@ public class CombatGroup implements Serializable, Copyable { blockers.clear(); blockerOrder.clear(); this.blocked = false; - game.informPlayers(new StringBuilder(attacker.getName()) + game.informPlayers(new StringBuilder(attacker.getLogName()) .append(" can't be blocked by more than ").append(attacker.getMaxBlockedBy()) .append(attacker.getMaxBlockedBy()==1?" creature.":" creatures.") .append(" Blockers discarded.").toString()); From 48f149c549f40250958a21850a12db7794182e84 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 13 Jun 2014 15:09:06 +0200 Subject: [PATCH 3/4] * LogName - Changed some more messages to use the logName instead of name. --- Mage.Sets/src/mage/sets/tempest/SeaMonster.java | 2 +- Mage/src/mage/game/GameImpl.java | 3 +++ Mage/src/mage/game/permanent/PermanentImpl.java | 8 ++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/sets/tempest/SeaMonster.java b/Mage.Sets/src/mage/sets/tempest/SeaMonster.java index 88a9082d5a..59bca7b48c 100644 --- a/Mage.Sets/src/mage/sets/tempest/SeaMonster.java +++ b/Mage.Sets/src/mage/sets/tempest/SeaMonster.java @@ -47,7 +47,7 @@ import mage.game.events.GameEvent; * * @author Plopman */ -public class SeaMonster extends CardImpl { + public class SeaMonster extends CardImpl { public SeaMonster(UUID ownerId) { super(ownerId, 85, "Sea Monster", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{U}{U}"); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 1dbc6ad15a..02c77afc66 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -524,6 +524,9 @@ public abstract class GameImpl implements Game, Serializable { public void restoreState(int bookmark) { if (!simulation) { if (bookmark != 0) { + if (savedStates.contains(bookmark - 1)) { + throw new UnsupportedOperationException("It was not possible to do the requested undo operation (bookmark " + (bookmark -1) + " does not exist)"); + } int stateNum = savedStates.get(bookmark - 1); removeBookmark(bookmark); GameState restore = gameStates.rollback(stateNum); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 10458f50b2..3889be96c1 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -792,9 +792,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { if (!game.replaceEvent(GameEvent.getEvent(EventType.DESTROY_PERMANENT, objectId, sourceId, controllerId, noRegen ? 1 : 0))) { if (moveToZone(Zone.GRAVEYARD, sourceId, game, false)) { if (this.getCardType().contains(CardType.CREATURE)) { - game.informPlayers(new StringBuilder(this.getName()).append(" died").toString()); + game.informPlayers(new StringBuilder(this.getLogName()).append(" died").toString()); } else { - game.informPlayers(new StringBuilder(this.getName()).append(" was destroyed").toString()); + game.informPlayers(new StringBuilder(this.getLogName()).append(" was destroyed").toString()); } game.fireEvent(GameEvent.getEvent(EventType.DESTROYED_PERMANENT, objectId, sourceId, controllerId)); return true; @@ -811,7 +811,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { moveToZone(Zone.GRAVEYARD, sourceId, game, true); Player player = game.getPlayer(getControllerId()); if (player != null) { - game.informPlayers(new StringBuilder(player.getName()).append(" sacrificed ").append(this.getName()).toString()); + game.informPlayers(new StringBuilder(player.getName()).append(" sacrificed ").append(this.getLogName()).toString()); } game.fireEvent(GameEvent.getEvent(EventType.SACRIFICED_PERMANENT, objectId, sourceId, controllerId)); return true; @@ -970,7 +970,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { public boolean removeFromCombat(Game game) { if (this.isAttacking() || this.blocking > 0) { if (game.getCombat().removeFromCombat(objectId, game)) { - game.informPlayers(new StringBuilder(this.getName()).append(" removed from combat").toString()); + game.informPlayers(new StringBuilder(this.getLogName()).append(" removed from combat").toString()); } } return true; From 86995cde87bd92c4a0c9a70a88071275fe03be4f Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 13 Jun 2014 15:10:37 +0200 Subject: [PATCH 4/4] * Propaganda, Windborn Muse, Ghostly Prison, Elephant Grass - Fixed bug that the attacker was wrongly forced to pay cost also if he attacked a planeswalker. --- .../championsofkamigawa/GhostlyPrison.java | 16 +++++++++++----- .../src/mage/sets/tempest/Propaganda.java | 14 +++++++++----- .../src/mage/sets/tenth/WindbornMuse.java | 19 +++++++++++++------ .../src/mage/sets/visions/ElephantGrass.java | 18 +++++++++++------- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java b/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java index 594679f9d9..be23c5977f 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java @@ -50,6 +50,8 @@ public class GhostlyPrison extends CardImpl { super(ownerId, 10, "Ghostly Prison", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); this.expansionSetCode = "CHK"; this.color.setWhite(true); + + // Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GhostlyPrisonReplacementEffect())); } @@ -87,10 +89,10 @@ class GhostlyPrisonReplacementEffect extends ReplacementEffectImpl { if ( event.getType() == GameEvent.EventType.DECLARE_ATTACKER) { Player player = game.getPlayer(event.getPlayerId()); if ( player != null && event.getTargetId().equals(source.getControllerId())) { - ManaCostsImpl propagandaTax = new ManaCostsImpl("{2}"); - if ( propagandaTax.canPay(source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, "Pay {2} to declare attacker?", game) ) { - if (propagandaTax.payOrRollback(source, game, this.getId(), event.getPlayerId())) { + ManaCostsImpl attackTax = new ManaCostsImpl("{2}"); + if ( attackTax.canPay(source.getSourceId(), event.getPlayerId(), game) && + player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", game) ) { + if (attackTax.payOrRollback(source, game, this.getId(), event.getPlayerId())) { return false; } } @@ -103,7 +105,11 @@ class GhostlyPrisonReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if ( event.getType() == GameEvent.EventType.DECLARE_ATTACKER && event.getTargetId().equals(source.getControllerId()) ) { - return true; + Player attackedPlayer = game.getPlayer(event.getTargetId()); + if (attackedPlayer != null) { + // only if a player is attacked. Attacking a planeswalker is free + return true; + } } return false; } diff --git a/Mage.Sets/src/mage/sets/tempest/Propaganda.java b/Mage.Sets/src/mage/sets/tempest/Propaganda.java index 0fc3fef66c..9c99525e51 100644 --- a/Mage.Sets/src/mage/sets/tempest/Propaganda.java +++ b/Mage.Sets/src/mage/sets/tempest/Propaganda.java @@ -89,11 +89,11 @@ class PropagandaReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(event.getPlayerId()); if ( player != null ) { - ManaCostsImpl propagandaTax = new ManaCostsImpl("{2}"); - if ( propagandaTax.canPay(source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Neutral, "Pay {2} to declare attacker?", game) ) + ManaCostsImpl attackTax = new ManaCostsImpl("{2}"); + if ( attackTax.canPay(source.getSourceId(), event.getPlayerId(), game) && + player.chooseUse(Outcome.Neutral, "Pay {2} to attack player?", game) ) { - if (propagandaTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId()) ) { + if (attackTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId()) ) { return false; } } @@ -105,7 +105,11 @@ class PropagandaReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if ( event.getType() == GameEvent.EventType.DECLARE_ATTACKER && event.getTargetId().equals(source.getControllerId())) { - return true; + Player attackedPlayer = game.getPlayer(event.getTargetId()); + if (attackedPlayer != null) { + // only if a player is attacked. Attacking a planeswalker is free + return true; + } } return false; } diff --git a/Mage.Sets/src/mage/sets/tenth/WindbornMuse.java b/Mage.Sets/src/mage/sets/tenth/WindbornMuse.java index 61f3b59696..83303e186d 100644 --- a/Mage.Sets/src/mage/sets/tenth/WindbornMuse.java +++ b/Mage.Sets/src/mage/sets/tenth/WindbornMuse.java @@ -54,9 +54,12 @@ public class WindbornMuse extends CardImpl { this.color.setWhite(true); this.power = new MageInt(2); this.toughness = new MageInt(3); + + // Flying this.addAbility(FlyingAbility.getInstance()); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WindbornMuseReplacementEffect())); // Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WindbornMuseReplacementEffect())); + } public WindbornMuse(final WindbornMuse card) { @@ -92,11 +95,11 @@ class WindbornMuseReplacementEffect extends ReplacementEffectImpl { if ( event.getType() == GameEvent.EventType.DECLARE_ATTACKER) { Player player = game.getPlayer(event.getPlayerId()); if ( player != null && event.getTargetId().equals(source.getControllerId())) { - ManaCostsImpl propagandaTax = new ManaCostsImpl("{2}"); - if ( propagandaTax.canPay(source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, "Pay {2} to declare attacker?", game) ) + ManaCostsImpl attackTax = new ManaCostsImpl("{2}"); + if ( attackTax.canPay(source.getSourceId(), event.getPlayerId(), game) && + player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", game) ) { - if (propagandaTax.payOrRollback(source, game, this.getId(), event.getPlayerId())) { + if (attackTax.payOrRollback(source, game, this.getId(), event.getPlayerId())) { return false; } } @@ -109,7 +112,11 @@ class WindbornMuseReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if ( event.getType() == GameEvent.EventType.DECLARE_ATTACKER && event.getTargetId().equals(source.getControllerId()) ) { - return true; + Player attackedPlayer = game.getPlayer(event.getTargetId()); + if (attackedPlayer != null) { + // only if a player is attacked. Attacking a planeswalker is free + return true; + } } return false; } diff --git a/Mage.Sets/src/mage/sets/visions/ElephantGrass.java b/Mage.Sets/src/mage/sets/visions/ElephantGrass.java index d32dbebf7d..908b8e174c 100644 --- a/Mage.Sets/src/mage/sets/visions/ElephantGrass.java +++ b/Mage.Sets/src/mage/sets/visions/ElephantGrass.java @@ -133,10 +133,10 @@ class ElephantGrassReplacementEffect2 extends ReplacementEffectImpl { if ( event.getType() == GameEvent.EventType.DECLARE_ATTACKER) { Player player = game.getPlayer(event.getPlayerId()); if ( player != null && event.getTargetId().equals(source.getControllerId())) { - ManaCostsImpl cost = new ManaCostsImpl("{2}"); - if ( cost.canPay(source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, "Pay {2} to declare attacker?", game) ) { - if (cost.payOrRollback(source, game, this.getId(), event.getPlayerId())) { + ManaCostsImpl attackCost = new ManaCostsImpl("{2}"); + if ( attackCost.canPay(source.getSourceId(), event.getPlayerId(), game) && + player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", game) ) { + if (attackCost.payOrRollback(source, game, this.getId(), event.getPlayerId())) { return false; } } @@ -150,8 +150,12 @@ class ElephantGrassReplacementEffect2 extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if ( event.getType() == GameEvent.EventType.DECLARE_ATTACKER && event.getTargetId().equals(source.getControllerId()) ) { Permanent creature = game.getPermanent(event.getSourceId()); - if(creature != null && !creature.getColor().isBlack()){ - return true; + if (creature != null && !creature.getColor().isBlack()) { + Player attackedPlayer = game.getPlayer(event.getTargetId()); + if (attackedPlayer != null) { + // only if a player is attacked. Attacking a planeswalker is free + return true; + } } } return false; @@ -162,4 +166,4 @@ class ElephantGrassReplacementEffect2 extends ReplacementEffectImpl { return new ElephantGrassReplacementEffect2(this); } -} \ No newline at end of file +}