From b7a0fa42fb220c47e06e5fd3b563f129dfcb98a2 Mon Sep 17 00:00:00 2001 From: spjspj Date: Sat, 6 Feb 2016 00:50:41 +1100 Subject: [PATCH 1/2] spjspj - Implement Mana Web (Weatherlight) --- .../src/mage/sets/weatherlight/ManaWeb.java | 174 ++++++++++++++++++ Mage/src/main/java/mage/Mana.java | 25 +++ 2 files changed, 199 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/weatherlight/ManaWeb.java diff --git a/Mage.Sets/src/mage/sets/weatherlight/ManaWeb.java b/Mage.Sets/src/mage/sets/weatherlight/ManaWeb.java new file mode 100644 index 0000000000..dd94bf3526 --- /dev/null +++ b/Mage.Sets/src/mage/sets/weatherlight/ManaWeb.java @@ -0,0 +1,174 @@ +/* + * 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.weatherlight; + +import java.util.Iterator; +import java.util.UUID; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousEffects; +import mage.abilities.effects.ContinuousEffectsList; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterLandPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffect; +import mage.abilities.mana.ManaAbility; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ManaEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * @author spjspj + */ +public class ManaWeb extends CardImpl { + + public ManaWeb(UUID ownerId) { + super(ownerId, 152, "Mana Web", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "WTH"; + + // Whenever a land an opponent controls is tapped for mana, tap all lands that player controls that could produce any type of mana that land could produce. + this.addAbility(new ManaWebTriggeredAbility()); + } + + public ManaWeb(final ManaWeb card) { + super(card); + } + + @Override + public ManaWeb copy() { + return new ManaWeb(this); + } +} + +class ManaWebTriggeredAbility extends TriggeredAbilityImpl { + + public ManaWebTriggeredAbility() { + super(Zone.BATTLEFIELD, new ManaWebeffect(), false); + } + + private static final String staticText = "Whenever a land an opponent controls is tapped for mana, tap all lands that player controls that could produce any type of mana that land could produce."; + + public ManaWebTriggeredAbility(ManaWebTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.TAPPED_FOR_MANA; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getOpponents(controllerId).contains(event.getPlayerId())) { + Permanent permanent = game.getPermanent(event.getSourceId()); + + if (permanent != null && permanent.getCardType().contains(CardType.LAND)) { + this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getSourceId())); + return true; + } + } + return false; + } + + @Override + public ManaWebTriggeredAbility copy() { + return new ManaWebTriggeredAbility(this); + } + + @Override + public String getRule() { + return staticText; + } +} + +class ManaWebeffect extends OneShotEffect { + + private int attackers; + private final static FilterLandPermanent filter = new FilterLandPermanent("an opponent taps a land"); + + public ManaWebeffect() { + super(Outcome.Tap); + staticText = "Whenever a land an opponent controls is tapped for mana, tap all lands that player controls that could produce any type of mana that land could produce."; + } + + public ManaWebeffect(final ManaWebeffect effect) { + super(effect); + } + + @Override + public ManaWebeffect copy() { + return new ManaWebeffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = null; + + if (game != null && source != null) { + permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + } + + if (permanent != null && game != null) { + Mana mana = new Mana(); + + for (ManaAbility ability : permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) { + for (Mana netMana : ability.getNetMana(game)) { + mana.add(netMana); + } + } + + boolean tappedLands = false; + for (Permanent opponentPermanent : game.getBattlefield().getActivePermanents(filter, permanent.getControllerId(), game)) { + if (opponentPermanent.getControllerId() == permanent.getControllerId()) { + Mana opponentLandMana = new Mana(); + + for (ManaAbility ability : opponentPermanent.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) { + for (Mana netMana : ability.getNetMana(game)) { + opponentLandMana.add(netMana); + } + } + + if (mana.containsAny(opponentLandMana)) { + tappedLands = opponentPermanent.tap(game) || tappedLands; + } + } + } + return tappedLands; + } + return false; + } +} diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java index 779d31f7cc..f4abecd691 100644 --- a/Mage/src/main/java/mage/Mana.java +++ b/Mage/src/main/java/mage/Mana.java @@ -812,6 +812,31 @@ public class Mana implements Comparable, Serializable, Copyable { return false; } + /** + * Returns if this objects mana contains any mana the same as the passed in + * {@link Mana}'s mana. + * + * @param mana the mana to check for + * @return true if this contains any of the same type of mana that this has + */ + public boolean containsAny(final Mana mana) { + if (mana.black > 0 && this.black > 0) { + return true; + } else if (mana.blue > 0 && this.blue > 0) { + return true; + } else if (mana.red > 0 && this.red > 0) { + return true; + } else if (mana.white > 0 && this.white > 0) { + return true; + } else if (mana.green > 0 && this.green > 0) { + return true; + } else if (mana.colorless > 0 && this.colorless > 0) { + return true; + } + + return false; + } + /** * Returns the total count of mana in this object as specified by the passed * in {@link ColoredManaSymbol}. From f5adc6591efae428e33629e7c5ea34cd185cf1b7 Mon Sep 17 00:00:00 2001 From: spjspj Date: Sat, 6 Feb 2016 02:20:58 +1100 Subject: [PATCH 2/2] spjspj - Reduce to Dreams was only returning the controller's enchantments/artifacts to hand. Should be all players in range having them returned to hand. --- .../betrayersofkamigawa/ReduceToDreams.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/ReduceToDreams.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/ReduceToDreams.java index ac93abbb65..1a8e01a6fa 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/ReduceToDreams.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/ReduceToDreams.java @@ -36,11 +36,14 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.other.OwnerIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; /** * @@ -72,11 +75,11 @@ class ReduceToDreamsEffect extends OneShotEffect { private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifacts and enchantments"); static { filter.add(Predicates.or( - new CardTypePredicate(CardType.ARTIFACT), - new CardTypePredicate(CardType.ENCHANTMENT) - )); + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.ENCHANTMENT) + )); } - + public ReduceToDreamsEffect() { super(Outcome.ReturnToHand); staticText = "Return all artifacts and enchantments to their owners' hands"; @@ -88,8 +91,15 @@ class ReduceToDreamsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - creature.moveToZone(Zone.HAND, source.getSourceId(), game, true); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID playerId : controller.getInRange()) { + FilterPermanent playerFilter = filter.copy(); + playerFilter.add(new OwnerIdPredicate(playerId)); + for (Permanent permanent : game.getBattlefield().getActivePermanents(playerFilter, playerId, game)) { + permanent.moveToZone(Zone.HAND, playerId, game, true); + } + } } return true; }