From d5148afaeb36e4252c53e22b063889937a0baa67 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 25 Mar 2014 23:59:17 +0100 Subject: [PATCH] * Sormtide Leviathan - Fixed that the Islands could not produce U mana. Fixed bug in the attack restriction effect. --- .../src/mage/sets/gatecrash/Realmwright.java | 10 +- .../src/mage/sets/innistrad/WitchbaneOrb.java | 10 +- .../mage/sets/magic2011/LeylineOfTheVoid.java | 34 ++--- .../sets/magic2011/StormtideLeviathan.java | 117 ++++++++---------- .../combat/CantAttackAllAnyPlayerEffect.java | 73 +++++++++++ .../combat/CantAttackAllSourceEffect.java | 7 +- 6 files changed, 160 insertions(+), 91 deletions(-) create mode 100644 Mage/src/mage/abilities/effects/common/combat/CantAttackAllAnyPlayerEffect.java diff --git a/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java b/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java index 6be1e3b77b..5a8ce7b9c4 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java +++ b/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java @@ -162,7 +162,7 @@ class RealmwrightEffect2 extends ContinuousEffectImpl { } } if (addAbility) { - land.addAbility(new GreenManaAbility(), source.getId(), game); + land.addAbility(new GreenManaAbility(), source.getSourceId(), game); } } if (choice.equals("Plains")) { @@ -173,7 +173,7 @@ class RealmwrightEffect2 extends ContinuousEffectImpl { } } if (addAbility) { - land.addAbility(new WhiteManaAbility(), source.getId(), game); + land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); } } if (choice.equals("Mountain")) { @@ -184,7 +184,7 @@ class RealmwrightEffect2 extends ContinuousEffectImpl { } } if (addAbility) { - land.addAbility(new RedManaAbility(), source.getId(), game); + land.addAbility(new RedManaAbility(), source.getSourceId(), game); } } if (choice.equals("Island")) { @@ -195,7 +195,7 @@ class RealmwrightEffect2 extends ContinuousEffectImpl { } } if (addAbility) { - land.addAbility(new BlueManaAbility(), source.getId(), game); + land.addAbility(new BlueManaAbility(), source.getSourceId(), game); } } if (choice.equals("Swamp")) { @@ -206,7 +206,7 @@ class RealmwrightEffect2 extends ContinuousEffectImpl { } } if (addAbility) { - land.addAbility(new BlackManaAbility(), source.getId(), game); + land.addAbility(new BlackManaAbility(), source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/sets/innistrad/WitchbaneOrb.java b/Mage.Sets/src/mage/sets/innistrad/WitchbaneOrb.java index fd9d18346d..7817fe9aa1 100644 --- a/Mage.Sets/src/mage/sets/innistrad/WitchbaneOrb.java +++ b/Mage.Sets/src/mage/sets/innistrad/WitchbaneOrb.java @@ -28,10 +28,6 @@ package mage.sets.innistrad; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -39,6 +35,10 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continious.GainAbilityControllerEffect; import mage.abilities.keyword.HexproofAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -102,4 +102,4 @@ class WitchbaneOrbEffect extends OneShotEffect { return new WitchbaneOrbEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2011/LeylineOfTheVoid.java b/Mage.Sets/src/mage/sets/magic2011/LeylineOfTheVoid.java index 29923f2e0a..05fb50b245 100644 --- a/Mage.Sets/src/mage/sets/magic2011/LeylineOfTheVoid.java +++ b/Mage.Sets/src/mage/sets/magic2011/LeylineOfTheVoid.java @@ -29,22 +29,23 @@ package mage.sets.magic2011; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.LeylineAbility; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; +import mage.players.Player; /** * @@ -56,7 +57,9 @@ public class LeylineOfTheVoid extends CardImpl { super(ownerId, 101, "Leyline of the Void", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); this.expansionSetCode = "M11"; this.color.setBlack(true); + // If Leyline of the Void is in your opening hand, you may begin the game with it on the battlefield. this.addAbility(LeylineAbility.getInstance()); + // If a card would be put into an opponent's graveyard from anywhere, exile it instead. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeylineOfTheVoidEffect())); } @@ -94,16 +97,19 @@ class LeylineOfTheVoidEffect extends ReplacementEffectImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures without flying or islandwalk"); + + static { + filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + filter.add(Predicates.not(new AbilityPredicate(IslandwalkAbility.class))); + } + public StormtideLeviathan(UUID ownerId) { super(ownerId, 74, "Stormtide Leviathan", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{U}{U}{U}"); this.expansionSetCode = "M11"; @@ -65,9 +75,12 @@ public class StormtideLeviathan extends CardImpl { this.power = new MageInt(8); this.toughness = new MageInt(8); + // Islandwalk (This creature is unblockable as long as defending player controls an Island.) this.addAbility(new IslandwalkAbility()); + // All lands are Islands in addition to their other types. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new StormtideLeviathanEffect())); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new StormtideLeviathanEffect2())); + // Creatures without flying or islandwalk can't attack. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAllAnyPlayerEffect(Duration.WhileOnBattlefield, filter))); } @@ -85,7 +98,7 @@ public class StormtideLeviathan extends CardImpl { class StormtideLeviathanEffect extends ContinuousEffectImpl { public StormtideLeviathanEffect() { - super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment); + super(Duration.WhileOnBattlefield, Outcome.Neutral); staticText = "All lands are Islands in addition to their other types"; } @@ -99,58 +112,38 @@ class StormtideLeviathanEffect extends ContinuousEffectImpl { - - private static IslandwalkAbility islandwalk = new IslandwalkAbility(); - - public StormtideLeviathanEffect2() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Creatures without flying or islandwalk can't attack"; - } - - public StormtideLeviathanEffect2(final StormtideLeviathanEffect2 effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public StormtideLeviathanEffect2 copy() { - return new StormtideLeviathanEffect2(this); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == EventType.DECLARE_ATTACKER) { - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null) { - Player player = game.getPlayer(source.getControllerId()); - if (player.getInRange().contains(permanent.getControllerId())) { - if (!(permanent.getAbilities().containsKey(FlyingAbility.getInstance().getId()) || - permanent.getAbilities().contains(islandwalk))) - return true; - } + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + for (Permanent land : game.getBattlefield().getActivePermanents(new FilterLandPermanent(), source.getControllerId(), game)) { + switch (layer) { + case TypeChangingEffects_4: + if (!land.getSubtype().contains("Island")) { + land.getSubtype().add("Island"); + } + break; + case AbilityAddingRemovingEffects_6: + boolean addAbility = true; + for (Ability existingAbility : land.getAbilities()) { + if (existingAbility instanceof BlueManaAbility) { + addAbility = false; + break; + } + } + if (addAbility) { + land.addAbility(new BlueManaAbility(), source.getSourceId(), game); + } + break; } } + return true; + } + + @Override + public boolean apply(Game game, Ability source) { return false; } + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; + } } diff --git a/Mage/src/mage/abilities/effects/common/combat/CantAttackAllAnyPlayerEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantAttackAllAnyPlayerEffect.java new file mode 100644 index 0000000000..6c69f1b4ba --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/combat/CantAttackAllAnyPlayerEffect.java @@ -0,0 +1,73 @@ +/* + * 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.RestrictionEffect; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * The creatures defined by filter can't attack any opponent + * + * @author LevelX2 + */ +public class CantAttackAllAnyPlayerEffect extends RestrictionEffect { + + private final FilterCreaturePermanent filter; + + public CantAttackAllAnyPlayerEffect(Duration duration, FilterCreaturePermanent filter) { + super(duration); + this.filter = filter; + staticText = new StringBuilder(filter.getMessage()).append(" can't attack").toString(); + } + + public CantAttackAllAnyPlayerEffect(final CantAttackAllAnyPlayerEffect effect) { + super(effect); + this.filter = effect.filter; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return filter.match(permanent, source.getSourceId(), source.getControllerId(), game); + } + + @Override + public boolean canAttack(Game game) { + return false; + } + + @Override + public CantAttackAllAnyPlayerEffect copy() { + return new CantAttackAllAnyPlayerEffect(this); + } + +} diff --git a/Mage/src/mage/abilities/effects/common/combat/CantAttackAllSourceEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantAttackAllSourceEffect.java index bc35ae12b9..a259204c24 100644 --- a/Mage/src/mage/abilities/effects/common/combat/CantAttackAllSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/combat/CantAttackAllSourceEffect.java @@ -28,9 +28,9 @@ package mage.abilities.effects.common.combat; -import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.effects.RestrictionEffect; +import mage.constants.Duration; import mage.game.Game; import mage.game.permanent.Permanent; @@ -51,10 +51,7 @@ public class CantAttackAllSourceEffect extends RestrictionEffect