diff --git a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java
index e6e12b2eec5..5c1a49af5e5 100644
--- a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java
+++ b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java
@@ -41,6 +41,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.util.CardUtil;
/**
*
@@ -106,7 +107,7 @@ class AngrathsMaraudersEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(2 * event.getAmount());
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java b/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java
index 068b806cfb4..c3ec17a4179 100644
--- a/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java
+++ b/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java
@@ -44,6 +44,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.util.CardUtil;
/**
* @author JotaPeRL
@@ -110,7 +111,7 @@ class AnthemOfRakdosHellbentEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AshnodsCylix.java b/Mage.Sets/src/mage/cards/a/AshnodsCylix.java
new file mode 100644
index 00000000000..fd11615bf38
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AshnodsCylix.java
@@ -0,0 +1,125 @@
+/*
+ * 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.a;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.TargetCard;
+import mage.target.TargetPlayer;
+
+/**
+ *
+ * @author L_J
+ */
+public class AshnodsCylix extends CardImpl {
+
+ public AshnodsCylix(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
+
+ // {3}, {T}: Target player looks at the top three cards of his or her library, puts one of them back on top of his or her library, then exiles the rest.
+ SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AshnodsCylixEffect(), new GenericManaCost(3));
+ ability.addCost(new TapSourceCost());
+ ability.addTarget(new TargetPlayer());
+ this.addAbility(ability);
+ }
+
+ public AshnodsCylix(final AshnodsCylix card) {
+ super(card);
+ }
+
+ @Override
+ public AshnodsCylix copy() {
+ return new AshnodsCylix(this);
+ }
+}
+
+class AshnodsCylixEffect extends OneShotEffect {
+
+ AshnodsCylixEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "Target player looks at the top three cards of his or her library, puts one of them back on top of his or her library, then exiles the rest";
+ }
+
+ AshnodsCylixEffect(final AshnodsCylixEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AshnodsCylixEffect copy() {
+ return new AshnodsCylixEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getFirstTarget());
+ if (player == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl();
+ int count = Math.min(player.getLibrary().size(), 3);
+ for (int i = 0; i < count; i++) {
+ Card card = player.getLibrary().removeFromTop(game);
+ if (card != null) {
+ cards.add(card);
+ }
+ }
+ //~ player.revealCards(source.getSourceObject(game).getIdName(), cards, game);
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on top of your library"));
+ if (player.choose(Outcome.DrawCard, cards, target, game)) {
+ Card card = cards.get(target.getFirstTarget(), game);
+ if (card != null) {
+ cards.remove(card);
+ player.getLibrary().putOnTop(card, game);
+ game.informPlayers(source.getSourceObject(game).getIdName() + ": " + player.getLogName() + " puts a card on top of his or her library");
+ }
+ }
+ for (UUID cardId : cards) {
+ Card card = game.getCard(cardId);
+ card.moveToExile(null, "", source.getSourceId(), game);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BitterFeud.java b/Mage.Sets/src/mage/cards/b/BitterFeud.java
index 5297a739da0..e7d64955514 100644
--- a/Mage.Sets/src/mage/cards/b/BitterFeud.java
+++ b/Mage.Sets/src/mage/cards/b/BitterFeud.java
@@ -47,6 +47,7 @@ import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.TargetPlayer;
+import mage.util.CardUtil;
/**
*
@@ -194,7 +195,7 @@ class BitterFeudEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BrandedBrawlers.java b/Mage.Sets/src/mage/cards/b/BrandedBrawlers.java
new file mode 100644
index 00000000000..83553cefb51
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrandedBrawlers.java
@@ -0,0 +1,122 @@
+/*
+ * 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.b;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.RestrictionEffect;
+import mage.abilities.effects.common.combat.CantAttackIfDefenderControlsPermanent;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterLandPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ * @author L_J
+ */
+public class BrandedBrawlers extends CardImpl {
+
+ static final private FilterLandPermanent filter = new FilterLandPermanent("an untapped land");
+ static {
+ filter.add(Predicates.not(new TappedPredicate()));
+ }
+
+ final static private String rule = "{this} can't block if you control an untapped land";
+
+ public BrandedBrawlers(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Branded Brawlers can't attack if defending player controls an untapped land.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackIfDefenderControlsPermanent(filter)));
+
+ // Branded Brawlers can't block if you control an untapped land.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BrandedBrawlersCantBlockEffect(filter)));
+ }
+
+ public BrandedBrawlers(final BrandedBrawlers card) {
+ super(card);
+ }
+
+ @Override
+ public BrandedBrawlers copy() {
+ return new BrandedBrawlers(this);
+ }
+}
+
+class BrandedBrawlersCantBlockEffect extends RestrictionEffect {
+
+ private final FilterPermanent filter;
+
+ public BrandedBrawlersCantBlockEffect(FilterPermanent filter) {
+ super(Duration.WhileOnBattlefield);
+ this.filter = filter;
+ staticText = new StringBuilder("{this} can't attack if you control ").append(filter.getMessage()).toString();
+ }
+
+ public BrandedBrawlersCantBlockEffect(final BrandedBrawlersCantBlockEffect effect) {
+ super(effect);
+ this.filter = effect.filter;
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return permanent.getId().equals(source.getSourceId());
+ }
+
+ @Override
+ public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
+ Player player = game.getPlayer(blocker.getControllerId());
+ if (player != null) {
+ if (game.getBattlefield().countAll(filter, player.getId(), game) > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public BrandedBrawlersCantBlockEffect copy() {
+ return new BrandedBrawlersCantBlockEffect(this);
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/b/ButcherOrgg.java b/Mage.Sets/src/mage/cards/b/ButcherOrgg.java
new file mode 100644
index 00000000000..f12cd58780a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/ButcherOrgg.java
@@ -0,0 +1,63 @@
+/*
+ * 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.b;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.ControllerDivideCombatDamageAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+/**
+ *
+ * @author L_J
+ */
+public class ButcherOrgg extends CardImpl {
+
+ public ButcherOrgg(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}{R}");
+ this.subtype.add(SubType.ORGG);
+
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // You may assign Butcher Orgg's combat damage divided as you choose among defending player and/or any number of creatures he or she controls.
+ this.addAbility(ControllerDivideCombatDamageAbility.getInstance());
+ }
+
+ public ButcherOrgg(final ButcherOrgg card) {
+ super(card);
+ }
+
+ @Override
+ public ButcherOrgg copy() {
+ return new ButcherOrgg(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CallousOppressor.java b/Mage.Sets/src/mage/cards/c/CallousOppressor.java
new file mode 100644
index 00000000000..63acbd3c2e1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CallousOppressor.java
@@ -0,0 +1,186 @@
+/*
+ * 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.c;
+
+import java.util.LinkedHashSet;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.AsEntersBattlefieldAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SkipUntapOptionalAbility;
+import mage.abilities.condition.common.SourceTappedCondition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.choices.Choice;
+import mage.choices.ChoiceImpl;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetCreaturePermanent;
+import mage.target.common.TargetOpponent;
+import mage.util.CardUtil;
+
+/**
+ *
+ * @author L_J
+ */
+public class CallousOppressor extends CardImpl {
+
+ public CallousOppressor(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}");
+ this.subtype.add(SubType.CEPHALID);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // You may choose not to untap Callous Oppressor during your untap step.
+ this.addAbility(new SkipUntapOptionalAbility());
+
+ // As Callous Oppressor enters the battlefield, an opponent chooses a creature type.
+ this.addAbility(new AsEntersBattlefieldAbility(new CallousOppressorChooseCreatureTypeEffect()));
+
+ // {T}: Gain control of target creature that isn't of the chosen type for as long as Callous Oppressor remains tapped.
+ ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
+ new GainControlTargetEffect(Duration.OneUse),
+ SourceTappedCondition.instance,
+ "Gain control of target creature for as long as {this} remains tapped");
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
+ ability.addTarget(new TargetCreaturePermanent(new CallousOppressorFilter()));
+ this.addAbility(ability);
+ }
+
+ public CallousOppressor(final CallousOppressor card) {
+ super(card);
+ }
+
+ @Override
+ public CallousOppressor copy() {
+ return new CallousOppressor(this);
+ }
+}
+
+class CallousOppressorFilter extends FilterCreaturePermanent {
+
+ public CallousOppressorFilter() {
+ super("creature that isn't of the chosen type");
+ }
+
+ public CallousOppressorFilter(final CallousOppressorFilter filter) {
+ super(filter);
+ }
+
+ @Override
+ public CallousOppressorFilter copy() {
+ return new CallousOppressorFilter(this);
+ }
+
+ @Override
+ public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
+ if (super.match(permanent, sourceId, playerId, game)) {
+ SubType subtype = (SubType) game.getState().getValue(sourceId + "_type");
+ if (subtype != null && permanent.hasSubtype(subtype, game)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+}
+
+class CallousOppressorChooseCreatureTypeEffect extends OneShotEffect {
+
+ public CallousOppressorChooseCreatureTypeEffect() {
+ super(Outcome.Benefit);
+ staticText = "an opponent chooses a creature type";
+ }
+
+ public CallousOppressorChooseCreatureTypeEffect(final CallousOppressorChooseCreatureTypeEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ MageObject mageObject = game.getPermanentEntering(source.getSourceId());
+ if (mageObject == null) {
+ mageObject = game.getObject(source.getSourceId());
+ }
+ if (controller != null) {
+ TargetOpponent target = new TargetOpponent(true);
+ if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
+ while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) {
+ controller.chooseTarget(outcome, target, source, game);
+ }
+ } else {
+ return false;
+ }
+ Player opponent = game.getPlayer(target.getFirstTarget());
+ if (opponent != null && mageObject != null) {
+ Choice typeChoice = new ChoiceImpl(true);
+ typeChoice.setMessage("Choose creature type");
+ typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
+ while (!opponent.choose(outcome, typeChoice, game)) {
+ if (!opponent.canRespond()) {
+ return false;
+ }
+ }
+ if (typeChoice.getChoice() == null) {
+ return false;
+ }
+ if (!game.isSimulation()) {
+ game.informPlayers(mageObject.getName() + ": " + opponent.getLogName() + " has chosen " + typeChoice.getChoice());
+ }
+ game.getState().setValue(mageObject.getId() + "_type", SubType.byDescription(typeChoice.getChoice()));
+ if (mageObject instanceof Permanent) {
+ ((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public CallousOppressorChooseCreatureTypeEffect copy() {
+ return new CallousOppressorChooseCreatureTypeEffect(this);
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java b/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java
index 941df4792e3..14a92b7d164 100644
--- a/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java
+++ b/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java
@@ -27,6 +27,7 @@
*/
package mage.cards.c;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
@@ -39,8 +40,7 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPlayer;
-
-import java.util.UUID;
+import mage.util.CardUtil;
/**
*
@@ -112,8 +112,8 @@ class CurseOfBloodlettingEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/d/DeathCharmer.java b/Mage.Sets/src/mage/cards/d/DeathCharmer.java
new file mode 100644
index 00000000000..d8873abbae4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DeathCharmer.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.d;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.DealsCombatDamageToACreatureTriggeredAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.abilities.effects.common.LoseLifeTargetControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+/**
+ *
+ * @author L_J
+ */
+public class DeathCharmer extends CardImpl {
+
+ public DeathCharmer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
+ this.subtype.add(SubType.WORM);
+ this.subtype.add(SubType.MERCENARY);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever Death Charmer deals combat damage to a creature, that creature's controller loses 2 life unless he or she pays {2}.
+ this.addAbility(new DealsCombatDamageToACreatureTriggeredAbility(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new LoseLifeTargetControllerEffect(2), new ManaCostsImpl("{2}")), false, true));
+ }
+
+ public DeathCharmer(final DeathCharmer card) {
+ super(card);
+ }
+
+ @Override
+ public DeathCharmer copy() {
+ return new DeathCharmer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/d/DesperateGambit.java b/Mage.Sets/src/mage/cards/d/DesperateGambit.java
index 1272b4c7291..3dde02e293d 100644
--- a/Mage.Sets/src/mage/cards/d/DesperateGambit.java
+++ b/Mage.Sets/src/mage/cards/d/DesperateGambit.java
@@ -49,6 +49,7 @@ import mage.filter.FilterObject;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.players.Player;
import mage.target.TargetSource;
+import mage.util.CardUtil;
/**
*
@@ -129,7 +130,7 @@ class DesperateGambitEffect extends PreventionEffectImpl {
if (controller != null && object != null) {
if (super.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {
if (wonFlip) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
this.discard();
} else {
preventDamageAction(event, source, game);
diff --git a/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java b/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java
index 8e4814dbcd9..8b57e8b53a2 100644
--- a/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java
+++ b/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java
@@ -44,6 +44,7 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
+import mage.util.CardUtil;
/**
*
@@ -115,13 +116,13 @@ class DictateOfTheTwinGodsEffect extends ReplacementEffectImpl {
if (damageEvent.getType() == EventType.DAMAGE_PLAYER) {
Player targetPlayer = game.getPlayer(event.getTargetId());
if (targetPlayer != null) {
- targetPlayer.damage(damageEvent.getAmount() * 2, damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
+ targetPlayer.damage(CardUtil.addWithOverflowCheck(damageEvent.getAmount(), damageEvent.getAmount()), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
return true;
}
} else {
Permanent targetPermanent = game.getPermanent(event.getTargetId());
if (targetPermanent != null) {
- targetPermanent.damage(damageEvent.getAmount() * 2, damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
+ targetPermanent.damage(CardUtil.addWithOverflowCheck(damageEvent.getAmount(), damageEvent.getAmount()), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/d/DoomCannon.java b/Mage.Sets/src/mage/cards/d/DoomCannon.java
new file mode 100644
index 00000000000..383bf31b35b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DoomCannon.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.d;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.AsEntersBattlefieldAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.ChooseCreatureTypeEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.common.TargetCreatureOrPlayer;
+
+/**
+ *
+ * @author L_J
+ */
+public class DoomCannon extends CardImpl {
+
+ public DoomCannon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{6}");
+
+ // As Doom Cannon enters the battlefield, choose a creature type.
+ this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Sacrifice)));
+
+ // {3}, {T}, Sacrifice a creature of the chosen type: Doom Cannon deals 3 damage to target creature or player.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new GenericManaCost(3));
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(new DoomCannonFilter())));
+ ability.addTarget(new TargetCreatureOrPlayer());
+ this.addAbility(ability);
+ }
+
+ public DoomCannon(final DoomCannon card) {
+ super(card);
+ }
+
+ @Override
+ public DoomCannon copy() {
+ return new DoomCannon(this);
+ }
+}
+
+class DoomCannonFilter extends FilterControlledCreaturePermanent {
+
+ public DoomCannonFilter() {
+ super("a creature of the chosen type");
+ }
+
+ public DoomCannonFilter(final DoomCannonFilter filter) {
+ super(filter);
+ }
+
+ @Override
+ public DoomCannonFilter copy() {
+ return new DoomCannonFilter(this);
+ }
+
+ @Override
+ public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
+ if (super.match(permanent, sourceId, playerId, game)) {
+ SubType subtype = (SubType) game.getState().getValue(sourceId + "_type");
+ if (subtype != null && permanent.hasSubtype(subtype, game)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/d/Dracoplasm.java b/Mage.Sets/src/mage/cards/d/Dracoplasm.java
index e378fc79986..1ccf4cfbe01 100644
--- a/Mage.Sets/src/mage/cards/d/Dracoplasm.java
+++ b/Mage.Sets/src/mage/cards/d/Dracoplasm.java
@@ -50,6 +50,7 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetControlledPermanent;
+import mage.util.CardUtil;
/**
*
@@ -131,8 +132,8 @@ class DracoplasmEffect extends ReplacementEffectImpl {
for (UUID targetId : target.getTargets()) {
Permanent targetCreature = game.getPermanent(targetId);
if (targetCreature != null && targetCreature.sacrifice(source.getSourceId(), game)) {
- power += targetCreature.getPower().getValue();
- toughness += targetCreature.getToughness().getValue();
+ power = CardUtil.addWithOverflowCheck(power, targetCreature.getPower().getValue());
+ toughness = CardUtil.addWithOverflowCheck(toughness, targetCreature.getToughness().getValue());
}
}
ContinuousEffect effect = new SetPowerToughnessSourceEffect(power, toughness, Duration.Custom, SubLayer.SetPT_7b);
@@ -141,4 +142,4 @@ class DracoplasmEffect extends ReplacementEffectImpl {
}
return false;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/e/EmbermawHellion.java b/Mage.Sets/src/mage/cards/e/EmbermawHellion.java
index 641091b6fc6..9a7957cf5f3 100644
--- a/Mage.Sets/src/mage/cards/e/EmbermawHellion.java
+++ b/Mage.Sets/src/mage/cards/e/EmbermawHellion.java
@@ -44,6 +44,7 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
+import mage.util.CardUtil;
/**
*
@@ -120,7 +121,7 @@ class EmbermawHellionEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() + 1);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), 1));
return false;
}
diff --git a/Mage.Sets/src/mage/cards/e/EntrailsFeaster.java b/Mage.Sets/src/mage/cards/e/EntrailsFeaster.java
new file mode 100644
index 00000000000..a446dd82ad2
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EntrailsFeaster.java
@@ -0,0 +1,124 @@
+/*
+ * 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.e;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.filter.common.FilterCreatureCard;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetCardInGraveyard;
+
+/**
+ *
+ * @author L_J
+ */
+public class EntrailsFeaster extends CardImpl {
+
+ public EntrailsFeaster(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}");
+ this.subtype.add(SubType.ZOMBIE);
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // At the beginning of your upkeep, you may exile a creature card from a graveyard. If you do, put a +1/+1 counter on Entrails Feaster. If you don't, tap Entrails Feaster.
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new EntrailsFeasterEffect(), TargetController.YOU, false);
+ this.addAbility(ability);
+
+ }
+
+ public EntrailsFeaster(final EntrailsFeaster card) {
+ super(card);
+ }
+
+ @Override
+ public EntrailsFeaster copy() {
+ return new EntrailsFeaster(this);
+ }
+}
+
+class EntrailsFeasterEffect extends OneShotEffect {
+
+ private static final FilterCreatureCard filter = new FilterCreatureCard("creature card from a graveyard");
+
+ public EntrailsFeasterEffect() {
+ super(Outcome.Detriment);
+ this.staticText = "you may exile a creature card from a graveyard. If you do, put a +1/+1 counter on {this}. If you don't, tap {this}";
+ }
+
+ public EntrailsFeasterEffect(final EntrailsFeasterEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public EntrailsFeasterEffect copy() {
+ return new EntrailsFeasterEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null && source.getSourceId() != null) {
+ Permanent sourceObject = (Permanent) source.getSourceObjectIfItStillExists(game);
+ TargetCardInGraveyard target = new TargetCardInGraveyard(filter);
+ target.setNotTarget(true);
+ if (target.canChoose(source.getSourceId(), controller.getId(), game) && controller.chooseUse(outcome, "Exile a creature card from a graveyard?", source, game)) {
+ if (controller.choose(Outcome.Exile, target, source.getId(), game)) {
+ Card cardChosen = game.getCard(target.getFirstTarget());
+ if (cardChosen != null) {
+ controller.moveCardsToExile(cardChosen, source, game, true, null, "");
+ if (sourceObject != null) {
+ sourceObject.getCounters(game).addCounter(CounterType.P1P1.createInstance());
+ game.informPlayers(controller.getLogName() + " puts a +1/+1 counter on " + sourceObject.getLogName());
+ }
+ }
+ } else if (sourceObject != null) {
+ sourceObject.tap(game);
+ }
+ } else if (sourceObject != null) {
+ sourceObject.tap(game);
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/Excise.java b/Mage.Sets/src/mage/cards/e/Excise.java
new file mode 100644
index 00000000000..e9220d5bb67
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/Excise.java
@@ -0,0 +1,68 @@
+/*
+ * 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.e;
+
+import java.util.UUID;
+import mage.abilities.dynamicvalue.common.ManacostVariableValue;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.AttackingPredicate;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class Excise extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("attacking creature");
+ static {
+ filter.add(new AttackingPredicate());
+ }
+
+ public Excise(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{W}");
+
+ // Excise target nonwhite attacking creature unless its controller pays {X}.
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
+ this.getSpellAbility().addEffect(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new ExileTargetEffect(), new ManacostVariableValue()));
+ }
+
+ public Excise(final Excise card) {
+ super(card);
+ }
+
+ @Override
+ public Excise copy() {
+ return new Excise(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FarrelsMantle.java b/Mage.Sets/src/mage/cards/f/FarrelsMantle.java
index 380f184ab96..e24f2981817 100644
--- a/Mage.Sets/src/mage/cards/f/FarrelsMantle.java
+++ b/Mage.Sets/src/mage/cards/f/FarrelsMantle.java
@@ -48,6 +48,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import mage.util.CardUtil;
/**
*
@@ -126,7 +127,8 @@ class FarrelsMantleEffect extends OneShotEffect{
@Override
public boolean apply(Game game, Ability source) {
Permanent perm = game.getPermanent(source.getSourceId());
- DamageTargetEffect dmgEffect = new DamageTargetEffect(2+perm.getPower().getValue());
+ int damage = CardUtil.addWithOverflowCheck(perm.getPower().getValue(), 2);
+ DamageTargetEffect dmgEffect = new DamageTargetEffect(damage);
return dmgEffect.apply(game, source);
}
}
diff --git a/Mage.Sets/src/mage/cards/f/FireServant.java b/Mage.Sets/src/mage/cards/f/FireServant.java
index e0eadfc9574..2349f1b97b0 100644
--- a/Mage.Sets/src/mage/cards/f/FireServant.java
+++ b/Mage.Sets/src/mage/cards/f/FireServant.java
@@ -43,6 +43,7 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.StackObject;
+import mage.util.CardUtil;
/**
*
@@ -111,7 +112,7 @@ class FireServantEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
diff --git a/Mage.Sets/src/mage/cards/f/Flay.java b/Mage.Sets/src/mage/cards/f/Flay.java
new file mode 100644
index 00000000000..e9cc5561a0a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/Flay.java
@@ -0,0 +1,65 @@
+/*
+ * 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.f;
+
+import java.util.UUID;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.abilities.effects.common.discard.DiscardTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.TargetPlayer;
+
+/**
+ *
+ * @author L_J
+ */
+public class Flay extends CardImpl {
+
+ public Flay(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}");
+
+ // Target player discards a card at random. Then that player discards another card at random unless he or she pays {1}.
+ this.getSpellAbility().addEffect(new DiscardTargetEffect(1, true));
+ Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new DiscardTargetEffect(1, true), new ManaCostsImpl("{1}"));
+ effect.setText("Then that player discards another card at random unless he or she pays {1}");
+ this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addTarget(new TargetPlayer());
+ }
+
+ public Flay(final Flay card) {
+ super(card);
+ }
+
+ @Override
+ public Flay copy() {
+ return new Flay(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FlintGolem.java b/Mage.Sets/src/mage/cards/f/FlintGolem.java
new file mode 100644
index 00000000000..ed99556a940
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FlintGolem.java
@@ -0,0 +1,99 @@
+/*
+ * 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.f;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author fireshoes & L_J
+ */
+public class FlintGolem extends CardImpl {
+
+ public FlintGolem(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}");
+ this.subtype.add(SubType.GOLEM);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Whenever Flint Golem becomes blocked, defending player puts the top three cards of his or her library into his or her graveyard.
+ this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(new FlintGolemEffect(), false));
+ }
+
+ public FlintGolem(final FlintGolem card) {
+ super(card);
+ }
+
+ @Override
+ public FlintGolem copy() {
+ return new FlintGolem(this);
+ }
+}
+
+class FlintGolemEffect extends OneShotEffect {
+
+ public FlintGolemEffect() {
+ super(Outcome.Detriment);
+ this.staticText = "defending player puts the top three cards of his or her library into his or her graveyard";
+ }
+
+ public FlintGolemEffect(final FlintGolemEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FlintGolemEffect copy() {
+ return new FlintGolemEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent blockingCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (blockingCreature != null) {
+ Player opponent = game.getPlayer(blockingCreature.getControllerId());
+ if (opponent != null) {
+ opponent.moveCards(opponent.getLibrary().getTopCards(game, 3), Zone.GRAVEYARD, source, game);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FogPatch.java b/Mage.Sets/src/mage/cards/f/FogPatch.java
new file mode 100644
index 00000000000..9baada1501f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FogPatch.java
@@ -0,0 +1,103 @@
+/*
+ * 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.f;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.PhaseStep;
+import mage.game.Game;
+import mage.game.combat.CombatGroup;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author L_J
+ */
+public class FogPatch extends CardImpl {
+
+ public FogPatch(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}");
+
+ // Cast Fog Patch only during the declare blockers step.
+ this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, PhaseStep.DECLARE_BLOCKERS, null, "Cast {this} only during the declare blockers step"));
+
+ // Attacking creatures become blocked.
+ this.getSpellAbility().addEffect(new FogPatchEffect());
+ }
+
+ public FogPatch(final FogPatch card) {
+ super(card);
+ }
+
+ @Override
+ public FogPatch copy() {
+ return new FogPatch(this);
+ }
+}
+
+class FogPatchEffect extends OneShotEffect {
+
+ public FogPatchEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "Attacking creatures become blocked";
+ }
+
+ public FogPatchEffect(final FogPatchEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FogPatchEffect copy() {
+ return new FogPatchEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null) {
+ for (UUID attackers : game.getCombat().getAttackers()) {
+ Permanent attacker = game.getPermanent(attackers);
+ if (attacker != null) {
+ CombatGroup combatGroup = game.getCombat().findGroup(attacker.getId());
+ if (combatGroup != null) {
+ combatGroup.setBlocked(true);
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java b/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java
index 5bc4655be51..9b8d485b31b 100644
--- a/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java
+++ b/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java
@@ -39,6 +39,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.util.CardUtil;
/**
*
@@ -99,7 +100,7 @@ class FurnaceOfRathEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(2 * event.getAmount());
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java
index 7556ea36dea..812edd6216d 100644
--- a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java
+++ b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java
@@ -41,6 +41,7 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
+import mage.util.CardUtil;
/**
* @author noxx
@@ -124,7 +125,7 @@ class GiselaBladeOfGoldnightDoubleDamageEffect extends ReplacementEffectImpl {
if (event.getTargetId().equals(source.getControllerId())) {
preventDamage(event, source, source.getControllerId(), game);
} else if (game.getOpponents(source.getControllerId()).contains(event.getTargetId())) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
}
break;
case DAMAGE_CREATURE:
@@ -134,7 +135,7 @@ class GiselaBladeOfGoldnightDoubleDamageEffect extends ReplacementEffectImpl {
if (permanent.getControllerId().equals(source.getControllerId())) {
preventDamage(event, source, permanent.getId(), game);
} else if (game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
}
}
}
diff --git a/Mage.Sets/src/mage/cards/g/GlitteringLion.java b/Mage.Sets/src/mage/cards/g/GlitteringLion.java
new file mode 100644
index 00000000000..4ecf4f220e7
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GlitteringLion.java
@@ -0,0 +1,102 @@
+/*
+ * 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.g;
+
+import java.io.ObjectStreamException;
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.MageSingleton;
+import mage.abilities.StaticAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
+import mage.abilities.effects.common.continuous.LoseAbilitySourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+
+/**
+ *
+ * @author L_J
+ */
+public class GlitteringLion extends CardImpl {
+
+ public GlitteringLion(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Prevent all damage that would be dealt to Glittering Lion.
+ this.addAbility(GlitteringLionAbility.getInstance());
+ // {3}: Until end of turn, Glittering Lion loses "Prevent all damage that would be dealt to Glittering Lion." Any player may activate this ability.
+ SimpleActivatedAbility ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseAbilitySourceEffect(GlitteringLionAbility.getInstance(), Duration.EndOfTurn).setText("Until end of turn, {this} loses \"Prevent all damage that would be dealt to {this}.\""), new ManaCostsImpl("{3}"));
+ ability2.setMayActivate(TargetController.ANY);
+ ability2.addEffect(new InfoEffect("Any player may activate this ability"));
+ this.addAbility(ability2);
+ }
+
+ public GlitteringLion(final GlitteringLion card) {
+ super(card);
+ }
+
+ @Override
+ public GlitteringLion copy() {
+ return new GlitteringLion(this);
+ }
+
+}
+
+class GlitteringLionAbility extends StaticAbility {
+
+ private static final GlitteringLionAbility instance = new GlitteringLionAbility();
+
+ private Object readResolve() throws ObjectStreamException {
+ return instance;
+ }
+
+ public static GlitteringLionAbility getInstance() {
+ return instance;
+ }
+
+ public GlitteringLionAbility() {
+ super(Zone.BATTLEFIELD, new PreventAllDamageToSourceEffect(Duration.WhileOnBattlefield));
+ }
+
+ @Override
+ public GlitteringLionAbility copy() {
+ return instance;
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/g/GlitteringLynx.java b/Mage.Sets/src/mage/cards/g/GlitteringLynx.java
new file mode 100644
index 00000000000..3c2269fb482
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GlitteringLynx.java
@@ -0,0 +1,102 @@
+/*
+ * 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.g;
+
+import java.io.ObjectStreamException;
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.MageSingleton;
+import mage.abilities.StaticAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
+import mage.abilities.effects.common.continuous.LoseAbilitySourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+
+/**
+ *
+ * @author L_J
+ */
+public class GlitteringLynx extends CardImpl {
+
+ public GlitteringLynx(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}");
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Prevent all damage that would be dealt to Glittering Lynx.
+ this.addAbility(GlitteringLynxAbility.getInstance());
+ // {2}: Until end of turn, Glittering Lynx loses "Prevent all damage that would be dealt to Glittering Lynx." Any player may activate this ability.
+ SimpleActivatedAbility ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseAbilitySourceEffect(GlitteringLynxAbility.getInstance(), Duration.EndOfTurn).setText("Until end of turn, {this} loses \"Prevent all damage that would be dealt to {this}.\""), new ManaCostsImpl("{2}"));
+ ability2.setMayActivate(TargetController.ANY);
+ ability2.addEffect(new InfoEffect("Any player may activate this ability"));
+ this.addAbility(ability2);
+ }
+
+ public GlitteringLynx(final GlitteringLynx card) {
+ super(card);
+ }
+
+ @Override
+ public GlitteringLynx copy() {
+ return new GlitteringLynx(this);
+ }
+
+}
+
+class GlitteringLynxAbility extends StaticAbility {
+
+ private static final GlitteringLynxAbility instance = new GlitteringLynxAbility();
+
+ private Object readResolve() throws ObjectStreamException {
+ return instance;
+ }
+
+ public static GlitteringLynxAbility getInstance() {
+ return instance;
+ }
+
+ public GlitteringLynxAbility() {
+ super(Zone.BATTLEFIELD, new PreventAllDamageToSourceEffect(Duration.WhileOnBattlefield));
+ }
+
+ @Override
+ public GlitteringLynxAbility copy() {
+ return instance;
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/g/GlyphOfLife.java b/Mage.Sets/src/mage/cards/g/GlyphOfLife.java
new file mode 100644
index 00000000000..69abf3dc790
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GlyphOfLife.java
@@ -0,0 +1,148 @@
+/*
+ * 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.g;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.InfoEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.DamagedCreatureEvent;
+import mage.game.events.GameEvent.EventType;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author fireshoes & L_J
+ */
+public class GlyphOfLife extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Wall creature");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.WALL));
+ }
+
+ public GlyphOfLife(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}");
+
+ // Choose target Wall creature. Whenever that creature is dealt damage by an attacking creature this turn, you gain that much life.
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
+ this.getSpellAbility().addEffect(new InfoEffect("Choose target Wall creature"));
+ this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new GlyphOfLifeTriggeredAbility()));
+ }
+
+ public GlyphOfLife(final GlyphOfLife card) {
+ super(card);
+ }
+
+ @Override
+ public GlyphOfLife copy() {
+ return new GlyphOfLife(this);
+ }
+}
+
+class GlyphOfLifeTriggeredAbility extends DelayedTriggeredAbility {
+
+ public GlyphOfLifeTriggeredAbility() {
+ super(new GlyphOfLifeGainLifeEffect(), Duration.EndOfTurn, false);
+ }
+
+ public GlyphOfLifeTriggeredAbility(final GlyphOfLifeTriggeredAbility effect) {
+ super(effect);
+ }
+
+ @Override
+ public GlyphOfLifeTriggeredAbility copy() {
+ return new GlyphOfLifeTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == EventType.DAMAGED_CREATURE;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getTargetId().equals(this.getFirstTarget())) {
+ DamagedCreatureEvent damageEvent = (DamagedCreatureEvent) event;
+ Permanent attackingCreature = game.getPermanentOrLKIBattlefield(damageEvent.getSourceId());
+ if (attackingCreature != null && attackingCreature.isCreature() && attackingCreature.isAttacking()) {
+ this.getEffects().get(0).setValue("damageAmount", event.getAmount());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever that creature is dealt damage by an attacking creature this turn, " + super.getRule();
+ }
+}
+
+class GlyphOfLifeGainLifeEffect extends OneShotEffect {
+
+ public GlyphOfLifeGainLifeEffect() {
+ super(Outcome.GainLife);
+ staticText = "you gain that much life";
+ }
+
+ public GlyphOfLifeGainLifeEffect(final GlyphOfLifeGainLifeEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public GlyphOfLifeGainLifeEffect copy() {
+ return new GlyphOfLifeGainLifeEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player != null) {
+ player.gainLife((Integer) this.getValue("damageAmount"), game);
+ }
+ return true;
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java b/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java
index 9411b61bbfd..5f173392257 100644
--- a/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java
+++ b/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java
@@ -45,6 +45,7 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
+import mage.util.CardUtil;
/**
*
@@ -118,14 +119,14 @@ class GoldnightCastigatorDoubleDamageEffect extends ReplacementEffectImpl {
switch (event.getType()) {
case DAMAGE_PLAYER:
if (event.getTargetId().equals(source.getControllerId())) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
}
break;
case DAMAGE_CREATURE:
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
if (permanent.getId().equals(source.getSourceId())) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
}
}
}
diff --git a/Mage.Sets/src/mage/cards/g/GratuitousViolence.java b/Mage.Sets/src/mage/cards/g/GratuitousViolence.java
index 2465d48dde0..dea9322ecda 100644
--- a/Mage.Sets/src/mage/cards/g/GratuitousViolence.java
+++ b/Mage.Sets/src/mage/cards/g/GratuitousViolence.java
@@ -40,6 +40,7 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
+import mage.util.CardUtil;
/**
*
@@ -106,7 +107,7 @@ class GratuitousViolenceReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(2 * event.getAmount());
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/h/HarvestMage.java b/Mage.Sets/src/mage/cards/h/HarvestMage.java
new file mode 100644
index 00000000000..8c0aee8aaf6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HarvestMage.java
@@ -0,0 +1,132 @@
+/*
+ * 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.h;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.MageObject;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.DiscardTargetCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.effects.common.AddManaOfAnyColorEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.GameEvent.EventType;
+import mage.game.events.ManaEvent;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCardInHand;
+
+/**
+ *
+ * @author L_J
+ */
+public class HarvestMage extends CardImpl {
+
+ public HarvestMage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SPELLSHAPER);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // {G}, {T}, Discard a card: Until end of turn, if you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount.
+ SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HarvestMageReplacementEffect(), new ManaCostsImpl("{G}"));
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new DiscardTargetCost(new TargetCardInHand()));
+ this.addAbility(ability);
+ }
+
+ public HarvestMage(final HarvestMage card) {
+ super(card);
+ }
+
+ @Override
+ public HarvestMage copy() {
+ return new HarvestMage(this);
+ }
+}
+
+class HarvestMageReplacementEffect extends ReplacementEffectImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent();
+
+ HarvestMageReplacementEffect() {
+ super(Duration.EndOfTurn, Outcome.Neutral);
+ staticText = "Until end of turn, if you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount";
+ }
+
+ HarvestMageReplacementEffect(final HarvestMageReplacementEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public HarvestMageReplacementEffect copy() {
+ return new HarvestMageReplacementEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ ManaEvent manaEvent = (ManaEvent) event;
+ Mana mana = manaEvent.getMana();
+ new AddManaOfAnyColorEffect().apply(game,source);
+ mana.setToMana(new Mana(0,0,0,0,0,0,0,0));
+ return true;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == EventType.TAPPED_FOR_MANA;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ MageObject mageObject = game.getObject(event.getSourceId());
+ if (mageObject != null && mageObject.isLand()) {
+ Permanent land = game.getPermanent(event.getSourceId());
+ return land != null && filter.match(land, game);
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HollowWarrior.java b/Mage.Sets/src/mage/cards/h/HollowWarrior.java
new file mode 100644
index 00000000000..fc39cb4e1be
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HollowWarrior.java
@@ -0,0 +1,109 @@
+/*
+ * 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.h;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapTargetCost;
+import mage.abilities.effects.PayCostToAttackBlockEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.AttackingPredicate;
+import mage.filter.predicate.permanent.BlockingPredicate;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.target.common.TargetControlledPermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class HollowWarrior extends CardImpl {
+
+ public HollowWarrior(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}");
+ this.subtype.add(SubType.GOLEM);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Hollow Warrior can't attack or block unless you tap an untapped creature you control not declared as an attacking or blocking creature this combat. (This cost is paid as attackers are declared.)
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HollowWarriorCostToAttackBlockEffect()));
+
+ }
+
+ public HollowWarrior(final HollowWarrior card) {
+ super(card);
+ }
+
+ @Override
+ public HollowWarrior copy() {
+ return new HollowWarrior(this);
+ }
+}
+
+class HollowWarriorCostToAttackBlockEffect extends PayCostToAttackBlockEffectImpl {
+
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("an untapped creature you control not declared as an attacking or blocking creature");
+ static {
+ filter.add(Predicates.not(new AttackingPredicate()));
+ filter.add(Predicates.not(new BlockingPredicate()));
+ filter.add(Predicates.not(new TappedPredicate()));
+ }
+
+ HollowWarriorCostToAttackBlockEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK_AND_BLOCK,
+ new TapTargetCost(new TargetControlledPermanent(filter)));
+ staticText = "{this} can't attack or block unless you tap an untapped creature you control not declared as an attacking or blocking creature this combat (This cost is paid as attackers are declared.)";
+ }
+
+ HollowWarriorCostToAttackBlockEffect(HollowWarriorCostToAttackBlockEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ return source.getSourceId().equals(event.getSourceId());
+ }
+
+ @Override
+ public HollowWarriorCostToAttackBlockEffect copy() {
+ return new HollowWarriorCostToAttackBlockEffect(this);
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java b/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java
index dd8af49bc75..d94fce17a22 100644
--- a/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java
+++ b/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java
@@ -46,6 +46,7 @@ import mage.game.permanent.Permanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.players.Player;
+import mage.util.CardUtil;
/**
*
@@ -121,7 +122,7 @@ class ImpulsiveManeuversEffect extends PreventionEffectImpl {
DamageEvent damageEvent = (DamageEvent) event;
if (damageEvent.isCombatDamage()) {
if (wonFlip) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
this.discard();
} else {
preventDamageAction(event, source, game);
diff --git a/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java b/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java
index fe38f01aba4..9b9d3189d19 100644
--- a/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java
+++ b/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java
@@ -45,6 +45,7 @@ import mage.game.events.DamageCreatureEvent;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
+import mage.util.CardUtil;
/**
* @author nantuko
@@ -126,7 +127,7 @@ class InquisitorsFlailEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
diff --git a/Mage.Sets/src/mage/cards/i/InsultInjury.java b/Mage.Sets/src/mage/cards/i/InsultInjury.java
index b4c272be79c..7ecd9561c18 100644
--- a/Mage.Sets/src/mage/cards/i/InsultInjury.java
+++ b/Mage.Sets/src/mage/cards/i/InsultInjury.java
@@ -19,6 +19,7 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
+import mage.util.CardUtil;
/**
* @author Stravant
@@ -88,7 +89,7 @@ class InsultDoubleDamageEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/k/KamahlsSummons.java b/Mage.Sets/src/mage/cards/k/KamahlsSummons.java
new file mode 100644
index 00000000000..a259d5289a3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KamahlsSummons.java
@@ -0,0 +1,121 @@
+/*
+ * 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.k;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.FilterCard;
+import mage.filter.common.FilterCreatureCard;
+import mage.game.Game;
+import mage.game.permanent.token.BearToken;
+import mage.game.permanent.token.Token;
+import mage.players.Player;
+import mage.target.common.TargetCardInHand;
+
+/**
+ *
+ * @author L_J
+ */
+public class KamahlsSummons extends CardImpl {
+
+ public KamahlsSummons(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}");
+
+ // Each player may reveal any number of creature cards from his or her hand. Then each player creates a 2/2 green Bear creature token for each card he or she revealed this way.
+ getSpellAbility().addEffect(new KamahlsSummonsEffect());
+ }
+
+ public KamahlsSummons(final KamahlsSummons card) {
+ super(card);
+ }
+
+ @Override
+ public KamahlsSummons copy() {
+ return new KamahlsSummons(this);
+ }
+}
+
+class KamahlsSummonsEffect extends OneShotEffect {
+
+ private static final FilterCard filter = new FilterCreatureCard();
+
+ public KamahlsSummonsEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "Each player may reveal any number of creature cards from his or her hand. Then each player creates a 2/2 green Bear creature token for each card he or she revealed this way";
+ }
+
+ public KamahlsSummonsEffect(final KamahlsSummonsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public KamahlsSummonsEffect copy() {
+ return new KamahlsSummonsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ MageObject sourceObject = game.getObject(source.getSourceId());
+ if (controller != null && sourceObject != null) {
+ Map revealedCards = new HashMap<>();
+ for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null) {
+ if (player.getHand().count(filter, game) > 0) {
+ TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
+ if (player.choose(outcome, target, source.getSourceId(), game)) {
+ Cards cards = new CardsImpl(target.getTargets());
+ controller.revealCards(sourceObject.getIdName(), cards, game);
+ revealedCards.put(playerId, target.getTargets().size());
+ }
+ }
+ }
+ }
+ Token token = new BearToken();
+ for (UUID playerId : revealedCards.keySet()) {
+ int value = revealedCards.get(playerId);
+ if (value > 0) {
+ token.putOntoBattlefield(value, game, source.getSourceId(), playerId);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KeldonBattlewagon.java b/Mage.Sets/src/mage/cards/k/KeldonBattlewagon.java
new file mode 100644
index 00000000000..e65943b01fc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KeldonBattlewagon.java
@@ -0,0 +1,169 @@
+ /*
+ * 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.k;
+
+import java.util.List;
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.CantBlockAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.CostImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.SacrificeSourceEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author jeffwadsworth & L_J
+ */
+public class KeldonBattlewagon extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("an untapped creature you control");
+ static {
+ filter.add(Predicates.not(new TappedPredicate()));
+ }
+
+ public KeldonBattlewagon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}");
+ this.subtype.add(SubType.JUGGERNAUT);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(3);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // Keldon Battlewagon can't block.
+ this.addAbility(new CantBlockAbility());
+
+ // When Keldon Battlewagon attacks, sacrifice it at end of combat.
+ this.addAbility(new AttacksTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new SacrificeSourceEffect())), false));
+
+ // Tap an untapped creature you control: Keldon Battlewagon gets +X/+0 until end of turn, where X is the power of the creature tapped this way.
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new KeldonBattlewagonBoostEffect(), new KeldonBattlewagonCost(new TargetControlledPermanent(filter))));
+
+ }
+
+ public KeldonBattlewagon(final KeldonBattlewagon card) {
+ super(card);
+ }
+
+ @Override
+ public KeldonBattlewagon copy() {
+ return new KeldonBattlewagon(this);
+ }
+}
+
+class KeldonBattlewagonCost extends CostImpl {
+
+ TargetControlledPermanent target;
+
+ public KeldonBattlewagonCost(TargetControlledPermanent target) {
+ this.target = target;
+ this.text = "Tap an untapped creature you control";
+ }
+
+ public KeldonBattlewagonCost(final KeldonBattlewagonCost cost) {
+ super(cost);
+ this.target = cost.target.copy();
+ }
+
+ @Override
+ public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
+ if (target.choose(Outcome.Tap, controllerId, sourceId, game)) {
+ for (UUID targetId: (List)target.getTargets()) {
+ Permanent permanent = game.getPermanent(targetId);
+ if (permanent == null)
+ return false;
+ paid |= permanent.tap(game);
+ for (Effect effect : ability.getEffects()) {
+ effect.setTargetPointer(new FixedTarget(permanent.getId()));
+ }
+ }
+ }
+ return paid;
+ }
+
+ @Override
+ public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
+ return target.canChoose(controllerId, game);
+ }
+
+ @Override
+ public KeldonBattlewagonCost copy() {
+ return new KeldonBattlewagonCost(this);
+ }
+}
+
+class KeldonBattlewagonBoostEffect extends OneShotEffect {
+
+ public KeldonBattlewagonBoostEffect() {
+ super(Outcome.BoostCreature);
+ staticText = "{this} gets +X/+0 until end of turn, where X is the power of the creature tapped this way";
+ }
+
+ public KeldonBattlewagonBoostEffect(KeldonBattlewagonBoostEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent KeldonBattlewagon = game.getPermanent(source.getSourceId());
+ Permanent tappedCreature = game.getPermanentOrLKIBattlefield(this.targetPointer.getFirst(game, source));
+ if (tappedCreature != null && KeldonBattlewagon != null) {
+ int amount = tappedCreature.getPower().getValue();
+ game.addEffect(new BoostSourceEffect(amount, 0, Duration.EndOfTurn), source);
+ }
+ return true;
+ }
+
+ @Override
+ public KeldonBattlewagonBoostEffect copy() {
+ return new KeldonBattlewagonBoostEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/ManaCache.java b/Mage.Sets/src/mage/cards/m/ManaCache.java
new file mode 100644
index 00000000000..e5976b259bf
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/ManaCache.java
@@ -0,0 +1,148 @@
+/*
+ * 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.m;
+
+import java.util.UUID;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbility;
+import mage.abilities.common.OnEventTriggeredAbility;
+import mage.abilities.costs.common.RemoveCountersSourceCost;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.BasicManaEffect;
+import mage.abilities.mana.ActivatedManaAbilityImpl;
+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.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledLandPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author L_J
+ */
+public class ManaCache extends CardImpl {
+
+ public ManaCache(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{R}");
+
+ // At the beginning of each player's end step, put a charge counter on Mana Cache for each untapped land that player controls.
+ TriggeredAbility ability = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of each player's end step", true, new ManaCacheEffect());
+ this.addAbility(ability);
+
+ // Remove a charge counter from Mana Cache: Add {C} to your mana pool. Any player may activate this ability but only during his or her turn before the end step.
+ this.addAbility(new ManaCacheManaAbility());
+ }
+
+ public ManaCache(final ManaCache card) {
+ super(card);
+ }
+
+ @Override
+ public ManaCache copy() {
+ return new ManaCache(this);
+ }
+}
+
+class ManaCacheEffect extends OneShotEffect {
+
+ private static final FilterPermanent filter = new FilterControlledLandPermanent();
+ static {
+ filter.add(Predicates.not(new TappedPredicate()));
+ }
+
+ public ManaCacheEffect() {
+ super(Outcome.Damage);
+ this.staticText = "put a charge counter on {this} for each untapped land that player controls";
+ }
+
+ @Override
+ public Effect copy() {
+ return new ManaCacheEffect();
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(game.getActivePlayerId());
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ if (player != null && sourcePermanent != null) {
+ int controlledUntappedLands = game.getBattlefield().countAll(filter, game.getActivePlayerId(), game);
+ sourcePermanent.addCounters(CounterType.CHARGE.createInstance(controlledUntappedLands), source, game);
+ return true;
+ }
+ return false;
+ }
+}
+
+class ManaCacheManaAbility extends ActivatedManaAbilityImpl {
+
+ public ManaCacheManaAbility() {
+ super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.ColorlessMana(1)), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(1)));
+ this.netMana.add(new Mana(0,0,0,0,0,0,0,1));
+ }
+
+ public ManaCacheManaAbility(final ManaCacheManaAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean canActivate(UUID playerId, Game game) {
+ if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) {
+ return false;
+ }
+ Player player = game.getPlayer(playerId);
+ if (player != null && playerId == game.getActivePlayerId() && game.getStep().getType().isBefore(PhaseStep.END_TURN)) {
+ if (costs.canPay(this, sourceId, playerId, game)) {
+ this.setControllerId(playerId);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public ManaCacheManaAbility copy() {
+ return new ManaCacheManaAbility(this);
+ }
+
+ @Override
+ public String getRule() {
+ return super.getRule() + " Any player may activate this ability but only during his or her turn before the end step.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MirrorStrike.java b/Mage.Sets/src/mage/cards/m/MirrorStrike.java
new file mode 100644
index 00000000000..5d9e5191041
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MirrorStrike.java
@@ -0,0 +1,131 @@
+/*
+ * 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.m;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.events.DamageEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.UnblockedPredicate;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class MirrorStrike extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("unblocked creature");
+
+ static {
+ filter.add(new UnblockedPredicate());
+ }
+
+ public MirrorStrike(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}");
+
+ // All combat damage that would be dealt to you this turn by target unblocked creature is dealt to its controller instead.
+ this.getSpellAbility().addEffect(new MirrorStrikeEffect());
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
+ }
+
+ public MirrorStrike(final MirrorStrike card) {
+ super(card);
+ }
+
+ @Override
+ public MirrorStrike copy() {
+ return new MirrorStrike(this);
+ }
+}
+
+class MirrorStrikeEffect extends ReplacementEffectImpl {
+
+ public MirrorStrikeEffect() {
+ super(Duration.EndOfTurn, Outcome.RedirectDamage);
+ staticText = "All combat damage that would be dealt to you this turn by target unblocked creature is dealt to its controller instead";
+ }
+
+ public MirrorStrikeEffect(final MirrorStrikeEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public MirrorStrikeEffect copy() {
+ return new MirrorStrikeEffect(this);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ Player controller = game.getPlayer(source.getControllerId());
+ DamageEvent damageEvent = (DamageEvent) event;
+ if (controller != null) {
+ Permanent targetPermanent = game.getPermanent(source.getFirstTarget());
+ if (targetPermanent != null) {
+ Player targetsController = game.getPlayer(targetPermanent.getControllerId());
+ if (targetsController != null) {
+ targetsController.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects());
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Player controller = game.getPlayer(source.getControllerId());
+ DamageEvent damageEvent = (DamageEvent) event;
+ Permanent targetPermanent = game.getPermanent(source.getFirstTarget());
+ if (controller != null && targetPermanent != null) {
+ return (damageEvent.isCombatDamage() && controller.getId() == damageEvent.getTargetId() && targetPermanent.getId() == damageEvent.getSourceId());
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MoggToady.java b/Mage.Sets/src/mage/cards/m/MoggToady.java
new file mode 100644
index 00000000000..be59454a951
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MoggToady.java
@@ -0,0 +1,150 @@
+/*
+ * 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.m;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.RestrictionEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author emerald000 & L_J
+ */
+public class MoggToady extends CardImpl {
+
+ public MoggToady(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}");
+ this.subtype.add(SubType.GOBLIN);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Mogg Toady can't attack unless you control more creatures than defending player.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MoggToadyCantAttackEffect()));
+
+ // Mogg Toady can't block unless you control more creatures than attacking player.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MoggToadyCantBlockEffect()));
+ }
+
+ public MoggToady(final MoggToady card) {
+ super(card);
+ }
+
+ @Override
+ public MoggToady copy() {
+ return new MoggToady(this);
+ }
+}
+
+class MoggToadyCantAttackEffect extends RestrictionEffect {
+
+ MoggToadyCantAttackEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "{this} can't attack unless you control more creatures than defending player";
+ }
+
+ MoggToadyCantAttackEffect(final MoggToadyCantAttackEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return permanent.getId().equals(source.getSourceId());
+ }
+
+ @Override
+ public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
+ UUID defendingPlayerId;
+ Player defender = game.getPlayer(defenderId);
+ if (defender == null) {
+ Permanent permanent = game.getPermanent(defenderId);
+ if (permanent != null) {
+ defendingPlayerId = permanent.getControllerId();
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ defendingPlayerId = defenderId;
+ }
+ if (defendingPlayerId != null) {
+ return game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), source.getControllerId(), game) > game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), defendingPlayerId, game);
+ }
+ else {
+ return true;
+ }
+ }
+
+ @Override
+ public MoggToadyCantAttackEffect copy() {
+ return new MoggToadyCantAttackEffect(this);
+ }
+}
+
+class MoggToadyCantBlockEffect extends RestrictionEffect {
+
+ MoggToadyCantBlockEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "{this} can't block unless you control more creatures than attacking player";
+ }
+
+ MoggToadyCantBlockEffect(final MoggToadyCantBlockEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public MoggToadyCantBlockEffect copy() {
+ return new MoggToadyCantBlockEffect(this);
+ }
+
+ @Override
+ public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
+ UUID attackingPlayerId = attacker.getControllerId();
+ if (attackingPlayerId != null) {
+ return game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), source.getControllerId(), game) > game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), attackingPlayerId, game);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return permanent.getId().equals(source.getSourceId());
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/Mossdog.java b/Mage.Sets/src/mage/cards/m/Mossdog.java
new file mode 100644
index 00000000000..728b242230e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/Mossdog.java
@@ -0,0 +1,103 @@
+/*
+ * 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.m;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.GameEvent.EventType;
+
+/**
+ *
+ * @author fireshoes & L_J
+ */
+public class Mossdog extends CardImpl {
+
+ public Mossdog(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
+ this.subtype.add(SubType.PLANT);
+ this.subtype.add(SubType.HOUND);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Whenever Mossdog becomes the target of a spell or ability an opponent controls, put a +1/+1 counter on Mossdog.
+ this.addAbility(new MossdogAbility());
+ }
+
+ public Mossdog(final Mossdog card) {
+ super(card);
+ }
+
+ @Override
+ public Mossdog copy() {
+ return new Mossdog(this);
+ }
+}
+
+class MossdogAbility extends TriggeredAbilityImpl {
+
+ public MossdogAbility() {
+ super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false);
+ }
+
+ public MossdogAbility(final MossdogAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public MossdogAbility copy() {
+ return new MossdogAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == EventType.TARGETED;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getTargetId().equals(this.getSourceId()) && game.getOpponents(this.controllerId).contains(event.getPlayerId())) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever {this} becomes the target of a spell or ability an opponent controls, put a +1/+1 counter on {this}.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/Overblaze.java b/Mage.Sets/src/mage/cards/o/Overblaze.java
index c1092570c8d..db7811c296c 100644
--- a/Mage.Sets/src/mage/cards/o/Overblaze.java
+++ b/Mage.Sets/src/mage/cards/o/Overblaze.java
@@ -27,6 +27,7 @@
*/
package mage.cards.o;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.keyword.SpliceOntoArcaneAbility;
@@ -39,8 +40,7 @@ import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.TargetPermanent;
-
-import java.util.UUID;
+import mage.util.CardUtil;
/**
*
@@ -104,8 +104,8 @@ class FireServantEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/p/PersonalIncarnation.java b/Mage.Sets/src/mage/cards/p/PersonalIncarnation.java
index 63ff9fa5de2..a9cdf4be71a 100644
--- a/Mage.Sets/src/mage/cards/p/PersonalIncarnation.java
+++ b/Mage.Sets/src/mage/cards/p/PersonalIncarnation.java
@@ -128,7 +128,7 @@ class PersonalIncarnationLoseHalfLifeEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(game.getOwnerId(source.getSourceId()));
if (player != null) {
- int amount = (player.getLife() + 1) / 2;
+ Integer amount = (int) Math.ceil(player.getLife() / 2f);
if (amount > 0) {
player.loseLife(amount, game, false);
return true;
diff --git a/Mage.Sets/src/mage/cards/p/Phthisis.java b/Mage.Sets/src/mage/cards/p/Phthisis.java
index 06f54043326..c60f351223d 100644
--- a/Mage.Sets/src/mage/cards/p/Phthisis.java
+++ b/Mage.Sets/src/mage/cards/p/Phthisis.java
@@ -40,6 +40,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
+import mage.util.CardUtil;
/**
*
@@ -91,7 +92,7 @@ class PhthisisEffect extends OneShotEffect {
if (creature != null) {
Player controller = game.getPlayer(creature.getControllerId());
if (controller != null) {
- int lifeLoss = creature.getPower().getValue() + creature.getToughness().getValue();
+ int lifeLoss = CardUtil.addWithOverflowCheck(creature.getPower().getValue(), creature.getToughness().getValue());
creature.destroy(source.getSourceId(), game, false);
// the life loss happens also if the creature is indestructible or regenerated (legal targets)
controller.loseLife(lifeLoss, game, false);
diff --git a/Mage.Sets/src/mage/cards/p/PredatorsRapport.java b/Mage.Sets/src/mage/cards/p/PredatorsRapport.java
index b2f8c3f5754..4374bbf5347 100644
--- a/Mage.Sets/src/mage/cards/p/PredatorsRapport.java
+++ b/Mage.Sets/src/mage/cards/p/PredatorsRapport.java
@@ -38,6 +38,7 @@ import mage.constants.CardType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
+import mage.util.CardUtil;
/**
*
@@ -72,7 +73,7 @@ class TargetPermanentPowerPlusToughnessCount implements DynamicValue {
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Permanent sourcePermanent = game.getPermanent(sourceAbility.getFirstTarget());
if (sourcePermanent != null) {
- return sourcePermanent.getPower().getValue() + sourcePermanent.getToughness().getValue();
+ return CardUtil.addWithOverflowCheck(sourcePermanent.getPower().getValue(), sourcePermanent.getToughness().getValue());
}
return 0;
}
diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java b/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java
index 1a2c6717ff2..1282b111719 100644
--- a/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java
+++ b/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java
@@ -42,6 +42,7 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
+import mage.util.CardUtil;
/**
*
@@ -103,7 +104,7 @@ class PyromancersGauntletReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() + 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), 2));
return false;
}
diff --git a/Mage.Sets/src/mage/cards/p/PyromancersSwath.java b/Mage.Sets/src/mage/cards/p/PyromancersSwath.java
index 84c83333cb7..933c587e750 100644
--- a/Mage.Sets/src/mage/cards/p/PyromancersSwath.java
+++ b/Mage.Sets/src/mage/cards/p/PyromancersSwath.java
@@ -39,6 +39,7 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.util.CardUtil;
/**
*
@@ -105,7 +106,7 @@ class PyromancersSwathReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() + 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), 2));
return false;
}
diff --git a/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java b/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java
index 4ac5e7ce402..de563d27acc 100644
--- a/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java
+++ b/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java
@@ -45,6 +45,7 @@ import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
+import mage.util.CardUtil;
/**
*
@@ -137,7 +138,7 @@ class QuestForPureFlameEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- event.setAmount(event.getAmount() * 2);
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/r/RhysticDeluge.java b/Mage.Sets/src/mage/cards/r/RhysticDeluge.java
new file mode 100644
index 00000000000..4434da3ec3b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RhysticDeluge.java
@@ -0,0 +1,66 @@
+/*
+ * 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.r;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.abilities.effects.common.TapTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Zone;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class RhysticDeluge extends CardImpl {
+
+ public RhysticDeluge(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
+
+ // {U}: Tap target creature unless its controller pays {1}.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new TapTargetEffect(), new ManaCostsImpl("{1}")), new ManaCostsImpl("{U}"));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ public RhysticDeluge(final RhysticDeluge card) {
+ super(card);
+ }
+
+ @Override
+ public RhysticDeluge copy() {
+ return new RhysticDeluge(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RhysticLightning.java b/Mage.Sets/src/mage/cards/r/RhysticLightning.java
new file mode 100644
index 00000000000..83d3f35dae1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RhysticLightning.java
@@ -0,0 +1,65 @@
+/*
+ * 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.r;
+
+import java.util.UUID;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetCreatureOrPlayer;
+
+/**
+ *
+ * @author L_J
+ */
+public class RhysticLightning extends CardImpl {
+
+ public RhysticLightning(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}");
+
+ // Rhystic Lightning deals 4 damage to target creature or player unless that creature's controller or that player pays {2}. If he or she does, Rhystic Lightning deals 2 damage to the creature or player.
+ Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new DamageTargetEffect(4), new DamageTargetEffect(2), new ManaCostsImpl("{2}"),
+ "Pay {2} to have {this} deal 2 damage instead of 4 damage?");
+ effect.setText("{this} deals 4 damage to target creature or player unless that creature's controller or that player pays {2}. If he or she does, {this} deals 2 damage to the creature or player");
+ this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
+ }
+
+ public RhysticLightning(final RhysticLightning card) {
+ super(card);
+ }
+
+ @Override
+ public RhysticLightning copy() {
+ return new RhysticLightning(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RhysticScrying.java b/Mage.Sets/src/mage/cards/r/RhysticScrying.java
new file mode 100644
index 00000000000..f558aa0e119
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RhysticScrying.java
@@ -0,0 +1,113 @@
+/*
+ * 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.r;
+
+import java.util.UUID;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.players.Player;
+
+/**
+ *
+ * @author L_J
+ */
+public class RhysticScrying extends CardImpl {
+
+ public RhysticScrying(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{U}");
+
+ // Draw three cards. Then, if any player pays {2}, discard three cards.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3));
+ this.getSpellAbility().addEffect(new RhysticScryingEffect());
+ }
+
+ public RhysticScrying(final RhysticScrying card) {
+ super(card);
+ }
+
+ @Override
+ public RhysticScrying copy() {
+ return new RhysticScrying(this);
+ }
+}
+
+class RhysticScryingEffect extends OneShotEffect {
+
+ public RhysticScryingEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "Then, if any player pays {2}, discard three cards";
+ }
+
+ public RhysticScryingEffect(final RhysticScryingEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ MageObject sourceObject = game.getObject(source.getSourceId());
+ if (controller != null && sourceObject != null) {
+ boolean result = true;
+ boolean doEffect = false;
+ Cost cost = new GenericManaCost(2);
+ // check if any player is willing to pay
+ for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, "Pay " + cost.getText() + " for " + sourceObject.getLogName() + "?", source, game)) {
+ cost.clearPaid();
+ if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
+ if (!game.isSimulation()) {
+ game.informPlayers(player.getLogName() + " pays the cost for " + sourceObject.getLogName());
+ }
+ doEffect = true;
+ }
+ }
+ }
+ // do the effects if anybody paid
+ if (doEffect) {
+ controller.discard(3, false, source, game);
+ }
+ return result;
+ }
+ return false;
+ }
+
+ @Override
+ public RhysticScryingEffect copy() {
+ return new RhysticScryingEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RhysticShield.java b/Mage.Sets/src/mage/cards/r/RhysticShield.java
new file mode 100644
index 00000000000..ad8e47187f9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RhysticShield.java
@@ -0,0 +1,65 @@
+/*
+ * 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.r;
+
+import java.util.UUID;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.filter.StaticFilters;
+
+/**
+ *
+ * @author L_J
+ */
+public class RhysticShield extends CardImpl {
+
+ public RhysticShield(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
+
+ // Creatures you control get +0/+1 until end of turn. They get an additional +0/+2 until end of turn unless any player pays {2}.
+ this.getSpellAbility().addEffect(new BoostControlledEffect(0, 1, Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE, false));
+ Effect effect = new DoUnlessAnyPlayerPaysEffect(new BoostControlledEffect(0, 2, Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE, false), new ManaCostsImpl("{2}"));
+ effect.setText("They get an additional +0/+2 until end of turn unless any player pays {2}");
+ this.getSpellAbility().addEffect(effect);
+ }
+
+ public RhysticShield(final RhysticShield card) {
+ super(card);
+ }
+
+ @Override
+ public RhysticShield copy() {
+ return new RhysticShield(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RhysticSyphon.java b/Mage.Sets/src/mage/cards/r/RhysticSyphon.java
new file mode 100644
index 00000000000..9435deb09fb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RhysticSyphon.java
@@ -0,0 +1,66 @@
+/*
+ * 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.r;
+
+import java.util.UUID;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.LoseLifeTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.TargetPlayer;
+
+/**
+ *
+ * @author L_J
+ */
+public class RhysticSyphon extends CardImpl {
+
+ public RhysticSyphon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}{B}");
+
+ // Unless target player pays {3}, he or she loses 5 life and you gain 5 life.
+ DoUnlessTargetPlayerOrTargetsControllerPaysEffect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new LoseLifeTargetEffect(5), new ManaCostsImpl("{3}"));
+ effect.addEffect(new GainLifeEffect(5));
+ effect.setText("Unless target player pays {3}, he or she loses 5 life and you gain 5 life");
+ this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addTarget(new TargetPlayer());
+ }
+
+ public RhysticSyphon(final RhysticSyphon card) {
+ super(card);
+ }
+
+ @Override
+ public RhysticSyphon copy() {
+ return new RhysticSyphon(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/Rupture.java b/Mage.Sets/src/mage/cards/r/Rupture.java
new file mode 100644
index 00000000000..d504b53365e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/Rupture.java
@@ -0,0 +1,116 @@
+/*
+ * 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.r;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DamageEverythingEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class Rupture extends CardImpl {
+
+ public Rupture(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}");
+
+ // Sacrifice a creature. Rupture deals damage equal to that creature's power to each creature without flying and each player.
+ this.getSpellAbility().addEffect(new RuptureEffect());
+ }
+
+ public Rupture(final Rupture card) {
+ super(card);
+ }
+
+ @Override
+ public Rupture copy() {
+ return new Rupture(this);
+ }
+}
+
+class RuptureEffect extends OneShotEffect {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature without flying");
+
+ static {
+ filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
+ }
+
+ public RuptureEffect() {
+ super(Outcome.Damage);
+ staticText = "Sacrifice a creature. Rupture deals damage equal to that creature's power to each creature without flying and each player";
+ }
+
+ public RuptureEffect(final RuptureEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player != null) {
+ int power = 0;
+ TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("creature to sacrifice"), true);
+ if (target.canChoose(source.getSourceId(), player.getId(), game)) {
+ while (!target.isChosen() && target.canChoose(player.getId(), game) && player.canRespond()) {
+ player.chooseTarget(Outcome.Sacrifice, target, source, game);
+ }
+ Permanent permanent = game.getPermanent(target.getFirstTarget());
+ if (permanent != null) {
+ power = permanent.getPower().getValue();
+ permanent.sacrifice(source.getSourceId(), game);
+ }
+ }
+ if (power > 0) {
+ new DamageEverythingEffect(power, filter).apply(game, source);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public RuptureEffect copy() {
+ return new RuptureEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/Seeker.java b/Mage.Sets/src/mage/cards/s/Seeker.java
new file mode 100644
index 00000000000..012a0ea0153
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/Seeker.java
@@ -0,0 +1,91 @@
+/*
+ * 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.s;
+
+import java.util.UUID;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleEvasionAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.AttachmentType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author LevelX2 & L_J
+ */
+public class Seeker extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("except by artifact creatures and/or white creatures");
+
+ static {
+ filter.add(Predicates.not(
+ Predicates.or(
+ Predicates.and(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE)),
+ Predicates.and(new CardTypePredicate(CardType.CREATURE), new ColorPredicate(ObjectColor.WHITE)
+ ))));
+ }
+
+ public Seeker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}");
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature can't be blocked except by artifact creatures and/or white creatures.
+ this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, filter, AttachmentType.AURA)));
+
+ }
+
+ public Seeker(final Seeker card) {
+ super(card);
+ }
+
+ @Override
+ public Seeker copy() {
+ return new Seeker(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/Sentinel.java b/Mage.Sets/src/mage/cards/s/Sentinel.java
index 1c67461fe41..c3c630145d5 100644
--- a/Mage.Sets/src/mage/cards/s/Sentinel.java
+++ b/Mage.Sets/src/mage/cards/s/Sentinel.java
@@ -51,6 +51,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
+import mage.util.CardUtil;
/**
*
@@ -105,7 +106,7 @@ class SentinelEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent targetPermanent = game.getPermanentOrLKIBattlefield(targetPointer.getFirst(game, source));
if (controller != null && targetPermanent != null) {
- int newToughness = targetPermanent.getPower().getValue() + 1;
+ int newToughness = CardUtil.addWithOverflowCheck(targetPermanent.getPower().getValue(), 1);
game.addEffect(new SetToughnessSourceEffect(new StaticValue(newToughness), Duration.Custom, SubLayer.SetPT_7b), source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/s/ShieldmageElder.java b/Mage.Sets/src/mage/cards/s/ShieldmageElder.java
new file mode 100644
index 00000000000..63c56953458
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ShieldmageElder.java
@@ -0,0 +1,96 @@
+/*
+ * 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.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapTargetCost;
+import mage.abilities.effects.common.PreventDamageByTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.target.TargetSpell;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class ShieldmageElder extends CardImpl {
+
+ private static final FilterControlledPermanent filter1 = new FilterControlledPermanent("untapped Clerics you control");
+
+ static {
+ filter1.add(Predicates.not(new TappedPredicate()));
+ filter1.add(new SubtypePredicate(SubType.CLERIC));
+ }
+ private static final FilterControlledPermanent filter2 = new FilterControlledPermanent("untapped Wizards you control");
+
+ static {
+ filter2.add(Predicates.not(new TappedPredicate()));
+ filter2.add(new SubtypePredicate(SubType.WIZARD));
+ }
+
+ public ShieldmageElder(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.CLERIC);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Tap two untapped Clerics you control: Prevent all damage target creature would deal this turn.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageByTargetEffect(Duration.EndOfTurn), new TapTargetCost(new TargetControlledPermanent(2, 2, filter1, false)));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+
+ // Tap two untapped Wizards you control: Prevent all damage target spell would deal this turn.
+ Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageByTargetEffect(Duration.EndOfTurn), new TapTargetCost(new TargetControlledPermanent(2, 2, filter2, false)));
+ ability2.addTarget(new TargetSpell());
+ this.addAbility(ability2);
+ }
+
+ public ShieldmageElder(final ShieldmageElder card) {
+ super(card);
+ }
+
+ @Override
+ public ShieldmageElder copy() {
+ return new ShieldmageElder(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/ShroudedSerpent.java b/Mage.Sets/src/mage/cards/s/ShroudedSerpent.java
new file mode 100644
index 00000000000..7730f739d74
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ShroudedSerpent.java
@@ -0,0 +1,72 @@
+/*
+ * 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.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedByAllSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SetTargetPointer;
+import mage.constants.Duration;
+import mage.filter.common.FilterCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class ShroudedSerpent extends CardImpl {
+
+ public ShroudedSerpent(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}{U}{U}");
+ this.subtype.add(SubType.SERPENT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Whenever Shrouded Serpent attacks, defending player may pay {4}. If he or she doesn't, Shrouded Serpent can't be blocked this turn.
+ this.addAbility(new AttacksTriggeredAbility(
+ new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new CantBeBlockedByAllSourceEffect(new FilterCreaturePermanent(), Duration.EndOfCombat), new ManaCostsImpl("{4}")),
+ false,
+ "Whenever {this} attacks, defending player may pay {4}. If he or she doesn't, {this} can't be blocked this turn.",
+ SetTargetPointer.PLAYER));
+ }
+
+ public ShroudedSerpent(final ShroudedSerpent card) {
+ super(card);
+ }
+
+ @Override
+ public ShroudedSerpent copy() {
+ return new ShroudedSerpent(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SivvisValor.java b/Mage.Sets/src/mage/cards/s/SivvisValor.java
new file mode 100644
index 00000000000..c63a2b21f14
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SivvisValor.java
@@ -0,0 +1,140 @@
+/*
+ * 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.s;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.AlternativeCostSourceAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.common.TapTargetCost;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.events.DamageEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class SivvisValor extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterPermanent("If you control a Plains");
+ private static final FilterControlledCreaturePermanent filterCreature = new FilterControlledCreaturePermanent("untapped creature you control");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.PLAINS));
+ filterCreature.add(Predicates.not(new TappedPredicate()));
+ }
+
+ public SivvisValor(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{W}");
+
+ // If you control a Plains, you may tap an untapped creature you control rather than pay Sivvi's Valor's mana cost.
+ Cost cost = new TapTargetCost(new TargetControlledPermanent(1,1,filterCreature,false));
+ cost.setText(" tap an untapped creature you control");
+ this.addAbility(new AlternativeCostSourceAbility(cost, new PermanentsOnTheBattlefieldCondition(filter)));
+
+ // All damage that would be dealt to target creature this turn is dealt to you instead.
+ this.getSpellAbility().addEffect(new SivvisValorEffect());
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ public SivvisValor(final SivvisValor card) {
+ super(card);
+ }
+
+ @Override
+ public SivvisValor copy() {
+ return new SivvisValor(this);
+ }
+}
+
+class SivvisValorEffect extends ReplacementEffectImpl {
+
+ public SivvisValorEffect() {
+ super(Duration.EndOfTurn, Outcome.RedirectDamage);
+ staticText = "All damage that would be dealt to target creature this turn is dealt to you instead";
+ }
+
+ public SivvisValorEffect(final SivvisValorEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SivvisValorEffect copy() {
+ return new SivvisValorEffect(this);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGE_CREATURE;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ Player controller = game.getPlayer(source.getControllerId());
+ DamageEvent damageEvent = (DamageEvent) event;
+ if (controller != null) {
+ controller.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects());
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Player controller = game.getPlayer(source.getControllerId());
+ DamageEvent damageEvent = (DamageEvent) event;
+ Permanent targetPermanent = game.getPermanent(source.getFirstTarget());
+ if (controller != null && targetPermanent != null) {
+ return targetPermanent.getId() == damageEvent.getTargetId();
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SoldeviSteamBeast.java b/Mage.Sets/src/mage/cards/s/SoldeviSteamBeast.java
new file mode 100644
index 00000000000..41c9a6c84ed
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SoldeviSteamBeast.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.cards.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BecomesTappedSourceTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.GainLifeTargetEffect;
+import mage.abilities.effects.common.RegenerateSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.target.common.TargetOpponent;
+
+/**
+ *
+ * @author L_J
+ */
+public class SoldeviSteamBeast extends CardImpl {
+
+ public SoldeviSteamBeast(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}");
+ this.subtype.add(SubType.BEAST);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // Whenever Soldevi Steam Beast becomes tapped, target opponent gains 2 life.
+ Ability ability = new BecomesTappedSourceTriggeredAbility(new GainLifeTargetEffect(2));
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+
+ // {2}: Regenerate Soldevi Steam Beast.
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new GenericManaCost(3)));
+ }
+
+ public SoldeviSteamBeast(final SoldeviSteamBeast card) {
+ super(card);
+ }
+
+ @Override
+ public SoldeviSteamBeast copy() {
+ return new SoldeviSteamBeast(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SoulCharmer.java b/Mage.Sets/src/mage/cards/s/SoulCharmer.java
new file mode 100644
index 00000000000..9602b4ffc6a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SoulCharmer.java
@@ -0,0 +1,66 @@
+/*
+ * 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.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.DealsCombatDamageToACreatureTriggeredAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+/**
+ *
+ * @author L_J
+ */
+public class SoulCharmer extends CardImpl {
+
+ public SoulCharmer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.REBEL);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever Soul Charmer deals combat damage to a creature, you gain 2 life unless he or she pays {2}.
+ this.addAbility(new DealsCombatDamageToACreatureTriggeredAbility(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new GainLifeEffect(2), new ManaCostsImpl("{2}")), false, true));
+ }
+
+ public SoulCharmer(final SoulCharmer card) {
+ super(card);
+ }
+
+ @Override
+ public SoulCharmer copy() {
+ return new SoulCharmer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/StromgaldSpy.java b/Mage.Sets/src/mage/cards/s/StromgaldSpy.java
new file mode 100644
index 00000000000..082fe025195
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/StromgaldSpy.java
@@ -0,0 +1,106 @@
+/*
+ * 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.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Layer;
+import mage.constants.Outcome;
+import mage.constants.SubLayer;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author L_J
+ */
+public class StromgaldSpy extends CardImpl {
+
+ public StromgaldSpy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+
+ // Whenever Stromgald Spy attacks and isn't blocked, you may have defending player play with his or her hand revealed for as long as Stromgald Spy remains on the battlefield. If you do, Stromgald Spy assigns no combat damage this turn.
+ Ability ability = new AttacksAndIsNotBlockedTriggeredAbility(new StromgaldSpyEffect(), true, true);
+ ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true));
+ this.addAbility(ability);
+ }
+
+ public StromgaldSpy(final StromgaldSpy card) {
+ super(card);
+ }
+
+ @Override
+ public StromgaldSpy copy() {
+ return new StromgaldSpy(this);
+ }
+}
+
+class StromgaldSpyEffect extends ContinuousEffectImpl {
+
+ public StromgaldSpyEffect() {
+ super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Detriment);
+ this.staticText = "you may have defending player play with his or her hand revealed for as long as Stromgald Spy remains on the battlefield";
+ }
+
+ public StromgaldSpyEffect(final StromgaldSpyEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null && sourcePermanent != null) {
+ Player defender = game.getPlayer(this.getTargetPointer().getFirst(game, source));
+ if (defender != null) {
+ defender.revealCards(defender.getName() + "'s hand cards", defender.getHand(), game, false);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public StromgaldSpyEffect copy() {
+ return new StromgaldSpyEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/ThresherBeast.java b/Mage.Sets/src/mage/cards/t/ThresherBeast.java
new file mode 100644
index 00000000000..032bebd53a1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/ThresherBeast.java
@@ -0,0 +1,103 @@
+/*
+ * 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.t;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.SacrificeEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author L_J
+ */
+public class ThresherBeast extends CardImpl {
+
+ public ThresherBeast(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}");
+ this.subtype.add(SubType.BEAST);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Whenever Thresher Beast becomes blocked, defending player sacrifices a land.
+ this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(new ThresherBeastEffect(), false));
+ }
+
+ public ThresherBeast(final ThresherBeast card) {
+ super(card);
+ }
+
+ @Override
+ public ThresherBeast copy() {
+ return new ThresherBeast(this);
+ }
+}
+
+class ThresherBeastEffect extends OneShotEffect {
+
+ public ThresherBeastEffect() {
+ super(Outcome.Discard);
+ this.staticText = "defending player sacrifices a land";
+ }
+
+ public ThresherBeastEffect(final ThresherBeastEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ThresherBeastEffect copy() {
+ return new ThresherBeastEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent blockingCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (blockingCreature != null) {
+ Player opponent = game.getPlayer(blockingCreature.getControllerId());
+ if (opponent != null) {
+ Effect effect = new SacrificeEffect(StaticFilters.FILTER_LAND, 1, "");
+ effect.setTargetPointer(new FixedTarget(opponent.getId()));
+ return effect.apply(game, source);
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/Topple.java b/Mage.Sets/src/mage/cards/t/Topple.java
new file mode 100644
index 00000000000..6b1a3ab0f53
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/Topple.java
@@ -0,0 +1,129 @@
+/*
+ * 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.t;
+
+import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class Topple extends CardImpl {
+
+ public Topple (UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}");
+
+ // Exile target creature with the greatest power among creatures on the battlefield.
+ this.getSpellAbility().addEffect(new ExileTargetEffect());
+ this.getSpellAbility().addTarget(new ToppleTargetCreature());
+ }
+
+ public Topple (final Topple card) {
+ super(card);
+ }
+
+ @Override
+ public Topple copy() {
+ return new Topple(this);
+ }
+}
+
+class ToppleTargetCreature extends TargetPermanent {
+
+ public ToppleTargetCreature() {
+ super();
+ filter.add(new CardTypePredicate(CardType.CREATURE));
+ setTargetName("creature with the greatest power among creatures on the battlefield");
+ }
+
+ public ToppleTargetCreature(final ToppleTargetCreature target) {
+ super(target);
+ }
+
+ @Override
+ public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
+ if (super.canTarget(controllerId, id, source, game)) {
+ int maxPower = 0;
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getId(), game)) {
+ if (permanent.getPower().getValue() > maxPower) {
+ maxPower = permanent.getPower().getValue();
+ }
+ }
+ Permanent targetPermanent = game.getPermanent(id);
+ if (targetPermanent != null) {
+ return targetPermanent.getPower().getValue() == maxPower;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
+ int maxPower = 0;
+ List activePermanents = game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game);
+ Set possibleTargets = new HashSet<>();
+ MageObject targetSource = game.getObject(sourceId);
+ for (Permanent permanent : activePermanents) {
+ if (permanent.getPower().getValue() > maxPower) {
+ maxPower = permanent.getPower().getValue();
+ }
+ }
+ for (Permanent permanent : activePermanents) {
+ if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
+ if (permanent.getPower().getValue() == maxPower) {
+ possibleTargets.add(permanent.getId());
+ }
+ }
+ }
+ return possibleTargets;
+ }
+
+ @Override
+ public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
+ return !possibleTargets(sourceId, sourceControllerId, game).isEmpty();
+ }
+
+ @Override
+ public ToppleTargetCreature copy() {
+ return new ToppleTargetCreature(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/v/VeteranBrawlers.java b/Mage.Sets/src/mage/cards/v/VeteranBrawlers.java
new file mode 100644
index 00000000000..1ab3d12c248
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/v/VeteranBrawlers.java
@@ -0,0 +1,122 @@
+/*
+ * 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.v;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.RestrictionEffect;
+import mage.abilities.effects.common.combat.CantAttackIfDefenderControlsPermanent;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterLandPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ * @author L_J
+ */
+public class VeteranBrawlers extends CardImpl {
+
+ static final private FilterLandPermanent filter = new FilterLandPermanent("an untapped land");
+ static {
+ filter.add(Predicates.not(new TappedPredicate()));
+ }
+
+ final static private String rule = "{this} can't block if you control an untapped land";
+
+ public VeteranBrawlers(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Veteran Brawlers can't attack if defending player controls an untapped land.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackIfDefenderControlsPermanent(filter)));
+
+ // Veteran Brawlers can't block if you control an untapped land.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new VeteranBrawlersCantBlockEffect(filter)));
+ }
+
+ public VeteranBrawlers(final VeteranBrawlers card) {
+ super(card);
+ }
+
+ @Override
+ public VeteranBrawlers copy() {
+ return new VeteranBrawlers(this);
+ }
+}
+
+class VeteranBrawlersCantBlockEffect extends RestrictionEffect {
+
+ private final FilterPermanent filter;
+
+ public VeteranBrawlersCantBlockEffect(FilterPermanent filter) {
+ super(Duration.WhileOnBattlefield);
+ this.filter = filter;
+ staticText = new StringBuilder("{this} can't attack if you control ").append(filter.getMessage()).toString();
+ }
+
+ public VeteranBrawlersCantBlockEffect(final VeteranBrawlersCantBlockEffect effect) {
+ super(effect);
+ this.filter = effect.filter;
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return permanent.getId().equals(source.getSourceId());
+ }
+
+ @Override
+ public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
+ Player player = game.getPlayer(blocker.getControllerId());
+ if (player != null) {
+ if (game.getBattlefield().countAll(filter, player.getId(), game) > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public VeteranBrawlersCantBlockEffect copy() {
+ return new VeteranBrawlersCantBlockEffect(this);
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/w/WallOfVipers.java b/Mage.Sets/src/mage/cards/w/WallOfVipers.java
new file mode 100644
index 00000000000..00dbc28da6c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WallOfVipers.java
@@ -0,0 +1,113 @@
+/*
+ * 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.w;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DestroySourceEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.keyword.DefenderAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.Game;
+import mage.game.combat.CombatGroup;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public class WallOfVipers extends CardImpl {
+
+ public WallOfVipers(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
+ this.subtype.add(SubType.SNAKE);
+ this.subtype.add(SubType.WALL);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+
+ // Defender
+ this.addAbility(DefenderAbility.getInstance());
+
+ // {3}: Destroy Wall of Vipers and target creature it's blocking. Any player may activate this ability.
+ SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroySourceEffect(), new ManaCostsImpl("{3}"));
+ ability.addEffect(new DestroyTargetEffect(" and target creature it's blocking"));
+ ability.addTarget(new TargetCreaturePermanent(new WallOfVipersFilter()));
+ ability.setMayActivate(TargetController.ANY);
+ ability.addEffect(new InfoEffect("Any player may activate this ability"));
+ this.addAbility(ability);
+ }
+
+ public WallOfVipers(final WallOfVipers card) {
+ super(card);
+ }
+
+ @Override
+ public WallOfVipers copy() {
+ return new WallOfVipers(this);
+ }
+}
+
+class WallOfVipersFilter extends FilterCreaturePermanent {
+
+ public WallOfVipersFilter() {
+ super("creature {this} is blocking");
+ }
+
+ public WallOfVipersFilter(final WallOfVipersFilter filter) {
+ super(filter);
+ }
+
+ @Override
+ public WallOfVipersFilter copy() {
+ return new WallOfVipersFilter(this);
+ }
+
+ @Override
+ public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
+ if (super.match(permanent, sourceId, playerId, game)) {
+ SubType subtype = (SubType) game.getState().getValue(sourceId + "_type");
+ for (CombatGroup combatGroup : game.getCombat().getGroups()) {
+ if (combatGroup.getBlockers().contains(sourceId) && combatGroup.getAttackers().contains(permanent.getId())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/w/WildMammoth.java b/Mage.Sets/src/mage/cards/w/WildMammoth.java
new file mode 100644
index 00000000000..3deee0822d3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WildMammoth.java
@@ -0,0 +1,140 @@
+/*
+ * 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.w;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author L_J
+ */
+public class WildMammoth extends CardImpl {
+
+ public WildMammoth(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}");
+ this.subtype.add(SubType.ELEPHANT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(4);
+
+ // At the beginning of your upkeep, if a player controls more creatures than each other player, the player who controls the most creatures gains control of Wild Mammoth.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(new WildMammothEffect(), TargetController.YOU, false));
+ }
+
+ public WildMammoth(final WildMammoth card) {
+ super(card);
+ }
+
+ @Override
+ public WildMammoth copy() {
+ return new WildMammoth(this);
+ }
+}
+
+class WildMammothEffect extends OneShotEffect {
+
+ public WildMammothEffect() {
+ super(Outcome.GainControl);
+ this.staticText = "if a player controls more creatures than each other player, the player who controls the most creatures gains control of {this}";
+ }
+
+ public WildMammothEffect(final WildMammothEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WildMammothEffect copy() {
+ return new WildMammothEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null) {
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ if (sourcePermanent != null) {
+ Player newController = null;
+ int maxCreatures = 0;
+ boolean tie = false;
+ FilterPermanent filter = new FilterPermanent();
+ filter.add(new CardTypePredicate(CardType.CREATURE));
+
+ for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null) {
+ int value = game.getBattlefield().countAll(filter, playerId, game);
+ if (value > maxCreatures) {
+ maxCreatures = value;
+ }
+ }
+ }
+ for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null) {
+ int value = game.getBattlefield().countAll(filter, playerId, game);
+ if (value == maxCreatures) {
+ if (newController == null) {
+ newController = player;
+ } else {
+ tie = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!controller.equals(newController) && !tie && newController != null) {
+ ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, newController.getId());
+ effect.setTargetPointer(new FixedTarget(sourcePermanent, game));
+ game.addEffect(effect, source);
+ }
+ }
+ return true;
+ }
+ return false;
+
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WingStorm.java b/Mage.Sets/src/mage/cards/w/WingStorm.java
new file mode 100644
index 00000000000..425fc90473a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WingStorm.java
@@ -0,0 +1,105 @@
+/*
+ * 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.w;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.game.Game;
+import mage.players.Player;
+
+/**
+ *
+ * @author LevelX2 & L_J
+ */
+public class WingStorm extends CardImpl {
+
+ public WingStorm(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}");
+
+ // Wing Storm deals damage to each player equal to twice the number of creatures with flying that player controls.
+ this.getSpellAbility().addEffect(new WingStormEffect());
+ }
+
+ public WingStorm(final WingStorm card) {
+ super(card);
+ }
+
+ @Override
+ public WingStorm copy() {
+ return new WingStorm(this);
+ }
+}
+
+class WingStormEffect extends OneShotEffect {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(new AbilityPredicate(FlyingAbility.class));
+ }
+
+ public WingStormEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "{this} deals damage to each player equal to twice the number of creatures with flying that player controls";
+ }
+
+ public WingStormEffect(final WingStormEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WingStormEffect copy() {
+ return new WingStormEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null) {
+ for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
+ int amount = game.getBattlefield().countAll(filter, playerId, game);
+ if (amount > 0) {
+ Player player = game.getPlayer(playerId);
+ if (player != null) {
+ player.damage(amount * 2, source.getSourceId(), game, false, true);
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java
index e97dda21691..a2f06f874ed 100644
--- a/Mage.Sets/src/mage/sets/Alliances.java
+++ b/Mage.Sets/src/mage/sets/Alliances.java
@@ -46,6 +46,7 @@ public class Alliances extends ExpansionSet {
cards.add(new SetCardInfo("Agent of Stromgald", 95, Rarity.COMMON, AgentOfStromgald.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Arcane Denial", 32, Rarity.COMMON, mage.cards.a.ArcaneDenial.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Arcane Denial", 33, Rarity.COMMON, mage.cards.a.ArcaneDenial.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Ashnod's Cylix", 158, Rarity.RARE, mage.cards.a.AshnodsCylix.class));
cards.add(new SetCardInfo("Astrolabe", 159, Rarity.COMMON, mage.cards.a.Astrolabe.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Astrolabe", 160, Rarity.COMMON, mage.cards.a.Astrolabe.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Balduvian Dead", 1, Rarity.UNCOMMON, mage.cards.b.BalduvianDead.class));
@@ -153,6 +154,8 @@ public class Alliances extends ExpansionSet {
cards.add(new SetCardInfo("Soldevi Heretic", 50, Rarity.COMMON, mage.cards.s.SoldeviHeretic.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Soldevi Sage", 51, Rarity.COMMON, SoldeviSage.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Soldevi Sage", 52, Rarity.COMMON, SoldeviSage.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Soldevi Steam Beast", 177, Rarity.COMMON, mage.cards.s.SoldeviSteamBeast.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Soldevi Steam Beast", 178, Rarity.COMMON, mage.cards.s.SoldeviSteamBeast.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Soldier of Fortune", 117, Rarity.UNCOMMON, mage.cards.s.SoldierOfFortune.class));
cards.add(new SetCardInfo("Sol Grail", 173, Rarity.UNCOMMON, mage.cards.s.SolGrail.class));
cards.add(new SetCardInfo("Stench of Decay", 27, Rarity.COMMON, mage.cards.s.StenchOfDecay.class, NON_FULL_USE_VARIOUS));
@@ -162,6 +165,7 @@ public class Alliances extends ExpansionSet {
cards.add(new SetCardInfo("Storm Crow", 55, Rarity.COMMON, mage.cards.s.StormCrow.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Storm Shaman", 118, Rarity.COMMON, StormShaman.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Storm Shaman", 119, Rarity.UNCOMMON, StormShaman.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Stromgald Spy", 29, Rarity.UNCOMMON, mage.cards.s.StromgaldSpy.class));
cards.add(new SetCardInfo("Surge of Strength", 197, Rarity.UNCOMMON, mage.cards.s.SurgeOfStrength.class));
cards.add(new SetCardInfo("Sustaining Spirit", 151, Rarity.RARE, mage.cards.s.SustainingSpirit.class));
cards.add(new SetCardInfo("Swamp Mosquito", 30, Rarity.COMMON, SwampMosquito.class, NON_FULL_USE_VARIOUS));
diff --git a/Mage.Sets/src/mage/sets/FourthEdition.java b/Mage.Sets/src/mage/sets/FourthEdition.java
index 77e093fdcdc..d4dfa9e5d7b 100644
--- a/Mage.Sets/src/mage/sets/FourthEdition.java
+++ b/Mage.Sets/src/mage/sets/FourthEdition.java
@@ -335,6 +335,7 @@ public class FourthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Righteousness", 46, Rarity.RARE, mage.cards.r.Righteousness.class));
cards.add(new SetCardInfo("Samite Healer", 47, Rarity.COMMON, mage.cards.s.SamiteHealer.class));
cards.add(new SetCardInfo("Savannah Lions", 48, Rarity.RARE, mage.cards.s.SavannahLions.class));
+ cards.add(new SetCardInfo("Seeker", 49, Rarity.COMMON, mage.cards.s.Seeker.class));
cards.add(new SetCardInfo("Serra Angel", 50, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class));
cards.add(new SetCardInfo("Spirit Link", 51, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class));
cards.add(new SetCardInfo("Swords to Plowshares", 52, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class));
diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java
index cba8669115e..e2c6548a2ec 100644
--- a/Mage.Sets/src/mage/sets/Legends.java
+++ b/Mage.Sets/src/mage/sets/Legends.java
@@ -130,6 +130,7 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Giant Strength", 147, Rarity.COMMON, mage.cards.g.GiantStrength.class));
cards.add(new SetCardInfo("Giant Turtle", 102, Rarity.COMMON, mage.cards.g.GiantTurtle.class));
cards.add(new SetCardInfo("Glyph of Destruction", 148, Rarity.COMMON, mage.cards.g.GlyphOfDestruction.class));
+ cards.add(new SetCardInfo("Glyph of Life", 184, Rarity.COMMON, mage.cards.g.GlyphOfLife.class));
cards.add(new SetCardInfo("Gravity Sphere", 149, Rarity.RARE, mage.cards.g.GravitySphere.class));
cards.add(new SetCardInfo("Great Defender", 185, Rarity.UNCOMMON, mage.cards.g.GreatDefender.class));
cards.add(new SetCardInfo("Greater Realm of Preservation", 187, Rarity.UNCOMMON, mage.cards.g.GreaterRealmOfPreservation.class));
@@ -233,6 +234,7 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Rubinia Soulsinger", 296, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class));
cards.add(new SetCardInfo("Rust", 49, Rarity.COMMON, mage.cards.r.Rust.class));
cards.add(new SetCardInfo("Sea Kings' Blessing", 75, Rarity.UNCOMMON, mage.cards.s.SeaKingsBlessing.class));
+ cards.add(new SetCardInfo("Seeker", 204, Rarity.UNCOMMON, mage.cards.s.Seeker.class));
cards.add(new SetCardInfo("Segovian Leviathan", 76, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class));
cards.add(new SetCardInfo("Sentinel", 239, Rarity.RARE, mage.cards.s.Sentinel.class));
cards.add(new SetCardInfo("Serpent Generator", 240, Rarity.RARE, mage.cards.s.SerpentGenerator.class));
diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java
index cafbc870abb..ec1bba35f8f 100644
--- a/Mage.Sets/src/mage/sets/MastersEditionII.java
+++ b/Mage.Sets/src/mage/sets/MastersEditionII.java
@@ -77,6 +77,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Armor of Faith", 4, Rarity.COMMON, mage.cards.a.ArmorOfFaith.class));
cards.add(new SetCardInfo("Armor Thrull", 77, Rarity.COMMON, ArmorThrull.class));
cards.add(new SetCardInfo("Ashen Ghoul", 78, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class));
+ cards.add(new SetCardInfo("Ashnod's Cylix", 203, Rarity.RARE, mage.cards.a.AshnodsCylix.class));
cards.add(new SetCardInfo("Aurochs", 153, Rarity.COMMON, mage.cards.a.Aurochs.class));
cards.add(new SetCardInfo("Aysen Bureaucrats", 6, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class));
cards.add(new SetCardInfo("Aysen Crusader", 7, Rarity.UNCOMMON, mage.cards.a.AysenCrusader.class));
diff --git a/Mage.Sets/src/mage/sets/Nemesis.java b/Mage.Sets/src/mage/sets/Nemesis.java
index f05a4909d36..a1fb5595e93 100644
--- a/Mage.Sets/src/mage/sets/Nemesis.java
+++ b/Mage.Sets/src/mage/sets/Nemesis.java
@@ -88,6 +88,7 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Eye of Yawgmoth", 129, Rarity.RARE, mage.cards.e.EyeOfYawgmoth.class));
cards.add(new SetCardInfo("Fanatical Devotion", 8, Rarity.COMMON, mage.cards.f.FanaticalDevotion.class));
cards.add(new SetCardInfo("Flame Rift", 80, Rarity.COMMON, mage.cards.f.FlameRift.class));
+ cards.add(new SetCardInfo("Flint Golem", 130, Rarity.UNCOMMON, mage.cards.f.FlintGolem.class));
cards.add(new SetCardInfo("Flowstone Armor", 131, Rarity.UNCOMMON, mage.cards.f.FlowstoneArmor.class));
cards.add(new SetCardInfo("Flowstone Crusher", 81, Rarity.COMMON, mage.cards.f.FlowstoneCrusher.class));
cards.add(new SetCardInfo("Flowstone Overseer", 82, Rarity.RARE, mage.cards.f.FlowstoneOverseer.class));
@@ -96,6 +97,8 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Flowstone Surge", 85, Rarity.UNCOMMON, mage.cards.f.FlowstoneSurge.class));
cards.add(new SetCardInfo("Flowstone Thopter", 132, Rarity.UNCOMMON, mage.cards.f.FlowstoneThopter.class));
cards.add(new SetCardInfo("Flowstone Wall", 86, Rarity.COMMON, mage.cards.f.FlowstoneWall.class));
+ cards.add(new SetCardInfo("Fog Patch", 104, Rarity.COMMON, mage.cards.f.FogPatch.class));
+ cards.add(new SetCardInfo("Harvest Mage", 105, Rarity.COMMON, mage.cards.h.HarvestMage.class));
cards.add(new SetCardInfo("Infiltrate", 33, Rarity.COMMON, mage.cards.i.Infiltrate.class));
cards.add(new SetCardInfo("Jolting Merfolk", 34, Rarity.UNCOMMON, mage.cards.j.JoltingMerfolk.class));
cards.add(new SetCardInfo("Kill Switch", 133, Rarity.RARE, mage.cards.k.KillSwitch.class));
@@ -109,12 +112,15 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Lawbringer", 10, Rarity.COMMON, mage.cards.l.Lawbringer.class));
cards.add(new SetCardInfo("Lightbringer", 11, Rarity.COMMON, mage.cards.l.Lightbringer.class));
cards.add(new SetCardInfo("Lin Sivvi, Defiant Hero", 12, Rarity.RARE, mage.cards.l.LinSivviDefiantHero.class));
+ cards.add(new SetCardInfo("Mana Cache", 92, Rarity.RARE, mage.cards.m.ManaCache.class));
cards.add(new SetCardInfo("Massacre", 58, Rarity.UNCOMMON, mage.cards.m.Massacre.class));
cards.add(new SetCardInfo("Mind Slash", 59, Rarity.UNCOMMON, mage.cards.m.MindSlash.class));
cards.add(new SetCardInfo("Mind Swords", 60, Rarity.COMMON, mage.cards.m.MindSwords.class));
cards.add(new SetCardInfo("Mogg Alarm", 93, Rarity.UNCOMMON, mage.cards.m.MoggAlarm.class));
- cards.add(new SetCardInfo("Moggcatcher", 96, Rarity.RARE, mage.cards.m.Moggcatcher.class));
cards.add(new SetCardInfo("Mogg Salvage", 94, Rarity.UNCOMMON, mage.cards.m.MoggSalvage.class));
+ cards.add(new SetCardInfo("Mogg Toady", 95, Rarity.COMMON, mage.cards.m.MoggToady.class));
+ cards.add(new SetCardInfo("Moggcatcher", 96, Rarity.RARE, mage.cards.m.Moggcatcher.class));
+ cards.add(new SetCardInfo("Mossdog", 106, Rarity.COMMON, mage.cards.m.Mossdog.class));
cards.add(new SetCardInfo("Murderous Betrayal", 61, Rarity.RARE, mage.cards.m.MurderousBetrayal.class));
cards.add(new SetCardInfo("Nesting Wurm", 107, Rarity.UNCOMMON, mage.cards.n.NestingWurm.class));
cards.add(new SetCardInfo("Netter en-Dal", 13, Rarity.COMMON, mage.cards.n.NetterEnDal.class));
@@ -146,6 +152,7 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Rising Waters", 38, Rarity.RARE, mage.cards.r.RisingWaters.class));
cards.add(new SetCardInfo("Rootwater Commando", 39, Rarity.COMMON, mage.cards.r.RootwaterCommando.class));
cards.add(new SetCardInfo("Rootwater Thief", 40, Rarity.RARE, mage.cards.r.RootwaterThief.class));
+ cards.add(new SetCardInfo("Rupture", 97, Rarity.UNCOMMON, mage.cards.r.Rupture.class));
cards.add(new SetCardInfo("Rusting Golem", 138, Rarity.UNCOMMON, mage.cards.r.RustingGolem.class));
cards.add(new SetCardInfo("Saproling Burst", 113, Rarity.RARE, mage.cards.s.SaprolingBurst.class));
cards.add(new SetCardInfo("Saproling Cluster", 114, Rarity.RARE, mage.cards.s.SaprolingCluster.class));
@@ -159,6 +166,7 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Silkenfist Fighter", 19, Rarity.COMMON, mage.cards.s.SilkenfistFighter.class));
cards.add(new SetCardInfo("Silkenfist Order", 20, Rarity.UNCOMMON, mage.cards.s.SilkenfistOrder.class));
cards.add(new SetCardInfo("Sivvi's Ruse", 21, Rarity.UNCOMMON, mage.cards.s.SivvisRuse.class));
+ cards.add(new SetCardInfo("Sivvi's Valor", 22, Rarity.RARE, mage.cards.s.SivvisValor.class));
cards.add(new SetCardInfo("Skyshroud Behemoth", 116, Rarity.RARE, mage.cards.s.SkyshroudBehemoth.class));
cards.add(new SetCardInfo("Skyshroud Claim", 117, Rarity.COMMON, mage.cards.s.SkyshroudClaim.class));
cards.add(new SetCardInfo("Skyshroud Cutter", 118, Rarity.COMMON, mage.cards.s.SkyshroudCutter.class));
@@ -179,6 +187,7 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Submerge", 48, Rarity.UNCOMMON, mage.cards.s.Submerge.class));
cards.add(new SetCardInfo("Tangle Wire", 139, Rarity.RARE, mage.cards.t.TangleWire.class));
cards.add(new SetCardInfo("Terrain Generator", 143, Rarity.UNCOMMON, mage.cards.t.TerrainGenerator.class));
+ cards.add(new SetCardInfo("Topple", 24, Rarity.COMMON, mage.cards.t.Topple.class));
cards.add(new SetCardInfo("Treetop Bracers", 123, Rarity.COMMON, mage.cards.t.TreetopBracers.class));
cards.add(new SetCardInfo("Trickster Mage", 49, Rarity.COMMON, mage.cards.t.TricksterMage.class));
cards.add(new SetCardInfo("Vicious Hunger", 74, Rarity.COMMON, mage.cards.v.ViciousHunger.class));
@@ -186,6 +195,7 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Voice of Truth", 25, Rarity.UNCOMMON, mage.cards.v.VoiceOfTruth.class));
cards.add(new SetCardInfo("Volrath the Fallen", 75, Rarity.RARE, mage.cards.v.VolrathTheFallen.class));
cards.add(new SetCardInfo("Wandering Eye", 50, Rarity.COMMON, mage.cards.w.WanderingEye.class));
+ cards.add(new SetCardInfo("Wild Mammoth", 124, Rarity.UNCOMMON, mage.cards.w.WildMammoth.class));
cards.add(new SetCardInfo("Woodripper", 125, Rarity.UNCOMMON, mage.cards.w.Woodripper.class));
}
}
diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java
index 8e76f69828b..daf0abe761b 100644
--- a/Mage.Sets/src/mage/sets/Onslaught.java
+++ b/Mage.Sets/src/mage/sets/Onslaught.java
@@ -62,9 +62,11 @@ public class Onslaught extends ExpansionSet {
cards.add(new SetCardInfo("Break Open", 190, Rarity.COMMON, mage.cards.b.BreakOpen.class));
cards.add(new SetCardInfo("Brightstone Ritual", 191, Rarity.COMMON, mage.cards.b.BrightstoneRitual.class));
cards.add(new SetCardInfo("Broodhatch Nantuko", 250, Rarity.UNCOMMON, mage.cards.b.BroodhatchNantuko.class));
+ cards.add(new SetCardInfo("Butcher Orgg", 192, Rarity.RARE, mage.cards.b.ButcherOrgg.class));
cards.add(new SetCardInfo("Cabal Archon", 129, Rarity.UNCOMMON, mage.cards.c.CabalArchon.class));
cards.add(new SetCardInfo("Cabal Executioner", 130, Rarity.UNCOMMON, mage.cards.c.CabalExecutioner.class));
cards.add(new SetCardInfo("Cabal Slaver", 131, Rarity.UNCOMMON, mage.cards.c.CabalSlaver.class));
+ cards.add(new SetCardInfo("Callous Oppressor", 72, Rarity.RARE, mage.cards.c.CallousOppressor.class));
cards.add(new SetCardInfo("Catapult Master", 10, Rarity.RARE, mage.cards.c.CatapultMaster.class));
cards.add(new SetCardInfo("Catapult Squad", 11, Rarity.UNCOMMON, mage.cards.c.CatapultSquad.class));
cards.add(new SetCardInfo("Centaur Glade", 251, Rarity.UNCOMMON, mage.cards.c.CentaurGlade.class));
@@ -102,6 +104,7 @@ public class Onslaught extends ExpansionSet {
cards.add(new SetCardInfo("Dispersing Orb", 80, Rarity.UNCOMMON, mage.cards.d.DispersingOrb.class));
cards.add(new SetCardInfo("Disruptive Pitmage", 81, Rarity.COMMON, mage.cards.d.DisruptivePitmage.class));
cards.add(new SetCardInfo("Dive Bomber", 26, Rarity.COMMON, mage.cards.d.DiveBomber.class));
+ cards.add(new SetCardInfo("Doom Cannon", 307, Rarity.RARE, mage.cards.d.DoomCannon.class));
cards.add(new SetCardInfo("Doomed Necromancer", 140, Rarity.RARE, mage.cards.d.DoomedNecromancer.class));
cards.add(new SetCardInfo("Doubtless One", 27, Rarity.UNCOMMON, mage.cards.d.DoubtlessOne.class));
cards.add(new SetCardInfo("Dragon Roost", 198, Rarity.RARE, mage.cards.d.DragonRoost.class));
@@ -117,6 +120,7 @@ public class Onslaught extends ExpansionSet {
cards.add(new SetCardInfo("Elvish Warrior", 260, Rarity.COMMON, mage.cards.e.ElvishWarrior.class));
cards.add(new SetCardInfo("Embermage Goblin", 200, Rarity.UNCOMMON, mage.cards.e.EmbermageGoblin.class));
cards.add(new SetCardInfo("Enchantress's Presence", 261, Rarity.RARE, mage.cards.e.EnchantresssPresence.class));
+ cards.add(new SetCardInfo("Entrails Feaster", 143, Rarity.RARE, mage.cards.e.EntrailsFeaster.class));
cards.add(new SetCardInfo("Erratic Explosion", 201, Rarity.COMMON, mage.cards.e.ErraticExplosion.class));
cards.add(new SetCardInfo("Essence Fracture", 82, Rarity.UNCOMMON, mage.cards.e.EssenceFracture.class));
cards.add(new SetCardInfo("Everglove Courier", 262, Rarity.UNCOMMON, mage.cards.e.EvergloveCourier.class));
@@ -186,6 +190,7 @@ public class Onslaught extends ExpansionSet {
cards.add(new SetCardInfo("Ixidor, Reality Sculptor", 89, Rarity.RARE, mage.cards.i.IxidorRealitySculptor.class));
cards.add(new SetCardInfo("Jareth, Leonine Titan", 43, Rarity.RARE, mage.cards.j.JarethLeonineTitan.class));
cards.add(new SetCardInfo("Kamahl, Fist of Krosa", 268, Rarity.RARE, mage.cards.k.KamahlFistOfKrosa.class));
+ cards.add(new SetCardInfo("Kamahl's Summons", 269, Rarity.UNCOMMON, mage.cards.k.KamahlsSummons.class));
cards.add(new SetCardInfo("Krosan Colossus", 270, Rarity.RARE, mage.cards.k.KrosanColossus.class));
cards.add(new SetCardInfo("Krosan Groundshaker", 271, Rarity.UNCOMMON, mage.cards.k.KrosanGroundshaker.class));
cards.add(new SetCardInfo("Krosan Tusker", 272, Rarity.COMMON, mage.cards.k.KrosanTusker.class));
@@ -266,6 +271,7 @@ public class Onslaught extends ExpansionSet {
cards.add(new SetCardInfo("Shaleskin Bruiser", 226, Rarity.UNCOMMON, mage.cards.s.ShaleskinBruiser.class));
cards.add(new SetCardInfo("Shared Triumph", 53, Rarity.RARE, mage.cards.s.SharedTriumph.class));
cards.add(new SetCardInfo("Shepherd of Rot", 168, Rarity.COMMON, mage.cards.s.ShepherdOfRot.class));
+ cards.add(new SetCardInfo("Shieldmage Elder", 54, Rarity.UNCOMMON, mage.cards.s.ShieldmageElder.class));
cards.add(new SetCardInfo("Shock", 227, Rarity.COMMON, mage.cards.s.Shock.class));
cards.add(new SetCardInfo("Sigil of the New Dawn", 55, Rarity.RARE, mage.cards.s.SigilOfTheNewDawn.class));
cards.add(new SetCardInfo("Silent Specter", 169, Rarity.RARE, mage.cards.s.SilentSpecter.class));
diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java
index 9f3172aa2f7..25bd32e66ce 100644
--- a/Mage.Sets/src/mage/sets/Prophecy.java
+++ b/Mage.Sets/src/mage/sets/Prophecy.java
@@ -68,6 +68,7 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Blessed Wind", 4, Rarity.RARE, mage.cards.b.BlessedWind.class));
cards.add(new SetCardInfo("Bog Elemental", 57, Rarity.RARE, mage.cards.b.BogElemental.class));
cards.add(new SetCardInfo("Bog Glider", 58, Rarity.COMMON, mage.cards.b.BogGlider.class));
+ cards.add(new SetCardInfo("Branded Brawlers", 84, Rarity.COMMON, mage.cards.b.BrandedBrawlers.class));
cards.add(new SetCardInfo("Calming Verse", 110, Rarity.COMMON, mage.cards.c.CalmingVerse.class));
cards.add(new SetCardInfo("Celestial Convergence", 5, Rarity.RARE, mage.cards.c.CelestialConvergence.class));
cards.add(new SetCardInfo("Chilling Apparition", 59, Rarity.UNCOMMON, mage.cards.c.ChillingApparition.class));
@@ -77,6 +78,7 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Coffin Puppets", 60, Rarity.RARE, mage.cards.c.CoffinPuppets.class));
cards.add(new SetCardInfo("Copper-Leaf Angel", 137, Rarity.RARE, mage.cards.c.CopperLeafAngel.class));
cards.add(new SetCardInfo("Darba", 111, Rarity.UNCOMMON, mage.cards.d.Darba.class));
+ cards.add(new SetCardInfo("Death Charmer", 61, Rarity.COMMON, mage.cards.d.DeathCharmer.class));
cards.add(new SetCardInfo("Denying Wind", 32, Rarity.RARE, mage.cards.d.DenyingWind.class));
cards.add(new SetCardInfo("Despoil", 62, Rarity.COMMON, mage.cards.d.Despoil.class));
cards.add(new SetCardInfo("Devastate", 87, Rarity.COMMON, mage.cards.d.Devastate.class));
@@ -86,24 +88,30 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Endbringer's Revel", 63, Rarity.UNCOMMON, mage.cards.e.EndbringersRevel.class));
cards.add(new SetCardInfo("Entangler", 7, Rarity.UNCOMMON, mage.cards.e.Entangler.class));
cards.add(new SetCardInfo("Excavation", 33, Rarity.UNCOMMON, mage.cards.e.Excavation.class));
+ cards.add(new SetCardInfo("Excise", 8, Rarity.COMMON, mage.cards.e.Excise.class));
cards.add(new SetCardInfo("Fault Riders", 88, Rarity.COMMON, mage.cards.f.FaultRiders.class));
cards.add(new SetCardInfo("Fen Stalker", 64, Rarity.COMMON, mage.cards.f.FenStalker.class));
cards.add(new SetCardInfo("Fickle Efreet", 89, Rarity.RARE, mage.cards.f.FickleEfreet.class));
cards.add(new SetCardInfo("Flameshot", 90, Rarity.UNCOMMON, mage.cards.f.Flameshot.class));
+ cards.add(new SetCardInfo("Flay", 65, Rarity.COMMON, mage.cards.f.Flay.class));
cards.add(new SetCardInfo("Flowering Field", 9, Rarity.UNCOMMON, mage.cards.f.FloweringField.class));
cards.add(new SetCardInfo("Foil", 34, Rarity.UNCOMMON, mage.cards.f.Foil.class));
cards.add(new SetCardInfo("Forgotten Harvest", 114, Rarity.RARE, mage.cards.f.ForgottenHarvest.class));
+ cards.add(new SetCardInfo("Glittering Lion", 10, Rarity.UNCOMMON, mage.cards.g.GlitteringLion.class));
+ cards.add(new SetCardInfo("Glittering Lynx", 11, Rarity.COMMON, mage.cards.g.GlitteringLynx.class));
cards.add(new SetCardInfo("Greel's Caress", 67, Rarity.COMMON, mage.cards.g.GreelsCaress.class));
cards.add(new SetCardInfo("Greel, Mind Raker", 66, Rarity.RARE, mage.cards.g.GreelMindRaker.class));
cards.add(new SetCardInfo("Gulf Squid", 35, Rarity.COMMON, mage.cards.g.GulfSquid.class));
cards.add(new SetCardInfo("Hazy Homunculus", 36, Rarity.COMMON, mage.cards.h.HazyHomunculus.class));
cards.add(new SetCardInfo("Heightened Awareness", 37, Rarity.RARE, mage.cards.h.HeightenedAwareness.class));
+ cards.add(new SetCardInfo("Hollow Warrior", 138, Rarity.UNCOMMON, mage.cards.h.HollowWarrior.class));
cards.add(new SetCardInfo("Infernal Genesis", 68, Rarity.RARE, mage.cards.i.InfernalGenesis.class));
cards.add(new SetCardInfo("Inflame", 91, Rarity.COMMON, mage.cards.i.Inflame.class));
cards.add(new SetCardInfo("Jeweled Spirit", 12, Rarity.RARE, mage.cards.j.JeweledSpirit.class));
cards.add(new SetCardInfo("Jolrael, Empress of Beasts", 115, Rarity.RARE, mage.cards.j.JolraelEmpressOfBeasts.class));
cards.add(new SetCardInfo("Jolrael's Favor", 116, Rarity.COMMON, mage.cards.j.JolraelsFavor.class));
cards.add(new SetCardInfo("Keldon Arsonist", 92, Rarity.UNCOMMON, mage.cards.k.KeldonArsonist.class));
+ cards.add(new SetCardInfo("Keldon Battlewagon", 139, Rarity.RARE, mage.cards.k.KeldonBattlewagon.class));
cards.add(new SetCardInfo("Keldon Berserker", 93, Rarity.COMMON, mage.cards.k.KeldonBerserker.class));
cards.add(new SetCardInfo("Keldon Firebombers", 94, Rarity.RARE, mage.cards.k.KeldonFirebombers.class));
cards.add(new SetCardInfo("Latulla, Keldon Overseer", 95, Rarity.RARE, mage.cards.l.LatullaKeldonOverseer.class));
@@ -116,6 +124,7 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Marsh Boa", 118, Rarity.COMMON, mage.cards.m.MarshBoa.class));
cards.add(new SetCardInfo("Mercenary Informer", 15, Rarity.RARE, mage.cards.m.MercenaryInformer.class));
cards.add(new SetCardInfo("Mine Bearer", 16, Rarity.COMMON, mage.cards.m.MineBearer.class));
+ cards.add(new SetCardInfo("Mirror Strike", 17, Rarity.UNCOMMON, mage.cards.m.MirrorStrike.class));
cards.add(new SetCardInfo("Mungha Wurm", 119, Rarity.RARE, mage.cards.m.MunghaWurm.class));
cards.add(new SetCardInfo("Nakaya Shade", 69, Rarity.UNCOMMON, mage.cards.n.NakayaShade.class));
cards.add(new SetCardInfo("Noxious Field", 70, Rarity.UNCOMMON, mage.cards.n.NoxiousField.class));
@@ -133,7 +142,12 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Reveille Squad", 18, Rarity.UNCOMMON, mage.cards.r.ReveilleSquad.class));
cards.add(new SetCardInfo("Rhystic Cave", 142, Rarity.UNCOMMON, mage.cards.r.RhysticCave.class));
cards.add(new SetCardInfo("Rhystic Circle", 19, Rarity.COMMON, mage.cards.r.RhysticCircle.class));
+ cards.add(new SetCardInfo("Rhystic Deluge", 43, Rarity.COMMON, mage.cards.r.RhysticDeluge.class));
+ cards.add(new SetCardInfo("Rhystic Lightning", 99, Rarity.COMMON, mage.cards.r.RhysticLightning.class));
+ cards.add(new SetCardInfo("Rhystic Scrying", 44, Rarity.UNCOMMON, mage.cards.r.RhysticScrying.class));
+ cards.add(new SetCardInfo("Rhystic Shield", 20, Rarity.COMMON, mage.cards.r.RhysticShield.class));
cards.add(new SetCardInfo("Rhystic Study", 45, Rarity.COMMON, mage.cards.r.RhysticStudy.class));
+ cards.add(new SetCardInfo("Rhystic Syphon", 76, Rarity.UNCOMMON, mage.cards.r.RhysticSyphon.class));
cards.add(new SetCardInfo("Rhystic Tutor", 77, Rarity.RARE, mage.cards.r.RhysticTutor.class));
cards.add(new SetCardInfo("Ribbon Snake", 46, Rarity.COMMON, mage.cards.r.RibbonSnake.class));
cards.add(new SetCardInfo("Rib Cage Spider", 121, Rarity.COMMON, mage.cards.r.RibCageSpider.class));
@@ -143,8 +157,10 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Scoria Cat", 101, Rarity.UNCOMMON, mage.cards.s.ScoriaCat.class));
cards.add(new SetCardInfo("Searing Wind", 103, Rarity.RARE, mage.cards.s.SearingWind.class));
cards.add(new SetCardInfo("Shield Dancer", 23, Rarity.UNCOMMON, mage.cards.s.ShieldDancer.class));
+ cards.add(new SetCardInfo("Shrouded Serpent", 47, Rarity.RARE, mage.cards.s.ShroudedSerpent.class));
cards.add(new SetCardInfo("Silt Crawler", 123, Rarity.COMMON, mage.cards.s.SiltCrawler.class));
cards.add(new SetCardInfo("Snag", 124, Rarity.UNCOMMON, mage.cards.s.Snag.class));
+ cards.add(new SetCardInfo("Soul Charmer", 24, Rarity.COMMON, mage.cards.s.SoulCharmer.class));
cards.add(new SetCardInfo("Spiketail Drake", 48, Rarity.UNCOMMON, mage.cards.s.SpiketailDrake.class));
cards.add(new SetCardInfo("Spiketail Hatchling", 49, Rarity.COMMON, mage.cards.s.SpiketailHatchling.class));
cards.add(new SetCardInfo("Spitting Spider", 125, Rarity.UNCOMMON, mage.cards.s.SpittingSpider.class));
@@ -156,20 +172,24 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Sunken Field", 51, Rarity.UNCOMMON, mage.cards.s.SunkenField.class));
cards.add(new SetCardInfo("Sword Dancer", 25, Rarity.UNCOMMON, mage.cards.s.SwordDancer.class));
cards.add(new SetCardInfo("Task Mage Assembly", 105, Rarity.RARE, mage.cards.t.TaskMageAssembly.class));
+ cards.add(new SetCardInfo("Thresher Beast", 128, Rarity.COMMON, mage.cards.t.ThresherBeast.class));
cards.add(new SetCardInfo("Thrive", 129, Rarity.COMMON, mage.cards.t.Thrive.class));
cards.add(new SetCardInfo("Trenching Steed", 26, Rarity.COMMON, mage.cards.t.TrenchingSteed.class));
cards.add(new SetCardInfo("Troubled Healer", 27, Rarity.COMMON, mage.cards.t.TroubledHealer.class));
cards.add(new SetCardInfo("Troublesome Spirit", 52, Rarity.RARE, mage.cards.t.TroublesomeSpirit.class));
cards.add(new SetCardInfo("Verdant Field", 130, Rarity.UNCOMMON, mage.cards.v.VerdantField.class));
+ cards.add(new SetCardInfo("Veteran Brawlers", 106, Rarity.RARE, mage.cards.v.VeteranBrawlers.class));
cards.add(new SetCardInfo("Vintara Elephant", 131, Rarity.COMMON, mage.cards.v.VintaraElephant.class));
cards.add(new SetCardInfo("Vintara Snapper", 132, Rarity.UNCOMMON, mage.cards.v.VintaraSnapper.class));
cards.add(new SetCardInfo("Vitalizing Wind", 133, Rarity.RARE, mage.cards.v.VitalizingWind.class));
+ cards.add(new SetCardInfo("Wall of Vipers", 80, Rarity.UNCOMMON, mage.cards.w.WallOfVipers.class));
cards.add(new SetCardInfo("Well of Discovery", 140, Rarity.RARE, mage.cards.w.WellOfDiscovery.class));
cards.add(new SetCardInfo("Well of Life", 141, Rarity.UNCOMMON, mage.cards.w.WellOfLife.class));
cards.add(new SetCardInfo("Whip Sergeant", 107, Rarity.UNCOMMON, mage.cards.w.WhipSergeant.class));
cards.add(new SetCardInfo("Whipstitched Zombie", 81, Rarity.COMMON, mage.cards.w.WhipstitchedZombie.class));
cards.add(new SetCardInfo("Wild Might", 134, Rarity.COMMON, mage.cards.w.WildMight.class));
cards.add(new SetCardInfo("Windscouter", 53, Rarity.UNCOMMON, mage.cards.w.Windscouter.class));
+ cards.add(new SetCardInfo("Wing Storm", 135, Rarity.UNCOMMON, mage.cards.w.WingStorm.class));
cards.add(new SetCardInfo("Wintermoon Mesa", 143, Rarity.RARE, mage.cards.w.WintermoonMesa.class));
cards.add(new SetCardInfo("Withdraw", 54, Rarity.COMMON, mage.cards.w.Withdraw.class));
cards.add(new SetCardInfo("Zerapa Minotaur", 108, Rarity.COMMON, mage.cards.z.ZerapaMinotaur.class));
diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
index 006f999ae22..5835ef9b067 100644
--- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
+++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
@@ -33,6 +33,7 @@ public class VerifyCardDataTest {
// power-toughness
skipListCreate("PT");
skipListAddName("PT", "Garbage Elemental"); // UST
+ skipListAddName("PT", "Infinity Elemental"); // UST
// color
skipListCreate("COLOR");
diff --git a/Mage/src/main/java/mage/abilities/common/ControllerDivideCombatDamageAbility.java b/Mage/src/main/java/mage/abilities/common/ControllerDivideCombatDamageAbility.java
new file mode 100644
index 00000000000..aceae25cf31
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/common/ControllerDivideCombatDamageAbility.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 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.common;
+
+import mage.abilities.MageSingleton;
+import mage.abilities.StaticAbility;
+
+import java.io.ObjectStreamException;
+
+import mage.constants.AbilityType;
+import mage.constants.Zone;
+
+/**
+ * @author L_J
+ */
+public class ControllerDivideCombatDamageAbility extends StaticAbility implements MageSingleton {
+
+ private static final ControllerDivideCombatDamageAbility instance = new ControllerDivideCombatDamageAbility();
+
+ private Object readResolve() throws ObjectStreamException {
+ return instance;
+ }
+
+ public static ControllerDivideCombatDamageAbility getInstance() {
+ return instance;
+ }
+
+ private ControllerDivideCombatDamageAbility() {
+ super(AbilityType.STATIC, Zone.BATTLEFIELD);
+ }
+
+ @Override
+ public String getRule() {
+ return "You may assign {this}'s combat damage divided as you choose among defending player and/or any number of creatures he or she controls.";
+ }
+
+ @Override
+ public ControllerDivideCombatDamageAbility copy() {
+ return instance;
+ }
+
+}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java
new file mode 100644
index 00000000000..47f064ea6fb
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java
@@ -0,0 +1,172 @@
+/*
+ * 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;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.Effects;
+import mage.abilities.effects.OneShotEffect;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.util.CardUtil;
+
+/**
+ *
+ * @author MarcoMarin & L_J
+ */
+public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEffect {
+
+ protected Effects executingEffects = new Effects();
+ private Effect otherwiseEffect;
+ private Cost cost;
+ private DynamicValue genericMana;
+ private String chooseUseText;
+
+ public DoUnlessTargetPlayerOrTargetsControllerPaysEffect(Effect effect, Cost cost) {
+ this(effect, cost, null);
+ }
+
+ public DoUnlessTargetPlayerOrTargetsControllerPaysEffect(Effect effect, Cost cost, String chooseUseText) {
+ this(effect, null, cost, chooseUseText);
+ }
+
+ public DoUnlessTargetPlayerOrTargetsControllerPaysEffect(Effect effect, Effect otherwiseEffect, Cost cost, String chooseUseText) {
+ super(Outcome.Detriment);
+ this.executingEffects.add(effect);
+ this.otherwiseEffect = otherwiseEffect;
+ this.cost = cost;
+ this.chooseUseText = chooseUseText;
+ }
+
+ public DoUnlessTargetPlayerOrTargetsControllerPaysEffect(Effect effect, DynamicValue genericMana) {
+ super(Outcome.Detriment);
+ this.executingEffects.add(effect);
+ this.genericMana = genericMana;
+ }
+
+ public DoUnlessTargetPlayerOrTargetsControllerPaysEffect(final DoUnlessTargetPlayerOrTargetsControllerPaysEffect effect) {
+ super(effect);
+ this.executingEffects = effect.executingEffects.copy();
+ this.otherwiseEffect = effect.otherwiseEffect;
+ if (effect.cost != null) {
+ this.cost = effect.cost.copy();
+ }
+ if (effect.genericMana != null) {
+ this.genericMana = effect.genericMana.copy();
+ }
+ this.chooseUseText = effect.chooseUseText;
+ }
+
+ public void addEffect(Effect effect) {
+ executingEffects.add(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player targetController = game.getPlayer(this.getTargetPointer().getFirst(game, source));
+ Permanent targetPermanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source));
+ if (targetPermanent != null) {
+ targetController = game.getPlayer(targetPermanent.getControllerId());
+ }
+ if (targetController != null) {
+ MageObject sourceObject = game.getObject(source.getSourceId());
+ if (targetController != null && sourceObject != null) {
+ Cost costToPay;
+ if (cost != null) {
+ costToPay = cost.copy();
+ } else {
+ costToPay = new GenericManaCost(genericMana.calculate(game, source, this));
+ }
+ String message;
+ if (chooseUseText == null) {
+ String effectText = executingEffects.getText(source.getModes().getMode());
+ message = "Pay " + costToPay.getText() + " to prevent (" + effectText.substring(0, effectText.length() - 1) + ")?";
+ } else {
+ message = chooseUseText;
+ }
+ message = CardUtil.replaceSourceName(message, sourceObject.getName());
+ boolean result = true;
+ boolean doEffect = true;
+
+ // check if targetController is willing to pay
+ if (costToPay.canPay(source, source.getSourceId(), targetController.getId(), game) && targetController.chooseUse(Outcome.Detriment, message, source, game)) {
+ costToPay.clearPaid();
+ if (costToPay.pay(source, game, source.getSourceId(), targetController.getId(), false, null)) {
+ if (!game.isSimulation()) {
+ game.informPlayers(targetController.getLogName() + " pays the cost to prevent the effect");
+ }
+ doEffect = false;
+ }
+ }
+
+ // do the effects if not paid
+ if (doEffect) {
+ for (Effect effect : executingEffects) {
+ effect.setTargetPointer(this.targetPointer);
+ if (effect instanceof OneShotEffect) {
+ result &= effect.apply(game, source);
+ } else {
+ game.addEffect((ContinuousEffect) effect, source);
+ }
+ }
+ } else if (otherwiseEffect != null) {
+ otherwiseEffect.setTargetPointer(this.targetPointer);
+ if (otherwiseEffect instanceof OneShotEffect) {
+ result &= otherwiseEffect.apply(game, source);
+ } else {
+ game.addEffect((ContinuousEffect) otherwiseEffect, source);
+ }
+ }
+ return result;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getText(Mode mode) {
+ if (!staticText.isEmpty()) {
+ return staticText;
+ }
+ String effectsText = executingEffects.getText(mode);
+ return effectsText.substring(0, effectsText.length() - 1) + " unless its controller pays " + (cost != null ? cost.getText() : "{X}");
+ }
+
+ @Override
+ public DoUnlessTargetPlayerOrTargetsControllerPaysEffect copy() {
+ return new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(this);
+ }
+}
diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java
index ca02d9e7bbf..7b5e10477b5 100644
--- a/Mage/src/main/java/mage/game/GameImpl.java
+++ b/Mage/src/main/java/mage/game/GameImpl.java
@@ -3000,5 +3000,4 @@ public abstract class GameImpl implements Game, Serializable {
fireEvent(new GameEvent(GameEvent.EventType.BECOMES_MONARCH, monarchId, source == null ? null : source.getSourceId(), monarchId));
}
}
-
}
diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java
index 44a4e52f383..7ad9391ceac 100644
--- a/Mage/src/main/java/mage/game/combat/CombatGroup.java
+++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java
@@ -34,6 +34,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.abilities.common.ControllerAssignCombatDamageToBlockersAbility;
+import mage.abilities.common.ControllerDivideCombatDamageAbility;
import mage.abilities.common.DamageAsThoughNotBlockedAbility;
import mage.abilities.keyword.CantBlockAloneAbility;
import mage.abilities.keyword.DeathtouchAbility;
@@ -41,6 +42,7 @@ import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.constants.Outcome;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@@ -140,21 +142,24 @@ public class CombatGroup implements Serializable, Copyable {
public void assignDamageToBlockers(boolean first, Game game) {
if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) {
- if (blockers.isEmpty()) {
- unblockedDamage(first, game);
- } else {
- 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.getLogName() + " as though it weren't blocked?", null, game)) {
- blocked = false;
- unblockedDamage(first, game);
- }
- }
- if (blockers.size() == 1) {
- singleBlockerDamage(first, game);
+ Permanent attacker = game.getPermanent(attackers.get(0));
+ if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(attacker, attacker.getControllerId(), first, game, true)) {
+ if (blockers.isEmpty()) {
+ unblockedDamage(first, game);
+ return;
} else {
- multiBlockerDamage(first, game);
+ Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : attacker.getControllerId());
+ if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { // for handling creatures like Thorn Elemental
+ if (player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + attacker.getLogName() + " as though it weren't blocked?", null, game)) {
+ blocked = false;
+ unblockedDamage(first, game);
+ }
+ }
+ if (blockers.size() == 1) {
+ singleBlockerDamage(player, first, game);
+ } else {
+ multiBlockerDamage(player, first, game);
+ }
}
}
}
@@ -162,6 +167,18 @@ public class CombatGroup implements Serializable, Copyable {
public void assignDamageToAttackers(boolean first, Game game) {
if (!blockers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) {
+ // this should only come up if Butcher Orgg is granted the ability to block multiple blockers
+ boolean altDamageMethod = false;
+ for (UUID blockerId : blockers) {
+ Permanent blocker = game.getPermanent(blockerId);
+ if (assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) {
+ altDamageMethod = true;
+ }
+ }
+ if (altDamageMethod) {
+ // this could be necessary to remake in the future (banding with Butcher Orgg?)
+ return;
+ }
if (attackers.size() == 1) {
singleAttackerDamage(first, game);
} else {
@@ -226,7 +243,7 @@ public class CombatGroup implements Serializable, Copyable {
}
}
- private void singleBlockerDamage(boolean first, Game game) {
+ private void singleBlockerDamage(Player player, boolean first, Game game) {
//TODO: handle banding
Permanent blocker = game.getPermanent(blockers.get(0));
Permanent attacker = game.getPermanent(attackers.get(0));
@@ -244,13 +261,6 @@ public class CombatGroup implements Serializable, Copyable {
if (lethalDamage >= damage) {
blocker.markDamage(damage, attacker.getId(), game, true, true);
} else {
- Player player = game.getPlayer(attacker.getControllerId());
- for (Permanent defensiveFormation : game.getBattlefield().getAllActivePermanents(defendingPlayerId)) { // for handling Defensive Formation
- if (defensiveFormation.getAbilities().containsKey(ControllerAssignCombatDamageToBlockersAbility.getInstance().getId())) {
- player = game.getPlayer(defendingPlayerId);
- break;
- }
- }
int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game);
blocker.markDamage(damageAssigned, attacker.getId(), game, true, true);
damage -= damageAssigned;
@@ -264,27 +274,21 @@ public class CombatGroup implements Serializable, Copyable {
}
if (canDamage(blocker, first)) {
if (blocker.getBlocking() == 1) { // blocking several creatures handled separately
- attacker.markDamage(blockerDamage, blocker.getId(), game, true, true);
+ if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) {
+ attacker.markDamage(blockerDamage, blocker.getId(), game, true, true);
+ }
}
}
}
}
- private void multiBlockerDamage(boolean first, Game game) {
+ private void multiBlockerDamage(Player player, boolean first, Game game) {
//TODO: handle banding
Permanent attacker = game.getPermanent(attackers.get(0));
if (attacker == null) {
return;
}
- boolean oldRuleDamage = false;
- Player player = game.getPlayer(attacker.getControllerId());
- for (Permanent defensiveFormation : game.getBattlefield().getAllActivePermanents(defendingPlayerId)) { // for handling Defensive Formation
- if (defensiveFormation.getAbilities().containsKey(ControllerAssignCombatDamageToBlockersAbility.getInstance().getId())) {
- player = game.getPlayer(defendingPlayerId);
- oldRuleDamage = true;
- break;
- }
- }
+ boolean oldRuleDamage = (player.getId() == defendingPlayerId);
int damage = getDamageValueFromPermanent(attacker, game);
if (canDamage(attacker, first)) {
// must be set before attacker damage marking because of effects like Test of Faith
@@ -310,9 +314,13 @@ public class CombatGroup implements Serializable, Copyable {
lethalDamage = blocker.getToughness().getValue() - blocker.getDamage();
}
if (lethalDamage >= damage) {
- assigned.put(blockerId, damage);
- damage = 0;
- break;
+ if (!oldRuleDamage) {
+ assigned.put(blockerId, damage);
+ damage = 0;
+ break;
+ } else if (damage == 0) {
+ break;
+ }
}
int damageAssigned = 0;
if (!oldRuleDamage) {
@@ -337,7 +345,11 @@ public class CombatGroup implements Serializable, Copyable {
for (UUID blockerId : blockerOrder) {
Integer power = blockerPower.get(blockerId);
if (power != null) {
- attacker.markDamage(power, blockerId, game, true, true);
+ // might be missing canDamage condition?
+ Permanent blocker = game.getPermanent(blockerId);
+ if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) {
+ attacker.markDamage(power, blockerId, game, true, true);
+ }
}
}
for (Map.Entry entry : assigned.entrySet()) {
@@ -348,7 +360,76 @@ public class CombatGroup implements Serializable, Copyable {
for (UUID blockerId : blockerOrder) {
Permanent blocker = game.getPermanent(blockerId);
if (canDamage(blocker, first)) {
- attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true);
+ if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) {
+ attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true);
+ }
+ }
+ }
+ }
+ }
+
+ private void defendingPlayerAndOrDefendingCreaturesDividedDamage(Permanent attacker, Player player, boolean first, Game game, boolean isAttacking) {
+ // for handling Butcher Orgg
+ if (!((blocked && blockers.isEmpty() && isAttacking) || (attackers.isEmpty() && !isAttacking))) {
+ if (attacker == null) {
+ return;
+ }
+ int damage = getDamageValueFromPermanent(attacker, game);
+ if (canDamage(attacker, first)) {
+ // must be set before attacker damage marking because of effects like Test of Faith
+ Map blockerPower = new HashMap<>();
+ for (UUID blockerId : blockerOrder) {
+ Permanent blocker = game.getPermanent(blockerId);
+ if (canDamage(blocker, first)) {
+ if (blocker.getBlocking() == 1) { // blocking several creatures handled separately
+ blockerPower.put(blockerId, getDamageValueFromPermanent(blocker, game));
+ }
+ }
+ }
+ Map assigned = new HashMap<>();
+ for (Permanent defendingCreature : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, defendingPlayerId, game)) {
+ if (defendingCreature != null) {
+ if (!(damage > 0)) {
+ break;
+ }
+ int damageAssigned = 0;
+ damageAssigned = player.getAmount(0, damage, "Assign damage to " + defendingCreature.getName(), game);
+ assigned.put(defendingCreature.getId(), damageAssigned);
+ damage -= damageAssigned;
+ }
+ }
+ if (damage > 0) {
+ Player defendingPlayer = game.getPlayer(defendingPlayerId);
+ if (defendingPlayer.isInGame()) {
+ defendingPlayer.damage(damage, attacker.getId(), game, true, true);
+ }
+ }
+ if (isAttacking) {
+ for (UUID blockerId : blockerOrder) {
+ Integer power = blockerPower.get(blockerId);
+ if (power != null) {
+ // might be missing canDamage condition?
+ Permanent blocker = game.getPermanent(blockerId);
+ if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) {
+ attacker.markDamage(power, blockerId, game, true, true);
+ }
+ }
+ }
+ }
+ for (Map.Entry entry : assigned.entrySet()) {
+ Permanent defendingCreature = game.getPermanent(entry.getKey());
+ defendingCreature.markDamage(entry.getValue(), attacker.getId(), game, true, true);
+ }
+ } else {
+ if (isAttacking) {
+ for (UUID blockerId : blockerOrder) {
+ Permanent blocker = game.getPermanent(blockerId);
+ if (canDamage(blocker, first)) {
+ if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) {
+ attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true);
+ }
+ }
+ }
}
}
}
@@ -491,13 +572,7 @@ public class CombatGroup implements Serializable, Copyable {
if (blockers.isEmpty()) {
return;
}
- Player player = game.getPlayer(playerId);
- for (Permanent defensiveFormation : game.getBattlefield().getAllActivePermanents(defendingPlayerId)) { // for handling Defensive Formation
- if (defensiveFormation.getAbilities().containsKey(ControllerAssignCombatDamageToBlockersAbility.getInstance().getId())) {
- player = game.getPlayer(defendingPlayerId);
- break;
- }
- }
+ Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : playerId);
List blockerList = new ArrayList<>(blockers);
blockerOrder.clear();
while (player.canRespond()) {
@@ -720,4 +795,30 @@ public class CombatGroup implements Serializable, Copyable {
}
return false;
}
+
+ public boolean defenderControlsDefensiveFormation(Game game) {
+ // for handling Defensive Formation
+ for (Permanent defensiveFormation : game.getBattlefield().getAllActivePermanents(defendingPlayerId)) {
+ if (defensiveFormation.getAbilities().containsKey(ControllerAssignCombatDamageToBlockersAbility.getInstance().getId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(Permanent creature, UUID playerId, boolean first, Game game, boolean isAttacking) {
+ // for handling Butcher Orgg
+ if (creature.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) {
+ Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : playerId);
+ // 10/4/2004 If it is blocked but then all of its blockers are removed before combat damage is assigned, then it won’t be able to deal combat damage and you won’t be able to use its ability.
+ // (same principle should apply if it's blocking and its blocked attacker is removed from combat)
+ if (!((blocked && blockers.isEmpty() && isAttacking) || (attackers.isEmpty() && !isAttacking)) && canDamage(creature, first)) {
+ if (player.chooseUse(Outcome.Damage, "Do you wish to assign " + creature.getLogName() + "'s combat damage divided among defending player and/or any number of defending creatures?", null, game)) {
+ defendingPlayerAndOrDefendingCreaturesDividedDamage(creature, player, first, game, isAttacking);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java
index a5e5b9d59c1..95c27b3c634 100644
--- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java
+++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java
@@ -56,6 +56,7 @@ import mage.game.permanent.token.SquirrelToken;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.players.Player;
+import mage.util.CardUtil;
import mage.util.GameLog;
import mage.util.ThreadLocalStringBuilder;
@@ -887,7 +888,8 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
addCounters(CounterType.M1M1.createInstance(actualDamage), damageSourceAbility, game);
}
} else {
- this.damage += actualDamage;
+ // this.damage += actualDamage;
+ this.damage = CardUtil.addWithOverflowCheck(this.damage, actualDamage);
}
game.fireEvent(new DamagedCreatureEvent(objectId, sourceId, controllerId, actualDamage, combat));
return actualDamage;
diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java
index de7e06268aa..64c9fde58e0 100644
--- a/Mage/src/main/java/mage/players/PlayerImpl.java
+++ b/Mage/src/main/java/mage/players/PlayerImpl.java
@@ -1759,7 +1759,8 @@ public abstract class PlayerImpl implements Player, Serializable {
}
GameEvent event = new GameEvent(GameEvent.EventType.LOSE_LIFE, playerId, playerId, playerId, amount, atCombat);
if (!game.replaceEvent(event)) {
- this.life -= event.getAmount();
+ // this.life -= event.getAmount();
+ this.life = CardUtil.subtractWithOverflowCheck(this.life, event.getAmount());
if (!game.isSimulation()) {
game.informPlayers(this.getLogName() + " loses " + event.getAmount() + " life");
}
@@ -1788,7 +1789,10 @@ public abstract class PlayerImpl implements Player, Serializable {
}
GameEvent event = new GameEvent(GameEvent.EventType.GAIN_LIFE, playerId, playerId, playerId, amount, false);
if (!game.replaceEvent(event)) {
- this.life += event.getAmount();
+ // TODO: lock life at Integer.MAX_VALUE if reached, until it's set to a different amount
+ // (https://magic.wizards.com/en/articles/archive/news/unstable-faqawaslfaqpaftidawabiajtbt-2017-12-06 - "infinite" life total stays infinite no matter how much is gained or lost)
+ // this.life += event.getAmount();
+ this.life = CardUtil.addWithOverflowCheck(this.life, event.getAmount());
if (!game.isSimulation()) {
game.informPlayers(this.getLogName() + " gains " + event.getAmount() + " life");
}
diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java
index 301a26e83f2..bdc5e2a1b52 100644
--- a/Mage/src/main/java/mage/util/CardUtil.java
+++ b/Mage/src/main/java/mage/util/CardUtil.java
@@ -509,4 +509,24 @@ public final class CardUtil {
}
}
+ public static int addWithOverflowCheck(int base, int increment) {
+ long result = ((long) base) + increment;
+ if (result > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ } else if (result < Integer.MIN_VALUE) {
+ return Integer.MIN_VALUE;
+ }
+ return base + increment;
+ }
+
+ public static int subtractWithOverflowCheck(int base, int decrement) {
+ long result = ((long) base) - decrement;
+ if (result > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ } else if (result < Integer.MIN_VALUE) {
+ return Integer.MIN_VALUE;
+ }
+ return base - decrement;
+ }
+
}