From cad645e1c5588fbd127df6ab77ae5e95297fa511 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 14:54:14 +0100 Subject: [PATCH 001/142] Implemented Callous Oppressor --- .../src/mage/cards/c/CallousOppressor.java | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CallousOppressor.java 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..f9d9bb0d601 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CallousOppressor.java @@ -0,0 +1,160 @@ +/* + * 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.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ChosenSubtypePredicate; +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 OpponentChooseCreatureTypeEffect())); + + // {T}: Gain control of target creature that isn't of the chosen type for as long as Callous Oppressor remains tapped. + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that isn't of the chosen type"); + filter.add(Predicates.not(new ChosenSubtypePredicate(this.getId()))); + ConditionalContinuousEffect effect = new ConditionalContinuousEffect( + new GainControlTargetEffect(Duration.OneUse), + SourceTappedCondition.instance, + "Gain control of target creature for as long as Callous Oppressor remains tapped"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public CallousOppressor(final CallousOppressor card) { + super(card); + } + + @Override + public CallousOppressor copy() { + return new CallousOppressor(this); + } +} + +class OpponentChooseCreatureTypeEffect extends OneShotEffect { + + public OpponentChooseCreatureTypeEffect() { + super(Outcome.Benefit); + staticText = "an opponent chooses a creature type"; + } + + public OpponentChooseCreatureTypeEffect(final OpponentChooseCreatureTypeEffect 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 false; + } + + @Override + public OpponentChooseCreatureTypeEffect copy() { + return new OpponentChooseCreatureTypeEffect(this); + } + +} From f7b747bcdb17357d449d6af2c3068cddd467789b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 14:54:56 +0100 Subject: [PATCH 002/142] Implemented Doom Cannon --- Mage.Sets/src/mage/cards/d/DoomCannon.java | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DoomCannon.java 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..33ae3a9b366 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DoomCannon.java @@ -0,0 +1,79 @@ +/* + * 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.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.ChosenSubtypePredicate; +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. + FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a creature of the chosen type"); + filter.add(new ChosenSubtypePredicate(this.getId())); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new GenericManaCost(3)); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public DoomCannon(final DoomCannon card) { + super(card); + } + + @Override + public DoomCannon copy() { + return new DoomCannon(this); + } +} From a703e52939bd6d0491c71fd6b8a05459439d974d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 14:55:54 +0100 Subject: [PATCH 003/142] Implemented Entrails Feaster --- .../src/mage/cards/e/EntrailsFeaster.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EntrailsFeaster.java 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..f796d7ba7eb --- /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.moveCardToExileWithInfo(cardChosen, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); + if (sourceObject != null) { + sourceObject.getCounters(game).addCounter(CounterType.P1P1.createInstance()); + game.informPlayers(controller.getLogName() + " puts a +1/+1 counter on " + sourceObject.getName()); + } + } + } else if (sourceObject != null) { + sourceObject.tap(game); + } + } else if (sourceObject != null) { + sourceObject.tap(game); + } + return true; + } + return false; + } +} From c98c638e179aa48d06fb48ad588249cc0808c6ed Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 14:56:55 +0100 Subject: [PATCH 004/142] Implemented Kamahl's Summons --- .../src/mage/cards/k/KamahlsSummons.java | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KamahlsSummons.java 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; + } +} From d1bed7a5329a7e86737b322a7a372baee8100d30 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 14:58:07 +0100 Subject: [PATCH 005/142] Implemented Shieldmage Elder --- .../src/mage/cards/s/ShieldmageElder.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShieldmageElder.java 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); + } +} From dcce07cfdcf1e1f9a7f0de0ebdfc3ed739500919 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 15:00:09 +0100 Subject: [PATCH 006/142] Implemented Butcher Orgg --- .../ControllerDivideCombatDamageAbility.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Mage/src/main/java/mage/abilities/common/ControllerDivideCombatDamageAbility.java 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; + } + +} From 0e60bcb7fa2155644ab6914c2590caeaba402cec Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 15:00:27 +0100 Subject: [PATCH 007/142] Implemented Butcher Orgg --- Mage.Sets/src/mage/cards/b/ButcherOrgg.java | 63 +++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/ButcherOrgg.java 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); + } +} From c3747b353a3cb056786e9ebf4ab251c8b60af4eb Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 15:03:04 +0100 Subject: [PATCH 008/142] Implemented cards --- Mage.Sets/src/mage/sets/Onslaught.java | 6 ++++++ 1 file changed, 6 insertions(+) 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)); From 47ef2a4ce421d8fbc8edbdc298fb278dae7c0179 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 16:31:36 +0100 Subject: [PATCH 009/142] Implemented Butcher Orgg (partially) Option to divide damage while being a blocker doesn't work for some reason --- .../java/mage/game/combat/CombatGroup.java | 103 +++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 44a4e52f383..ffa79a34737 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,12 +142,31 @@ public class CombatGroup implements Serializable, Copyable { public void assignDamageToBlockers(boolean first, Game game) { if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { + Permanent attacker = game.getPermanent(attackers.get(0)); + if (attacker.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) { // for handling Butcher Orgg + 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; + } + } + if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + attacker.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { + butcherOrggDamage(attacker, player, first, game); + return; + } + } if (blockers.isEmpty()) { unblockedDamage(first, game); } else { - Permanent attacker = game.getPermanent(attackers.get(0)); - if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { + if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { // for handling creatures like Thorn Elemental 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; + } + } 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); @@ -162,6 +183,28 @@ public class CombatGroup implements Serializable, Copyable { public void assignDamageToAttackers(boolean first, Game game) { if (!blockers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { + // this never comes up for some reason + boolean altDamageMethod = false; + for (UUID blockerId : blockers) { + Permanent blocker = game.getPermanent(blockerId); + if (blocker.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) { // for handling Butcher Orgg + Player player = game.getPlayer(blocker.getControllerId()); + for (Permanent defensiveFormation : game.getBattlefield().getAllActivePermanents(defendingPlayerId)) { // for handling Defensive Formation + if (defensiveFormation.getAbilities().containsKey(ControllerAssignCombatDamageToBlockersAbility.getInstance().getId())) { + player = game.getPlayer(defendingPlayerId); + break; + } + } + if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + blocker.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { Permanent attacker = game.getPermanent(attackers.get(0)); + butcherOrggDamage(blocker, player, first, game); + altDamageMethod = true; + continue; + } + } + } + if (altDamageMethod) { + return; + } if (attackers.size() == 1) { singleAttackerDamage(first, game); } else { @@ -226,6 +269,62 @@ public class CombatGroup implements Serializable, Copyable { } } + private void butcherOrggDamage(Permanent attacker, Player player, boolean first, Game game) { + if (!(blocked && blockers.isEmpty()) && (!first || hasFirstOrDoubleStrike(game))) { + 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) { + defenderDamage(attacker, damage, game); + } + // possibly remove? + for (UUID blockerId : blockerOrder) { + Integer power = blockerPower.get(blockerId); + if (power != null) { + // might be missing canDamage condition? + 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 { + // possibly remove? + for (UUID blockerId : blockerOrder) { + Permanent blocker = game.getPermanent(blockerId); + if (canDamage(blocker, first)) { + attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true); + } + } + } + } + } + private void singleBlockerDamage(boolean first, Game game) { //TODO: handle banding Permanent blocker = game.getPermanent(blockers.get(0)); From b48c37ea8f7e373280fa24426e9caf8a09371c1f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 17:02:49 +0100 Subject: [PATCH 010/142] Defensive Formation slight cleanup --- .../java/mage/game/combat/CombatGroup.java | 66 +++++++------------ 1 file changed, 25 insertions(+), 41 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index ffa79a34737..8c164d0b486 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -144,13 +144,7 @@ public class CombatGroup implements Serializable, Copyable { if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { Permanent attacker = game.getPermanent(attackers.get(0)); if (attacker.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) { // for handling Butcher Orgg - 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; - } - } + Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : attacker.getControllerId()); if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + attacker.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { butcherOrggDamage(attacker, player, first, game); return; @@ -160,13 +154,7 @@ public class CombatGroup implements Serializable, Copyable { unblockedDamage(first, game); } else { if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { // for handling creatures like Thorn Elemental - 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; - } - } + Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : 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); @@ -188,13 +176,7 @@ public class CombatGroup implements Serializable, Copyable { for (UUID blockerId : blockers) { Permanent blocker = game.getPermanent(blockerId); if (blocker.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) { // for handling Butcher Orgg - Player player = game.getPlayer(blocker.getControllerId()); - 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 : blocker.getControllerId()); // the difference should only rarely come up if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + blocker.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { Permanent attacker = game.getPermanent(attackers.get(0)); butcherOrggDamage(blocker, player, first, game); altDamageMethod = true; @@ -343,13 +325,7 @@ 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; - } - } + Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : attacker.getControllerId()); int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); blocker.markDamage(damageAssigned, attacker.getId(), game, true, true); damage -= damageAssigned; @@ -377,12 +353,9 @@ public class CombatGroup implements Serializable, Copyable { } 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; - } + if (defenderControlsDefensiveFormation(game)) { + player = game.getPlayer(defendingPlayerId); + oldRuleDamage = true; } int damage = getDamageValueFromPermanent(attacker, game); if (canDamage(attacker, first)) { @@ -590,13 +563,14 @@ 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); + //~ 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; + //~ } + //~ } List blockerList = new ArrayList<>(blockers); blockerOrder.clear(); while (player.canRespond()) { @@ -819,4 +793,14 @@ 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; + } } From 16513408fce9fe54e6f5f9d56c9f859c2bccf838 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 17:05:30 +0100 Subject: [PATCH 011/142] Cleanup #2 --- Mage/src/main/java/mage/game/combat/CombatGroup.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 8c164d0b486..9cdf03ebf25 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -564,13 +564,6 @@ public class CombatGroup implements Serializable, Copyable { return; } Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : playerId); - //~ 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; - //~ } - //~ } List blockerList = new ArrayList<>(blockers); blockerOrder.clear(); while (player.canRespond()) { From edd07d4f80443df5edd68f0beb3c676ad060a287 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 19:46:13 +0100 Subject: [PATCH 012/142] Implemented Butcher Orgg (the missing bits) --- .../java/mage/game/combat/CombatGroup.java | 81 ++++++++++++------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 9cdf03ebf25..eabeb9bbcc2 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -9,7 +9,7 @@ * * 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. + * provided with the distribution.i * * 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 @@ -143,12 +143,9 @@ public class CombatGroup implements Serializable, Copyable { public void assignDamageToBlockers(boolean first, Game game) { if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { Permanent attacker = game.getPermanent(attackers.get(0)); - if (attacker.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) { // for handling Butcher Orgg - Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : attacker.getControllerId()); - if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + attacker.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { - butcherOrggDamage(attacker, player, first, game); - return; - } + if (isButcherOrgg(attacker, attacker.getControllerId(), first, game, true)) { + game.informPlayers("test one"); + return; } if (blockers.isEmpty()) { unblockedDamage(first, game); @@ -171,20 +168,17 @@ public class CombatGroup implements Serializable, Copyable { public void assignDamageToAttackers(boolean first, Game game) { if (!blockers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { - // this never comes up for some reason + // this should only come up if Butcher Orgg is granted the ability to block multiple blockers - warning: untested boolean altDamageMethod = false; for (UUID blockerId : blockers) { Permanent blocker = game.getPermanent(blockerId); - if (blocker.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) { // for handling Butcher Orgg - Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : blocker.getControllerId()); // the difference should only rarely come up - if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + blocker.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { Permanent attacker = game.getPermanent(attackers.get(0)); - butcherOrggDamage(blocker, player, first, game); - altDamageMethod = true; - continue; - } + if (isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + game.informPlayers("test two"); + altDamageMethod = true; } } if (altDamageMethod) { + // this could be necessary to remake in the future (banding with Butcher Orgg?) return; } if (attackers.size() == 1) { @@ -251,7 +245,7 @@ public class CombatGroup implements Serializable, Copyable { } } - private void butcherOrggDamage(Permanent attacker, Player player, boolean first, Game game) { + private void butcherOrggDamage(Permanent attacker, Player player, boolean first, Game game, boolean isAttacking) { if (!(blocked && blockers.isEmpty()) && (!first || hasFirstOrDoubleStrike(game))) { if (attacker == null) { return; @@ -283,12 +277,16 @@ public class CombatGroup implements Serializable, Copyable { if (damage > 0) { defenderDamage(attacker, damage, game); } - // possibly remove? - for (UUID blockerId : blockerOrder) { - Integer power = blockerPower.get(blockerId); - if (power != null) { - // might be missing canDamage condition? - attacker.markDamage(power, blockerId, 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 (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + attacker.markDamage(power, blockerId, game, true, true); + } + } } } for (Map.Entry entry : assigned.entrySet()) { @@ -296,11 +294,14 @@ public class CombatGroup implements Serializable, Copyable { defendingCreature.markDamage(entry.getValue(), attacker.getId(), game, true, true); } } else { - // possibly remove? - for (UUID blockerId : blockerOrder) { - Permanent blocker = game.getPermanent(blockerId); - if (canDamage(blocker, first)) { - attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true); + if (isAttacking) { + for (UUID blockerId : blockerOrder) { + Permanent blocker = game.getPermanent(blockerId); + if (canDamage(blocker, first)) { + if (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true); + } + } } } } @@ -339,7 +340,9 @@ 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 (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + attacker.markDamage(blockerDamage, blocker.getId(), game, true, true); + } } } } @@ -409,7 +412,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 (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + attacker.markDamage(power, blockerId, game, true, true); + } } } for (Map.Entry entry : assigned.entrySet()) { @@ -420,7 +427,9 @@ 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 (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true); + } } } } @@ -796,4 +805,16 @@ public class CombatGroup implements Serializable, Copyable { } return false; } + + public boolean isButcherOrgg(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); + if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + creature.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { + butcherOrggDamage(creature, player, first, game, isAttacking); + return true; + } + } + return false; + } } From c6e69868faa84f5ec3f33df34ff4d7764471cd56 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 19:50:06 +0100 Subject: [PATCH 013/142] Test message cleanup --- Mage/src/main/java/mage/game/combat/CombatGroup.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index eabeb9bbcc2..403aab9154d 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -9,7 +9,7 @@ * * 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.i + * 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 @@ -144,7 +144,6 @@ public class CombatGroup implements Serializable, Copyable { if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { Permanent attacker = game.getPermanent(attackers.get(0)); if (isButcherOrgg(attacker, attacker.getControllerId(), first, game, true)) { - game.informPlayers("test one"); return; } if (blockers.isEmpty()) { @@ -173,7 +172,6 @@ public class CombatGroup implements Serializable, Copyable { for (UUID blockerId : blockers) { Permanent blocker = game.getPermanent(blockerId); if (isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { - game.informPlayers("test two"); altDamageMethod = true; } } From 5fec04935d11fd2559609cb0f27ebbe68e6ad2df Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 20:31:54 +0100 Subject: [PATCH 014/142] Optimization edit for assignDamageToBlockers --- Mage/src/main/java/mage/game/combat/CombatGroup.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 403aab9154d..d4a5bf7c4d6 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -142,13 +142,12 @@ public class CombatGroup implements Serializable, Copyable { public void assignDamageToBlockers(boolean first, Game game) { if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { - Permanent attacker = game.getPermanent(attackers.get(0)); - if (isButcherOrgg(attacker, attacker.getControllerId(), first, game, true)) { - return; - } if (blockers.isEmpty()) { unblockedDamage(first, game); - } else { + return; + } + Permanent attacker = game.getPermanent(attackers.get(0)); + if (!isButcherOrgg(attacker, attacker.getControllerId(), first, game, true)) { if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { // for handling creatures like Thorn Elemental Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : attacker.getControllerId()); if (player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + attacker.getLogName() + " as though it weren't blocked?", null, game)) { From e1fdc3093a5f041930e6091b0d22ee85a8455030 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 6 Dec 2017 21:30:33 +0100 Subject: [PATCH 015/142] Some other edits + small fix for Defensive Formation --- .../java/mage/game/combat/CombatGroup.java | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index d4a5bf7c4d6..ba67ca8cfc0 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -142,23 +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); - return; - } Permanent attacker = game.getPermanent(attackers.get(0)); if (!isButcherOrgg(attacker, attacker.getControllerId(), first, game, true)) { - if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { // for handling creatures like Thorn Elemental - Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : 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); + 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); + } } } } @@ -305,7 +306,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)); @@ -323,7 +324,6 @@ public class CombatGroup implements Serializable, Copyable { if (lethalDamage >= damage) { blocker.markDamage(damage, attacker.getId(), game, true, true); } else { - Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : attacker.getControllerId()); int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); blocker.markDamage(damageAssigned, attacker.getId(), game, true, true); damage -= damageAssigned; @@ -345,18 +345,13 @@ public class CombatGroup implements Serializable, Copyable { } } - 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()); - if (defenderControlsDefensiveFormation(game)) { - player = game.getPlayer(defendingPlayerId); - oldRuleDamage = true; - } + 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 @@ -382,9 +377,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) { From d8daec11d4239a1dd0f3ad9d7513d72c31aea3ae Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 7 Dec 2017 01:04:31 +0100 Subject: [PATCH 016/142] Fixed Butcher Orgg handling attackers/blockers leaving combat --- Mage/src/main/java/mage/game/combat/CombatGroup.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index ba67ca8cfc0..50f1d778594 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -244,7 +244,7 @@ public class CombatGroup implements Serializable, Copyable { } private void butcherOrggDamage(Permanent attacker, Player player, boolean first, Game game, boolean isAttacking) { - if (!(blocked && blockers.isEmpty()) && (!first || hasFirstOrDoubleStrike(game))) { + if (!((blocked && blockers.isEmpty() && isAttacking) || (attackers.isEmpty() && !isAttacking)) && (!first || hasFirstOrDoubleStrike(game))) { if (attacker == null) { return; } @@ -806,9 +806,12 @@ public class CombatGroup implements Serializable, Copyable { // for handling Butcher Orgg if (creature.getAbilities().containsKey(ControllerDivideCombatDamageAbility.getInstance().getId())) { Player player = game.getPlayer(defenderControlsDefensiveFormation(game) ? defendingPlayerId : playerId); - if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + creature.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { - butcherOrggDamage(creature, player, first, game, isAttacking); - return true; + // 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. + if (!((blocked && blockers.isEmpty() && isAttacking) || (attackers.isEmpty() && !isAttacking))) { + if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + creature.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { + butcherOrggDamage(creature, player, first, game, isAttacking); + return true; + } } } return false; From 230233659b3c19fa9578b7d3fa65762da47e5d0f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 7 Dec 2017 11:13:27 +0100 Subject: [PATCH 017/142] Some naming changes, Butcher Orgg first strike fix --- .../java/mage/game/combat/CombatGroup.java | 151 +++++++++--------- 1 file changed, 78 insertions(+), 73 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 50f1d778594..7ad9391ceac 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -143,7 +143,7 @@ public class CombatGroup implements Serializable, Copyable { public void assignDamageToBlockers(boolean first, Game game) { if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { Permanent attacker = game.getPermanent(attackers.get(0)); - if (!isButcherOrgg(attacker, attacker.getControllerId(), first, game, true)) { + if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(attacker, attacker.getControllerId(), first, game, true)) { if (blockers.isEmpty()) { unblockedDamage(first, game); return; @@ -167,11 +167,11 @@ 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 - warning: untested + // 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 (isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + if (assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) { altDamageMethod = true; } } @@ -243,69 +243,6 @@ public class CombatGroup implements Serializable, Copyable { } } - private void butcherOrggDamage(Permanent attacker, Player player, boolean first, Game game, boolean isAttacking) { - if (!((blocked && blockers.isEmpty() && isAttacking) || (attackers.isEmpty() && !isAttacking)) && (!first || hasFirstOrDoubleStrike(game))) { - 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) { - defenderDamage(attacker, damage, game); - } - 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 (!isButcherOrgg(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 (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { - attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true); - } - } - } - } - } - } - } - private void singleBlockerDamage(Player player, boolean first, Game game) { //TODO: handle banding Permanent blocker = game.getPermanent(blockers.get(0)); @@ -337,7 +274,7 @@ public class CombatGroup implements Serializable, Copyable { } if (canDamage(blocker, first)) { if (blocker.getBlocking() == 1) { // blocking several creatures handled separately - if (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) { attacker.markDamage(blockerDamage, blocker.getId(), game, true, true); } } @@ -410,7 +347,7 @@ public class CombatGroup implements Serializable, Copyable { if (power != null) { // might be missing canDamage condition? Permanent blocker = game.getPermanent(blockerId); - if (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) { attacker.markDamage(power, blockerId, game, true, true); } } @@ -423,7 +360,7 @@ public class CombatGroup implements Serializable, Copyable { for (UUID blockerId : blockerOrder) { Permanent blocker = game.getPermanent(blockerId); if (canDamage(blocker, first)) { - if (!isButcherOrgg(blocker, blocker.getControllerId(), first, game, false)) { + if (!assignsDefendingPlayerAndOrDefendingCreaturesDividedDamage(blocker, blocker.getControllerId(), first, game, false)) { attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true); } } @@ -431,6 +368,73 @@ public class CombatGroup implements Serializable, Copyable { } } + 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); + } + } + } + } + } + } + } + /** * Damages attacking creatures by a creature that blocked several ones * Damages only attackers as blocker was damage in @@ -802,14 +806,15 @@ public class CombatGroup implements Serializable, Copyable { return false; } - public boolean isButcherOrgg(Permanent creature, UUID playerId, boolean first, Game game, boolean isAttacking) { + 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. - if (!((blocked && blockers.isEmpty() && isAttacking) || (attackers.isEmpty() && !isAttacking))) { - if (player.chooseUse(Outcome.Damage, "Do you wish to divide " + creature.getLogName() + "'s combat damage among defending player and/or any number of defending creatures?", null, game)) { - butcherOrggDamage(creature, player, first, game, isAttacking); + // (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; } } From b16f50cd7279f8e6bee684c90ad974abc9166610 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 7 Dec 2017 21:28:42 +0100 Subject: [PATCH 018/142] Entrails Feaster fixes --- Mage.Sets/src/mage/cards/e/EntrailsFeaster.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/e/EntrailsFeaster.java b/Mage.Sets/src/mage/cards/e/EntrailsFeaster.java index f796d7ba7eb..a446dd82ad2 100644 --- a/Mage.Sets/src/mage/cards/e/EntrailsFeaster.java +++ b/Mage.Sets/src/mage/cards/e/EntrailsFeaster.java @@ -105,10 +105,10 @@ class EntrailsFeasterEffect extends OneShotEffect { if (controller.choose(Outcome.Exile, target, source.getId(), game)) { Card cardChosen = game.getCard(target.getFirstTarget()); if (cardChosen != null) { - controller.moveCardToExileWithInfo(cardChosen, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); + 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.getName()); + game.informPlayers(controller.getLogName() + " puts a +1/+1 counter on " + sourceObject.getLogName()); } } } else if (sourceObject != null) { From 73504fd3c1c9ab3e06e887bae8598fbfb4689761 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 7 Dec 2017 21:58:30 +0100 Subject: [PATCH 019/142] Implemented Glyph of Life --- Mage.Sets/src/mage/cards/g/GlyphOfLife.java | 148 ++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GlyphOfLife.java 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; + } + +} From 887fec53019b6a520132c2f6638a91b0ac4b3f9c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 7 Dec 2017 21:59:42 +0100 Subject: [PATCH 020/142] Implemented Glyph of Life --- Mage.Sets/src/mage/sets/Legends.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 53bd34f1b5b..b180b62b5c4 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -129,6 +129,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)); From 33cdada012448cba44566f1e0aa19249089713e7 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 7 Dec 2017 22:46:24 +0100 Subject: [PATCH 021/142] Callous Oppressor fix --- .../src/mage/cards/c/CallousOppressor.java | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CallousOppressor.java b/Mage.Sets/src/mage/cards/c/CallousOppressor.java index f9d9bb0d601..63acbd3c2e1 100644 --- a/Mage.Sets/src/mage/cards/c/CallousOppressor.java +++ b/Mage.Sets/src/mage/cards/c/CallousOppressor.java @@ -51,8 +51,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.ChosenSubtypePredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -76,17 +74,15 @@ public class CallousOppressor extends CardImpl { this.addAbility(new SkipUntapOptionalAbility()); // As Callous Oppressor enters the battlefield, an opponent chooses a creature type. - this.addAbility(new AsEntersBattlefieldAbility(new OpponentChooseCreatureTypeEffect())); + 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. - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that isn't of the chosen type"); - filter.add(Predicates.not(new ChosenSubtypePredicate(this.getId()))); ConditionalContinuousEffect effect = new ConditionalContinuousEffect( new GainControlTargetEffect(Duration.OneUse), SourceTappedCondition.instance, - "Gain control of target creature for as long as Callous Oppressor remains tapped"); + "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(filter)); + ability.addTarget(new TargetCreaturePermanent(new CallousOppressorFilter())); this.addAbility(ability); } @@ -100,14 +96,43 @@ public class CallousOppressor extends CardImpl { } } -class OpponentChooseCreatureTypeEffect extends OneShotEffect { +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; + } + +} - public OpponentChooseCreatureTypeEffect() { +class CallousOppressorChooseCreatureTypeEffect extends OneShotEffect { + + public CallousOppressorChooseCreatureTypeEffect() { super(Outcome.Benefit); staticText = "an opponent chooses a creature type"; } - public OpponentChooseCreatureTypeEffect(final OpponentChooseCreatureTypeEffect effect) { + public CallousOppressorChooseCreatureTypeEffect(final CallousOppressorChooseCreatureTypeEffect effect) { super(effect); } @@ -147,14 +172,15 @@ class OpponentChooseCreatureTypeEffect extends OneShotEffect { if (mageObject instanceof Permanent) { ((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); } + return true; } } return false; } @Override - public OpponentChooseCreatureTypeEffect copy() { - return new OpponentChooseCreatureTypeEffect(this); + public CallousOppressorChooseCreatureTypeEffect copy() { + return new CallousOppressorChooseCreatureTypeEffect(this); } } From a2840cd148ae203991498e3ed86bbc9fa0203e94 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 7 Dec 2017 22:49:18 +0100 Subject: [PATCH 022/142] Doom Cannon fix --- Mage.Sets/src/mage/cards/d/DoomCannon.java | 36 +++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DoomCannon.java b/Mage.Sets/src/mage/cards/d/DoomCannon.java index 33ae3a9b366..383bf31b35b 100644 --- a/Mage.Sets/src/mage/cards/d/DoomCannon.java +++ b/Mage.Sets/src/mage/cards/d/DoomCannon.java @@ -39,10 +39,12 @@ 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.filter.predicate.mageobject.ChosenSubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreatureOrPlayer; @@ -59,11 +61,9 @@ public class DoomCannon extends CardImpl { 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. - FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a creature of the chosen type"); - filter.add(new ChosenSubtypePredicate(this.getId())); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(new DoomCannonFilter()))); ability.addTarget(new TargetCreatureOrPlayer()); this.addAbility(ability); } @@ -77,3 +77,31 @@ public class DoomCannon extends CardImpl { 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; + } + +} From 2f9536e11a94305ea889351db8df64c58bae966b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 11 Dec 2017 17:20:34 +0100 Subject: [PATCH 023/142] Implemented Ashnod's Cylix --- Mage.Sets/src/mage/cards/a/AshnodsCylix.java | 125 +++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AshnodsCylix.java 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; + } +} From e80217304b6cc47ba935cff06a1f9c8f706acc29 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 11 Dec 2017 17:21:23 +0100 Subject: [PATCH 024/142] Implemented Soldevi Steam Beast --- .../src/mage/cards/s/SoldeviSteamBeast.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoldeviSteamBeast.java 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); + } +} From 927692d51448f3845d5252fa3ff61af95fb76440 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 11 Dec 2017 17:21:59 +0100 Subject: [PATCH 025/142] Implemented Stromgald Spy --- Mage.Sets/src/mage/cards/s/StromgaldSpy.java | 106 +++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StromgaldSpy.java 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); + } +} From 67983d755f332a56c69315228bb6dcdad99aab49 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 11 Dec 2017 17:22:58 +0100 Subject: [PATCH 026/142] Implemented Ashnod's Cylix --- Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 1 file changed, 1 insertion(+) 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)); From e4215cc1efb492d6eddc3a909b174237fa9ca00f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 11 Dec 2017 17:24:45 +0100 Subject: [PATCH 027/142] Implemented cards --- Mage.Sets/src/mage/sets/Alliances.java | 4 ++++ 1 file changed, 4 insertions(+) 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)); From dca59519341176865ccfc776541e78dcd4407dc0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 13 Dec 2017 11:55:31 +0100 Subject: [PATCH 028/142] Implemented Seeker --- Mage.Sets/src/mage/cards/s/Seeker.java | 91 ++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Seeker.java 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); + } +} From 92f9d5e9f29e6a4820e33227f08613485572c9bd Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 13 Dec 2017 11:56:32 +0100 Subject: [PATCH 029/142] Implemented Seeker --- Mage.Sets/src/mage/sets/Legends.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index b180b62b5c4..849c78e2fec 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -233,6 +233,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)); From af19f49710e5b06a9aeb66966aaa972e47199929 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 13 Dec 2017 11:57:31 +0100 Subject: [PATCH 030/142] Implemented Seeker --- Mage.Sets/src/mage/sets/FourthEdition.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/FourthEdition.java b/Mage.Sets/src/mage/sets/FourthEdition.java index 263ec33b0d7..126a1999819 100644 --- a/Mage.Sets/src/mage/sets/FourthEdition.java +++ b/Mage.Sets/src/mage/sets/FourthEdition.java @@ -319,6 +319,7 @@ public class FourthEdition extends ExpansionSet { cards.add(new SetCardInfo("Scavenging Ghoul", 43, Rarity.UNCOMMON, mage.cards.s.ScavengingGhoul.class)); cards.add(new SetCardInfo("Scryb Sprites", 154, Rarity.COMMON, mage.cards.s.ScrybSprites.class)); cards.add(new SetCardInfo("Sea Serpent", 98, Rarity.COMMON, mage.cards.s.SeaSerpent.class)); + cards.add(new SetCardInfo("Seeker", 299, Rarity.COMMON, mage.cards.s.Seeker.class)); cards.add(new SetCardInfo("Segovian Leviathan", 99, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); cards.add(new SetCardInfo("Sengir Vampire", 44, Rarity.UNCOMMON, mage.cards.s.SengirVampire.class)); cards.add(new SetCardInfo("Serra Angel", 300, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class)); From b77d67524eb7a0a03072f504e84b882ab8c85d52 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:53:47 +0100 Subject: [PATCH 031/142] Implemented Flint Golem --- Mage.Sets/src/mage/cards/f/FlintGolem.java | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FlintGolem.java 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; + } +} From be4dcf41bdecb3b3a146e3bb21b172b7468a6b1f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:54:27 +0100 Subject: [PATCH 032/142] Implemented Fog Patch --- Mage.Sets/src/mage/cards/f/FogPatch.java | 103 +++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FogPatch.java 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; + } +} From b71976c124adffd0b169e002b86269a3efe94c48 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:55:12 +0100 Subject: [PATCH 033/142] Implemented Harvest Mage --- Mage.Sets/src/mage/cards/h/HarvestMage.java | 132 ++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HarvestMage.java 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; + } +} From f54b7fd07f77831316d74f38a45acc0e5bd4d263 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:55:54 +0100 Subject: [PATCH 034/142] Implemented Mana Cache --- Mage.Sets/src/mage/cards/m/ManaCache.java | 148 ++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/ManaCache.java 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."; + } +} From 22cfd70abbbe3dcf66ed15fa6095f324e704339d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:56:27 +0100 Subject: [PATCH 035/142] Implemented Mogg Toady --- Mage.Sets/src/mage/cards/m/MoggToady.java | 150 ++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MoggToady.java 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()); + } +} From 7a3a1fd20fa63ed1204232f93b8484d183c2c459 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:57:11 +0100 Subject: [PATCH 036/142] Implemented Mossdog --- Mage.Sets/src/mage/cards/m/Mossdog.java | 103 ++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/Mossdog.java 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}."; + } +} From 83d71a46cb0c1915e69947670ebd91522418a2cb Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:58:03 +0100 Subject: [PATCH 037/142] Implemented Rupture --- Mage.Sets/src/mage/cards/r/Rupture.java | 116 ++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/Rupture.java 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); + } +} From 4e82e2110fa147210055b7c4bfb0862f27e43db3 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:59:04 +0100 Subject: [PATCH 038/142] Implemented Sivvi's Valor --- Mage.Sets/src/mage/cards/s/SivvisValor.java | 140 ++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SivvisValor.java 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; + } +} From b0349ba6cae7b5277be602b2aa6d81f83900dc2f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 15:59:45 +0100 Subject: [PATCH 039/142] Implemented Topple --- Mage.Sets/src/mage/cards/t/Topple.java | 129 +++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/Topple.java 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); + } +} From c4094d07494227905877f8d93ea9dc73ff9ce064 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 16:00:28 +0100 Subject: [PATCH 040/142] Implemented Wild Mammoth --- Mage.Sets/src/mage/cards/w/WildMammoth.java | 139 ++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WildMammoth.java 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..bd0f5bf9083 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WildMammoth.java @@ -0,0 +1,139 @@ +/* + * 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; + } + } + } + } + + 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; + + } +} From 1ed70db679f726ed5eea06637dcf3861ff1dca33 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 16:01:05 +0100 Subject: [PATCH 041/142] Implemented cards --- Mage.Sets/src/mage/sets/Nemesis.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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)); } } From d0691d8d95399f9de8b0d9430f23f7b90452610d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 16 Dec 2017 20:01:32 +0100 Subject: [PATCH 042/142] Tiny edit --- Mage.Sets/src/mage/cards/w/WildMammoth.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/cards/w/WildMammoth.java b/Mage.Sets/src/mage/cards/w/WildMammoth.java index bd0f5bf9083..3deee0822d3 100644 --- a/Mage.Sets/src/mage/cards/w/WildMammoth.java +++ b/Mage.Sets/src/mage/cards/w/WildMammoth.java @@ -120,6 +120,7 @@ class WildMammothEffect extends OneShotEffect { newController = player; } else { tie = true; + break; } } } From 982c17892151c9226209bde038db94b080f03c72 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 14:46:24 +0100 Subject: [PATCH 043/142] Added DoUnlessTargetPlayerOrTargetsControllerPaysEffect --- ...etPlayerOrTargetsControllerPaysEffect.java | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java 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..12d698b5274 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java @@ -0,0 +1,158 @@ +/* + * 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 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) { + super(Outcome.Detriment); + this.executingEffects.add(effect); + 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(); + 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(source.getFirstTarget()); + Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + 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); + } + } + } + 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); + } +} From 8539ffc92835e4d6276ef04ce5486b95cc6a4390 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 14:48:06 +0100 Subject: [PATCH 044/142] Implemented Excise --- Mage.Sets/src/mage/cards/e/Excise.java | 68 ++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/Excise.java 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); + } +} From 23b7fb775a926a9afa44623679bdaa3251997db4 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 14:50:30 +0100 Subject: [PATCH 045/142] Implemented Flay --- Mage.Sets/src/mage/cards/f/Flay.java | 65 ++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/Flay.java 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); + } +} From 7d043fc6e4c2bcfc02e48d424d0bf8d7116d7c28 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 14:51:24 +0100 Subject: [PATCH 046/142] Implemented Rhystic Deluge --- Mage.Sets/src/mage/cards/RhysticDeluge.java | 66 +++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/RhysticDeluge.java diff --git a/Mage.Sets/src/mage/cards/RhysticDeluge.java b/Mage.Sets/src/mage/cards/RhysticDeluge.java new file mode 100644 index 00000000000..4434da3ec3b --- /dev/null +++ b/Mage.Sets/src/mage/cards/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); + } +} From 23e33b41e13dee95cde5ec048a14aa8e28b005a2 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 14:51:43 +0100 Subject: [PATCH 047/142] Moved Rhystic Deluge --- Mage.Sets/src/mage/cards/{ => r}/RhysticDeluge.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Mage.Sets/src/mage/cards/{ => r}/RhysticDeluge.java (100%) diff --git a/Mage.Sets/src/mage/cards/RhysticDeluge.java b/Mage.Sets/src/mage/cards/r/RhysticDeluge.java similarity index 100% rename from Mage.Sets/src/mage/cards/RhysticDeluge.java rename to Mage.Sets/src/mage/cards/r/RhysticDeluge.java From 36052f513d5d4f4c6c2840403d8c61161bf47b4b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 14:52:13 +0100 Subject: [PATCH 048/142] Implemented Rhystic Scrying --- .../src/mage/cards/r/RhysticScrying.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RhysticScrying.java 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..5b19673103a --- /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(3); + // 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); + } +} From 88bbf8d91717a610b2b5476b6979ecb95846cf2e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 15:49:00 +0100 Subject: [PATCH 049/142] Implemented Rhystic Shield --- Mage.Sets/src/mage/cards/r/RhysticShield.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RhysticShield.java 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); + } +} From 848a9993a69a100ac459ad2d3c7f0c05c135a2f1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 15:49:38 +0100 Subject: [PATCH 050/142] Implemented Rhystic Syphon --- Mage.Sets/src/mage/cards/r/RhysticSyphon.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RhysticSyphon.java 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); + } +} From 9f4b63017f2069f52add132fb432408d5962c56d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 15:50:20 +0100 Subject: [PATCH 051/142] Implemented Thresher Beast --- Mage.Sets/src/mage/cards/t/ThresherBeast.java | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ThresherBeast.java 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; + } +} From d5b948973aec1544e87a12775e3d7c6d143a142b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 15:51:22 +0100 Subject: [PATCH 052/142] Implemented Wing Storm --- Mage.Sets/src/mage/cards/w/WingStorm.java | 105 ++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WingStorm.java 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; + } +} From 5a36a4d47ec7d2b30a753d38938719f97b072ce1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 15:54:05 +0100 Subject: [PATCH 053/142] Implemented cards --- Mage.Sets/src/mage/sets/Prophecy.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 9f3172aa2f7..0727299f8dc 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -86,10 +86,12 @@ 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)); @@ -133,7 +135,11 @@ 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 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)); @@ -156,6 +162,7 @@ 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)); @@ -170,6 +177,7 @@ public class Prophecy extends ExpansionSet { 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)); From 5c48d549161d666edec577d73ffacee0d14ec51e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 16:02:46 +0100 Subject: [PATCH 054/142] Rhystic Scrying payment cost fix --- Mage.Sets/src/mage/cards/r/RhysticScrying.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/r/RhysticScrying.java b/Mage.Sets/src/mage/cards/r/RhysticScrying.java index 5b19673103a..f558aa0e119 100644 --- a/Mage.Sets/src/mage/cards/r/RhysticScrying.java +++ b/Mage.Sets/src/mage/cards/r/RhysticScrying.java @@ -83,7 +83,7 @@ class RhysticScryingEffect extends OneShotEffect { if (controller != null && sourceObject != null) { boolean result = true; boolean doEffect = false; - Cost cost = new GenericManaCost(3); + 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); From aa7231bec0472824781b970e76caa618bcd4fcdc Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 19:41:22 +0100 Subject: [PATCH 055/142] Expanded DoUnlessTargetPlayerOrTargetsControllerPaysEffect --- ...sTargetPlayerOrTargetsControllerPaysEffect.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java index 12d698b5274..5876210895c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java @@ -50,6 +50,7 @@ import mage.util.CardUtil; public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEffect { protected Effects executingEffects = new Effects(); + private Effect otherwiseEffect; private Cost cost; private DynamicValue genericMana; private String chooseUseText; @@ -59,8 +60,13 @@ public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEf } 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; } @@ -74,6 +80,7 @@ public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEf 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(); } @@ -135,6 +142,13 @@ public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEf 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; } From 63b50ea140f464d6754f6b18f5d6bd48d243a87d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 19:42:33 +0100 Subject: [PATCH 056/142] Implemented Rhystic Lightning --- .../src/mage/cards/r/RhysticLightning.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RhysticLightning.java 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); + } +} From ca18060b7d9c7c9d49e1856b8b372cb7325a34ab Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 19:44:02 +0100 Subject: [PATCH 057/142] Implemented Keldon Battlewagon --- .../src/mage/cards/k/KeldonBattlewagon.java | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KeldonBattlewagon.java 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); + } +} From d001fafaeddbd518a6060c3478d1afc68b641352 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 19:45:26 +0100 Subject: [PATCH 058/142] Implemented Rhystic Lightning and Keldon Battlewagon --- Mage.Sets/src/mage/sets/Prophecy.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 0727299f8dc..5e29e9f37cd 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -106,6 +106,7 @@ public class Prophecy extends ExpansionSet { 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)); @@ -136,6 +137,7 @@ public class Prophecy extends ExpansionSet { 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)); From 860909408d8ca1f513245594fd32ba6a48f4ee53 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 23:03:54 +0100 Subject: [PATCH 059/142] Minor improvement --- .../DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java index 5876210895c..79aeee1d2e8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java @@ -96,8 +96,8 @@ public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEf @Override public boolean apply(Game game, Ability source) { - Player targetController = game.getPlayer(source.getFirstTarget()); - Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + Player targetController = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + Permanent targetPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (targetPermanent != null) { targetController = game.getPlayer(targetPermanent.getControllerId()); } From e9e7034c72bdd5bf12e2e3800653ad277e9fa84f Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 23:16:26 +0100 Subject: [PATCH 060/142] Implemented Shrouded Serpent --- .../src/mage/cards/s/ShroudedSerpent.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShroudedSerpent.java 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); + } +} From fc580f16ac8a6ef0a178750e917bde5b3ef70feb Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 17 Dec 2017 23:17:24 +0100 Subject: [PATCH 061/142] Implemented Shrouded Serpent --- Mage.Sets/src/mage/sets/Prophecy.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 5e29e9f37cd..1683668a27c 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -151,6 +151,7 @@ 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("Spiketail Drake", 48, Rarity.UNCOMMON, mage.cards.s.SpiketailDrake.class)); From 8bc9ae15437132579557445393132fe8142b0d20 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 03:12:41 +0100 Subject: [PATCH 062/142] Implemented Infinity Elemental --- .../src/mage/cards/i/InfinityElemental.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/InfinityElemental.java diff --git a/Mage.Sets/src/mage/cards/i/InfinityElemental.java b/Mage.Sets/src/mage/cards/i/InfinityElemental.java new file mode 100644 index 00000000000..f9e425f80d1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InfinityElemental.java @@ -0,0 +1,95 @@ +/* + * 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.i; + +import java.util.Objects; +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author L_J + */ +public class InfinityElemental extends CardImpl { + + private class MaxMageInt extends MageInt { + + private boolean isInfinite = true; + + public MaxMageInt() { + super(Integer.MAX_VALUE); + } + + @Override + public MaxMageInt copy() { + if (Objects.equals(this, EmptyMageInt)) { + return this; + } + return new MaxMageInt(); + } + + @Override + public void setValue(int value) { + this.boostedValue = value; + this.isInfinite = false; + } + + @Override + public void boostValue(int amount) { + if (!isInfinite) { + this.boostedValue += amount; + } + } + + @Override + public void resetToBaseValue() { + this.boostedValue = this.baseValueModified; + this.isInfinite = true; + } + }; + + public InfinityElemental(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}{R}"); + this.subtype.add(SubType.ELEMENTAL); + this.power = new MaxMageInt(); + this.toughness = new MageInt(5); + } + + public InfinityElemental(final InfinityElemental card) { + super(card); + } + + @Override + public InfinityElemental copy() { + return new InfinityElemental(this); + } +} From 9963a5ddf8f4bfa8b5604f32005b95040d7fa007 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 03:15:36 +0100 Subject: [PATCH 063/142] Implemented Infinity Elemental --- Mage.Sets/src/mage/sets/Unstable.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Unstable.java b/Mage.Sets/src/mage/sets/Unstable.java index d7ecad68d42..82f53b7b454 100644 --- a/Mage.Sets/src/mage/sets/Unstable.java +++ b/Mage.Sets/src/mage/sets/Unstable.java @@ -62,6 +62,7 @@ public class Unstable extends ExpansionSet { cards.add(new SetCardInfo("Ground Pounder", 110, Rarity.COMMON, mage.cards.g.GroundPounder.class)); cards.add(new SetCardInfo("Hammer Helper", 85, Rarity.COMMON, mage.cards.h.HammerHelper.class)); cards.add(new SetCardInfo("Hydradoodle", 112, Rarity.RARE, mage.cards.h.Hydradoodle.class)); + cards.add(new SetCardInfo("Infinity Elemental", 88, Rarity.MYTHIC, mage.cards.i.InfinityElemental.class)); cards.add(new SetCardInfo("Inhumaniac", 59, Rarity.UNCOMMON, mage.cards.i.Inhumaniac.class)); cards.add(new SetCardInfo("Island", 213, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.UNH_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("Krark's Other Thumb", 151, Rarity.UNCOMMON, mage.cards.k.KrarksOtherThumb.class)); From ae4e244c3fbb076700b15efae34309e2d0722ad3 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 09:09:07 +0100 Subject: [PATCH 064/142] Implemented Infinity Elemental --- Utils/mtg-cards-data.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 113a6e90685..c74f1e0d65b 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32764,3 +32764,4 @@ Wall of Fortune|Unstable|50|C|{1}{U}|Artifact Creature - Wall|0|4|Defender$You m Wild Crocodile|Unstable|125|C|{1}{G}|Host Creature - Crocodile|1|1|When this creature enters the battlefield, search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.| Willing Test Subject|Unstable|126|C|{2}{G}|Creature- Spider Monkey Scientist|2|2|Reach$Whenever you roll a 4 or higher on a die, put a +1/+1 counter on Willing Test Subject.$6: Roll a six-sided die.| Garbage Elemental|Unstable|82|U|{4}{R}|Creature - Elemental|3|2|Battle cry (Whenever this creature attacks, each other attacking creature gets +1/+0 until end of turn.)$When Garbage Elemental enters the battlefield, roll two six-sided dice. Create a number of 1/1 red Goblin creature tokens equal to the difference between those results.| +Infinity Elemental|Unstable|88|M|{4}{R}{R}{R}|Creature - Elemental|2147483647|5|| From 9f515368c107ac191b8bf386eb5488543e9ffb09 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 09:32:15 +0100 Subject: [PATCH 065/142] Verify workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verify fails without the ∞ symbol at power for Infinity Elemental --- Utils/mtg-cards-data.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index c74f1e0d65b..113a6e90685 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32764,4 +32764,3 @@ Wall of Fortune|Unstable|50|C|{1}{U}|Artifact Creature - Wall|0|4|Defender$You m Wild Crocodile|Unstable|125|C|{1}{G}|Host Creature - Crocodile|1|1|When this creature enters the battlefield, search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.| Willing Test Subject|Unstable|126|C|{2}{G}|Creature- Spider Monkey Scientist|2|2|Reach$Whenever you roll a 4 or higher on a die, put a +1/+1 counter on Willing Test Subject.$6: Roll a six-sided die.| Garbage Elemental|Unstable|82|U|{4}{R}|Creature - Elemental|3|2|Battle cry (Whenever this creature attacks, each other attacking creature gets +1/+0 until end of turn.)$When Garbage Elemental enters the battlefield, roll two six-sided dice. Create a number of 1/1 red Goblin creature tokens equal to the difference between those results.| -Infinity Elemental|Unstable|88|M|{4}{R}{R}{R}|Creature - Elemental|2147483647|5|| From 920432d2d400b6dc82bdac5bc4b07cdcc7dd6f01 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 21:22:15 +0100 Subject: [PATCH 066/142] Implemented Branded Brawlers --- .../src/mage/cards/b/BrandedBrawlers.java | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BrandedBrawlers.java 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); + } + +} From bc728d31f3aae5c01a3d6dcfb6f17da95fdf8541 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 21:22:49 +0100 Subject: [PATCH 067/142] Implemented Veteran Brawlers --- .../src/mage/cards/v/VeteranBrawlers.java | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VeteranBrawlers.java 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); + } + +} From e6b15f65d8a472abe6183a60d51a8653466ac9b1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 21:23:51 +0100 Subject: [PATCH 068/142] Implemented Branded Brawlers and Veteran Brawlers --- Mage.Sets/src/mage/sets/Prophecy.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 1683668a27c..9d65ff6399e 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)); @@ -171,6 +172,7 @@ public class Prophecy extends ExpansionSet { 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)); From eae526e3b393db69fecabd2009541f6da2e814e1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Mon, 18 Dec 2017 22:16:14 +0100 Subject: [PATCH 069/142] Added Verify exception for Infinity Elemental --- Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 574e5b627fc..2f5cef23786 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"); From 4a6ff5593edbd6982503b5757d64ebbce2574f1c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 01:40:44 +0100 Subject: [PATCH 070/142] More edits --- .../DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java index 79aeee1d2e8..47f064ea6fb 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessTargetPlayerOrTargetsControllerPaysEffect.java @@ -97,7 +97,7 @@ public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEf @Override public boolean apply(Game game, Ability source) { Player targetController = game.getPlayer(this.getTargetPointer().getFirst(game, source)); - Permanent targetPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); + Permanent targetPermanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); if (targetPermanent != null) { targetController = game.getPlayer(targetPermanent.getControllerId()); } From 1ae892c63ffc9f67f6f2bda04258983a98a5e7c8 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 01:56:20 +0100 Subject: [PATCH 071/142] Implemented Death Charmer --- Mage.Sets/src/mage/cards/d/DeathCharmer.java | 66 ++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeathCharmer.java 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); + } +} From fe5231730ba978d2198fc00e9223f7585e63894d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 01:57:38 +0100 Subject: [PATCH 072/142] Implemented Hollow Warrior --- Mage.Sets/src/mage/cards/h/HollowWarrior.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HollowWarrior.java 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); + } + +} From ee06dccca714cca26aed8a6c53ae90506d53a591 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 01:58:19 +0100 Subject: [PATCH 073/142] Implemented Mirror Strike --- Mage.Sets/src/mage/cards/m/MirrorStrike.java | 131 +++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MirrorStrike.java 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; + } +} From 7adc04f8942e3463ae82099ed9865954bcc09a6d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 01:59:08 +0100 Subject: [PATCH 074/142] Implemented Soul Charmer --- Mage.Sets/src/mage/cards/s/SoulCharmer.java | 66 +++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoulCharmer.java 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); + } +} From 45b79319579243b81c55d17c06fe0149198d4ad3 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 02:01:01 +0100 Subject: [PATCH 075/142] Implemented more cards --- Mage.Sets/src/mage/sets/Prophecy.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 9d65ff6399e..5fa54206277 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -78,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)); @@ -101,6 +102,7 @@ public class Prophecy extends ExpansionSet { 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)); @@ -120,6 +122,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)); @@ -155,6 +158,7 @@ public class Prophecy extends ExpansionSet { 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)); From 20dc4a2f28a6fe222424c9a4a9fbcc98d1f0675d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 12:48:11 +0100 Subject: [PATCH 076/142] Implemented Glittering Lion --- .../src/mage/cards/g/GlitteringLion.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GlitteringLion.java 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; + } + +} From ca25f5cad2a29bc7559a9982c6eaa08fecd04324 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 12:49:38 +0100 Subject: [PATCH 077/142] Implemented Glittering Lynx --- .../src/mage/cards/g/GlitteringLynx.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GlitteringLynx.java 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; + } + +} From 33dd84bf5c2d4de54d1c789b819565eafb1384f5 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 12:51:44 +0100 Subject: [PATCH 078/142] Implemented Wall of Vipers --- Mage.Sets/src/mage/cards/w/WallOfVipers.java | 83 ++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WallOfVipers.java 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..caa2f077e9b --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WallOfVipers.java @@ -0,0 +1,83 @@ +/* + * 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.FilterAttackingCreature; +import mage.filter.predicate.permanent.BlockedByIdPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author BursegSardaukar & 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. + FilterAttackingCreature filter = new FilterAttackingCreature("creature it's blocking"); + filter.add(new BlockedByIdPredicate(this.getId())); + 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(filter)); + 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); + } +} From c457bb47c74082df3ebcb6c5635cf4dee72159b7 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 15:28:46 +0100 Subject: [PATCH 079/142] Implemented more cards --- Mage.Sets/src/mage/sets/Prophecy.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 5fa54206277..25bd32e66ce 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -97,6 +97,8 @@ public class Prophecy extends ExpansionSet { 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)); @@ -180,6 +182,7 @@ public class Prophecy extends ExpansionSet { 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)); From dff74cce5a30a9fe4179f0518fbb71f30160256a Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 23:43:21 +0100 Subject: [PATCH 080/142] Removed Infinity Elemental --- Mage.Sets/src/mage/sets/Unstable.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Unstable.java b/Mage.Sets/src/mage/sets/Unstable.java index 82f53b7b454..d7ecad68d42 100644 --- a/Mage.Sets/src/mage/sets/Unstable.java +++ b/Mage.Sets/src/mage/sets/Unstable.java @@ -62,7 +62,6 @@ public class Unstable extends ExpansionSet { cards.add(new SetCardInfo("Ground Pounder", 110, Rarity.COMMON, mage.cards.g.GroundPounder.class)); cards.add(new SetCardInfo("Hammer Helper", 85, Rarity.COMMON, mage.cards.h.HammerHelper.class)); cards.add(new SetCardInfo("Hydradoodle", 112, Rarity.RARE, mage.cards.h.Hydradoodle.class)); - cards.add(new SetCardInfo("Infinity Elemental", 88, Rarity.MYTHIC, mage.cards.i.InfinityElemental.class)); cards.add(new SetCardInfo("Inhumaniac", 59, Rarity.UNCOMMON, mage.cards.i.Inhumaniac.class)); cards.add(new SetCardInfo("Island", 213, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.UNH_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("Krark's Other Thumb", 151, Rarity.UNCOMMON, mage.cards.k.KrarksOtherThumb.class)); From e69dbe2adf65291a306753b874b04cbbfe38ff87 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 19 Dec 2017 23:44:25 +0100 Subject: [PATCH 081/142] Removed Infinity Elemental --- .../src/mage/cards/i/InfinityElemental.java | 95 ------------------- 1 file changed, 95 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/i/InfinityElemental.java diff --git a/Mage.Sets/src/mage/cards/i/InfinityElemental.java b/Mage.Sets/src/mage/cards/i/InfinityElemental.java deleted file mode 100644 index f9e425f80d1..00000000000 --- a/Mage.Sets/src/mage/cards/i/InfinityElemental.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.cards.i; - -import java.util.Objects; -import java.util.UUID; -import mage.MageInt; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -/** - * - * @author L_J - */ -public class InfinityElemental extends CardImpl { - - private class MaxMageInt extends MageInt { - - private boolean isInfinite = true; - - public MaxMageInt() { - super(Integer.MAX_VALUE); - } - - @Override - public MaxMageInt copy() { - if (Objects.equals(this, EmptyMageInt)) { - return this; - } - return new MaxMageInt(); - } - - @Override - public void setValue(int value) { - this.boostedValue = value; - this.isInfinite = false; - } - - @Override - public void boostValue(int amount) { - if (!isInfinite) { - this.boostedValue += amount; - } - } - - @Override - public void resetToBaseValue() { - this.boostedValue = this.baseValueModified; - this.isInfinite = true; - } - }; - - public InfinityElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}{R}"); - this.subtype.add(SubType.ELEMENTAL); - this.power = new MaxMageInt(); - this.toughness = new MageInt(5); - } - - public InfinityElemental(final InfinityElemental card) { - super(card); - } - - @Override - public InfinityElemental copy() { - return new InfinityElemental(this); - } -} From 29c9ce696dc9ba6b517ab168091e422c8fbc1ffe Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 20 Dec 2017 00:20:27 +0100 Subject: [PATCH 082/142] Included overflow check methods --- Mage/src/main/java/mage/game/Game.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index 3956dd24b7b..af57f22d9c8 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -466,4 +466,8 @@ public interface Game extends MageItem, Serializable { UUID getMonarchId(); void setMonarchId(Ability source, UUID monarchId); + + int addWithOverflowCheck(int base, int increment); + + int subtractWithOverflowCheck(int base, int decrement); } From 35bbe20b95fff211a81608afd61c16167fd134b1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 20 Dec 2017 00:21:44 +0100 Subject: [PATCH 083/142] Included overflow check methods --- Mage/src/main/java/mage/game/GameImpl.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 9e07a84e340..b37590f40a6 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -3000,4 +3000,25 @@ public abstract class GameImpl implements Game, Serializable { } } + @Override + public 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; + } + + @Override + public 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; + } } From 40561e900a67718a622de2b50e191e59f6f0352c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 20 Dec 2017 00:29:36 +0100 Subject: [PATCH 084/142] Included overflow check methods --- Mage/src/main/java/mage/players/PlayerImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 423aee4372d..c130af8cb0a 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1748,7 +1748,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 = game.subtractWithOverflowCheck(this.life, event.getAmount()); if (!game.isSimulation()) { game.informPlayers(this.getLogName() + " loses " + event.getAmount() + " life"); } @@ -1777,7 +1778,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 = game.addWithOverflowCheck(this.life, event.getAmount()); if (!game.isSimulation()) { game.informPlayers(this.getLogName() + " gains " + event.getAmount() + " life"); } From bf6939f45b4bf465b5b7f657a96465b1a91c7b6e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 20 Dec 2017 00:31:31 +0100 Subject: [PATCH 085/142] Included overflow check methods --- Mage/src/main/java/mage/game/permanent/PermanentImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index a5e5b9d59c1..34659ec7841 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -887,7 +887,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 = game.addWithOverflowCheck(this.damage, actualDamage); } game.fireEvent(new DamagedCreatureEvent(objectId, sourceId, controllerId, actualDamage, combat)); return actualDamage; From 24200738957d2a071e00a29e1ef9409a2acf8726 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 20 Dec 2017 00:35:26 +0100 Subject: [PATCH 086/142] Changed integer amount declaration --- Mage.Sets/src/mage/cards/p/PersonalIncarnation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 75ee0c27bb5ba981b67829c80f7cb65539cbc2a8 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 20:30:24 +0100 Subject: [PATCH 087/142] Fix for Wall of Vipers --- Mage.Sets/src/mage/cards/w/WallOfVipers.java | 42 +++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/w/WallOfVipers.java b/Mage.Sets/src/mage/cards/w/WallOfVipers.java index caa2f077e9b..25025cd38bb 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfVipers.java +++ b/Mage.Sets/src/mage/cards/w/WallOfVipers.java @@ -41,13 +41,15 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.common.FilterAttackingCreature; -import mage.filter.predicate.permanent.BlockedByIdPredicate; +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 BursegSardaukar & L_J + * @author L_J */ public class WallOfVipers extends CardImpl { @@ -62,11 +64,9 @@ public class WallOfVipers extends CardImpl { this.addAbility(DefenderAbility.getInstance()); // {3}: Destroy Wall of Vipers and target creature it's blocking. Any player may activate this ability. - FilterAttackingCreature filter = new FilterAttackingCreature("creature it's blocking"); - filter.add(new BlockedByIdPredicate(this.getId())); 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(filter)); + ability.addTarget(new TargetCreaturePermanent(new WallOfVipersFilter())); ability.setMayActivate(TargetController.ANY); ability.addEffect(new InfoEffect("Any player may activate this ability")); this.addAbility(ability); @@ -81,3 +81,33 @@ public class WallOfVipers extends CardImpl { return new WallOfVipers(this); } } + +class WallOfVipersFilter extends FilterCreaturePermanent { + + public WallOfVipersFilter() { + super("creature it's 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; + } + +} From 6e1c177eca25f8d32253579a9f426f7d69a2a049 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 20:31:50 +0100 Subject: [PATCH 088/142] Text fix --- Mage.Sets/src/mage/cards/w/WallOfVipers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/w/WallOfVipers.java b/Mage.Sets/src/mage/cards/w/WallOfVipers.java index 25025cd38bb..00dbc28da6c 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfVipers.java +++ b/Mage.Sets/src/mage/cards/w/WallOfVipers.java @@ -85,7 +85,7 @@ public class WallOfVipers extends CardImpl { class WallOfVipersFilter extends FilterCreaturePermanent { public WallOfVipersFilter() { - super("creature it's blocking"); + super("creature {this} is blocking"); } public WallOfVipersFilter(final WallOfVipersFilter filter) { From d0f74c9f9d68d4a3d62eaa9a992f8e26ad397bc7 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:06:34 +0100 Subject: [PATCH 089/142] Overflow check --- Mage.Sets/src/mage/cards/i/InsultInjury.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/InsultInjury.java b/Mage.Sets/src/mage/cards/i/InsultInjury.java index b4c272be79c..3e22fc7d0da 100644 --- a/Mage.Sets/src/mage/cards/i/InsultInjury.java +++ b/Mage.Sets/src/mage/cards/i/InsultInjury.java @@ -88,7 +88,7 @@ class InsultDoubleDamageEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 27f0f04d52aa6923e4cae7d429748003e9e950c5 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:07:42 +0100 Subject: [PATCH 090/142] Overflow check --- Mage.Sets/src/mage/cards/a/AngrathsMarauders.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java index e6e12b2eec5..b7d3baf22f0 100644 --- a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java +++ b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java @@ -106,7 +106,7 @@ class AngrathsMaraudersEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(2 * event.getAmount()); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 78bf442674f93c740670c93f1b439fbaa879825e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:08:31 +0100 Subject: [PATCH 091/142] Overflow check --- Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java index 7556ea36dea..ff0cd7caa0c 100644 --- a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java +++ b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java @@ -124,7 +124,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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); } break; case DAMAGE_CREATURE: @@ -134,7 +134,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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); } } } From 123190bfa3db370864fe6476a331d07d4bde63a0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:10:34 +0100 Subject: [PATCH 092/142] Overflow check --- Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java b/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java index 8e4814dbcd9..bdc2dac7a71 100644 --- a/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java +++ b/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java @@ -115,13 +115,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(game.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(game.addWithOverflowCheck(damageEvent.getAmount(), damageEvent.getAmount()), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects()); return true; } } From 536f9732e429532b1856c9a3ec78a5955b6c0c66 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:11:45 +0100 Subject: [PATCH 093/142] Overflow check --- Mage.Sets/src/mage/cards/f/FurnaceOfRath.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java b/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java index 5bc4655be51..41e06785d73 100644 --- a/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java +++ b/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java @@ -99,7 +99,7 @@ class FurnaceOfRathEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(2 * event.getAmount()); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From bf8cd69f80a415b0025ef5641f33c4ab245713f0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:13:10 +0100 Subject: [PATCH 094/142] Overflow check --- Mage.Sets/src/mage/cards/d/DesperateGambit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DesperateGambit.java b/Mage.Sets/src/mage/cards/d/DesperateGambit.java index 1272b4c7291..6e4f4b2f880 100644 --- a/Mage.Sets/src/mage/cards/d/DesperateGambit.java +++ b/Mage.Sets/src/mage/cards/d/DesperateGambit.java @@ -129,7 +129,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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); this.discard(); } else { preventDamageAction(event, source, game); From 031eda86ab9f515d2d0cabd8081e70ee5291bcf1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:14:23 +0100 Subject: [PATCH 095/142] Overflow check --- Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java b/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java index dd8af49bc75..7fc226aa004 100644 --- a/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java +++ b/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java @@ -121,7 +121,7 @@ class ImpulsiveManeuversEffect extends PreventionEffectImpl { DamageEvent damageEvent = (DamageEvent) event; if (damageEvent.isCombatDamage()) { if (wonFlip) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); this.discard(); } else { preventDamageAction(event, source, game); From 977f3d4e0c507394d0a4f57ae181f957efc4276e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:15:32 +0100 Subject: [PATCH 096/142] Overflow check --- Mage.Sets/src/mage/cards/g/GratuitousViolence.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/g/GratuitousViolence.java b/Mage.Sets/src/mage/cards/g/GratuitousViolence.java index 2465d48dde0..7dab860ff64 100644 --- a/Mage.Sets/src/mage/cards/g/GratuitousViolence.java +++ b/Mage.Sets/src/mage/cards/g/GratuitousViolence.java @@ -106,7 +106,7 @@ class GratuitousViolenceReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(2 * event.getAmount()); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 77cbeb39136e7e57f80f0ea1aa5012a8512859a2 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:16:35 +0100 Subject: [PATCH 097/142] Overflow check --- Mage.Sets/src/mage/cards/o/Overblaze.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/Overblaze.java b/Mage.Sets/src/mage/cards/o/Overblaze.java index c1092570c8d..836f1d1fce1 100644 --- a/Mage.Sets/src/mage/cards/o/Overblaze.java +++ b/Mage.Sets/src/mage/cards/o/Overblaze.java @@ -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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } -} \ No newline at end of file +} From 3584e66712fc0444baea60cd2c8fc772d57b1685 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:17:16 +0100 Subject: [PATCH 098/142] Overflow check --- Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java b/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java index 068b806cfb4..46e3457cb37 100644 --- a/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java +++ b/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java @@ -110,7 +110,7 @@ class AnthemOfRakdosHellbentEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 1ab224f046568b7659f127b3b1f85dc67bc2701d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:18:09 +0100 Subject: [PATCH 099/142] Overflow check --- Mage.Sets/src/mage/cards/b/BitterFeud.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/b/BitterFeud.java b/Mage.Sets/src/mage/cards/b/BitterFeud.java index 5297a739da0..e97d01e2306 100644 --- a/Mage.Sets/src/mage/cards/b/BitterFeud.java +++ b/Mage.Sets/src/mage/cards/b/BitterFeud.java @@ -194,7 +194,7 @@ class BitterFeudEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 9e45d962e943c79cfabca6641d1f79cfeda047ea Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:18:51 +0100 Subject: [PATCH 100/142] Overflow check --- Mage.Sets/src/mage/cards/q/QuestForPureFlame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java b/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java index 4ac5e7ce402..90cf5b24b1d 100644 --- a/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java +++ b/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java @@ -137,7 +137,7 @@ class QuestForPureFlameEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From a5fc384644eb367cbde908b59cc7366014d2fcde Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:19:59 +0100 Subject: [PATCH 101/142] Overflow check --- Mage.Sets/src/mage/cards/i/InquisitorsFlail.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java b/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java index fe38f01aba4..7cb40b89162 100644 --- a/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java +++ b/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java @@ -126,7 +126,7 @@ class InquisitorsFlailEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } From f4b66f4de3def7d521d6cfeeff76d0b13809aa75 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:21:32 +0100 Subject: [PATCH 102/142] Overflow check --- Mage.Sets/src/mage/cards/g/GoldnightCastigator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java b/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java index 9411b61bbfd..b461de60e8e 100644 --- a/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java +++ b/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java @@ -118,14 +118,14 @@ class GoldnightCastigatorDoubleDamageEffect extends ReplacementEffectImpl { switch (event.getType()) { case DAMAGE_PLAYER: if (event.getTargetId().equals(source.getControllerId())) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); } } } From 76a4d07b05d4e0a11232876dee3a3f3a036e4aa8 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:22:52 +0100 Subject: [PATCH 103/142] Overflow check --- Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java b/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java index 941df4792e3..156ef33fa17 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java @@ -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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } -} \ No newline at end of file +} From ed490950cfbd21c02a49f6eb62e9b23bd1398d72 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:23:39 +0100 Subject: [PATCH 104/142] Overflow check --- Mage.Sets/src/mage/cards/f/FireServant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/f/FireServant.java b/Mage.Sets/src/mage/cards/f/FireServant.java index e0eadfc9574..b084bb2631d 100644 --- a/Mage.Sets/src/mage/cards/f/FireServant.java +++ b/Mage.Sets/src/mage/cards/f/FireServant.java @@ -111,7 +111,7 @@ class FireServantEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() * 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } From d9c6e53877c4733b5ba392c190fe0b20d564d827 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:28:52 +0100 Subject: [PATCH 105/142] Overflow check --- Mage.Sets/src/mage/cards/p/PyromancersSwath.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/PyromancersSwath.java b/Mage.Sets/src/mage/cards/p/PyromancersSwath.java index 84c83333cb7..4e012805316 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersSwath.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersSwath.java @@ -105,7 +105,7 @@ class PyromancersSwathReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() + 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), 2)); return false; } From 3a74a44a2710f1196b9a463b05b0dd83f7d4c06c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:30:57 +0100 Subject: [PATCH 106/142] Overflow check --- Mage.Sets/src/mage/cards/e/EmbermawHellion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/e/EmbermawHellion.java b/Mage.Sets/src/mage/cards/e/EmbermawHellion.java index 641091b6fc6..d56d7c9a1c6 100644 --- a/Mage.Sets/src/mage/cards/e/EmbermawHellion.java +++ b/Mage.Sets/src/mage/cards/e/EmbermawHellion.java @@ -120,7 +120,7 @@ class EmbermawHellionEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() + 1); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), 1)); return false; } From 18661c2c4d01bdb9010069c5391e37c670fe483e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:33:05 +0100 Subject: [PATCH 107/142] Overflow check --- Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java b/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java index 1a2c6717ff2..7f9cdbe2025 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java @@ -103,7 +103,7 @@ class PyromancersGauntletReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() + 2); + event.setAmount(game.addWithOverflowCheck(event.getAmount(), 2)); return false; } From 02cb7145f2b23dea73b1b1ebe02db066cb3d054e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:45:28 +0100 Subject: [PATCH 108/142] Overflow check --- Mage.Sets/src/mage/cards/p/Phthisis.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/Phthisis.java b/Mage.Sets/src/mage/cards/p/Phthisis.java index 06f54043326..b3c8fff54b1 100644 --- a/Mage.Sets/src/mage/cards/p/Phthisis.java +++ b/Mage.Sets/src/mage/cards/p/Phthisis.java @@ -91,7 +91,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 = game.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); From 3fc7f0c513001f6859156585f7ad4efe1d6fadf1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:47:42 +0100 Subject: [PATCH 109/142] Overflow check --- Mage.Sets/src/mage/cards/f/FarrelsMantle.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/f/FarrelsMantle.java b/Mage.Sets/src/mage/cards/f/FarrelsMantle.java index 380f184ab96..b2eee44e85f 100644 --- a/Mage.Sets/src/mage/cards/f/FarrelsMantle.java +++ b/Mage.Sets/src/mage/cards/f/FarrelsMantle.java @@ -126,7 +126,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 = game.addWithOverflowCheck(perm.getPower().getValue(), 2); + DamageTargetEffect dmgEffect = new DamageTargetEffect(damage); return dmgEffect.apply(game, source); } } From 8e2b397f1dfeda591441aaa00a24e88f648faeca Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:49:12 +0100 Subject: [PATCH 110/142] Overflow check --- Mage.Sets/src/mage/cards/s/Sentinel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/Sentinel.java b/Mage.Sets/src/mage/cards/s/Sentinel.java index 1c67461fe41..d5d2518b1fe 100644 --- a/Mage.Sets/src/mage/cards/s/Sentinel.java +++ b/Mage.Sets/src/mage/cards/s/Sentinel.java @@ -105,7 +105,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 = game.addWithOverflowCheck(targetPermanent.getPower().getValue(), 1); game.addEffect(new SetToughnessSourceEffect(new StaticValue(newToughness), Duration.Custom, SubLayer.SetPT_7b), source); return true; } From c0fb7b5cf08ff3a783e7d708ba0ab396839a9e64 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:50:37 +0100 Subject: [PATCH 111/142] Overflow check --- Mage.Sets/src/mage/cards/p/PredatorsRapport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/PredatorsRapport.java b/Mage.Sets/src/mage/cards/p/PredatorsRapport.java index b2f8c3f5754..989e0258ed3 100644 --- a/Mage.Sets/src/mage/cards/p/PredatorsRapport.java +++ b/Mage.Sets/src/mage/cards/p/PredatorsRapport.java @@ -72,7 +72,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 game.addWithOverflowCheck(sourcePermanent.getPower().getValue(), sourcePermanent.getToughness().getValue()); } return 0; } From 95bde33ddb986b98095ff594e253d9021648b598 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 22:54:25 +0100 Subject: [PATCH 112/142] Overflow check --- Mage.Sets/src/mage/cards/d/Dracoplasm.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/Dracoplasm.java b/Mage.Sets/src/mage/cards/d/Dracoplasm.java index e378fc79986..48d56455f1f 100644 --- a/Mage.Sets/src/mage/cards/d/Dracoplasm.java +++ b/Mage.Sets/src/mage/cards/d/Dracoplasm.java @@ -131,8 +131,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 = game.addWithOverflowCheck(power, targetCreature.getPower().getValue()); + toughness = game.addWithOverflowCheck(toughness, targetCreature.getToughness().getValue()); } } ContinuousEffect effect = new SetPowerToughnessSourceEffect(power, toughness, Duration.Custom, SubLayer.SetPT_7b); @@ -141,4 +141,4 @@ class DracoplasmEffect extends ReplacementEffectImpl { } return false; } -} \ No newline at end of file +} From e4326184c2e984a67199bac974dfbbc353bf416e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 22 Dec 2017 23:02:11 +0100 Subject: [PATCH 113/142] 4ED Seeker numbering fix --- Mage.Sets/src/mage/sets/FourthEdition.java | 610 ++++++++++----------- 1 file changed, 305 insertions(+), 305 deletions(-) diff --git a/Mage.Sets/src/mage/sets/FourthEdition.java b/Mage.Sets/src/mage/sets/FourthEdition.java index 126a1999819..d4dfa9e5d7b 100644 --- a/Mage.Sets/src/mage/sets/FourthEdition.java +++ b/Mage.Sets/src/mage/sets/FourthEdition.java @@ -53,362 +53,362 @@ public class FourthEdition extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Abomination", 1, Rarity.UNCOMMON, mage.cards.a.Abomination.class)); + cards.add(new SetCardInfo("Abomination", 117, Rarity.UNCOMMON, mage.cards.a.Abomination.class)); + cards.add(new SetCardInfo("Animate Dead", 118, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class)); + cards.add(new SetCardInfo("Ashes to Ashes", 119, Rarity.UNCOMMON, mage.cards.a.AshesToAshes.class)); + cards.add(new SetCardInfo("Bad Moon", 120, Rarity.RARE, mage.cards.b.BadMoon.class)); + cards.add(new SetCardInfo("Black Knight", 121, Rarity.UNCOMMON, mage.cards.b.BlackKnight.class)); + cards.add(new SetCardInfo("Blight", 122, Rarity.UNCOMMON, mage.cards.b.Blight.class)); + cards.add(new SetCardInfo("Bog Imp", 123, Rarity.COMMON, mage.cards.b.BogImp.class)); + cards.add(new SetCardInfo("Bog Wraith", 124, Rarity.UNCOMMON, mage.cards.b.BogWraith.class)); + cards.add(new SetCardInfo("Carrion Ants", 125, Rarity.UNCOMMON, mage.cards.c.CarrionAnts.class)); + cards.add(new SetCardInfo("Cosmic Horror", 126, Rarity.RARE, mage.cards.c.CosmicHorror.class)); + cards.add(new SetCardInfo("Cursed Land", 127, Rarity.UNCOMMON, mage.cards.c.CursedLand.class)); + cards.add(new SetCardInfo("Cyclopean Mummy", 128, Rarity.COMMON, mage.cards.c.CyclopeanMummy.class)); + cards.add(new SetCardInfo("Dark Ritual", 129, Rarity.COMMON, mage.cards.d.DarkRitual.class)); + cards.add(new SetCardInfo("Deathgrip", 130, Rarity.UNCOMMON, mage.cards.d.Deathgrip.class)); + cards.add(new SetCardInfo("Deathlace", 131, Rarity.RARE, mage.cards.d.Deathlace.class)); + cards.add(new SetCardInfo("Drain Life", 132, Rarity.COMMON, mage.cards.d.DrainLife.class)); + cards.add(new SetCardInfo("Drudge Skeletons", 133, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class)); + cards.add(new SetCardInfo("El-Hajjaj", 134, Rarity.RARE, mage.cards.e.ElHajjaj.class)); + cards.add(new SetCardInfo("Erg Raiders", 135, Rarity.COMMON, mage.cards.e.ErgRaiders.class)); + cards.add(new SetCardInfo("Evil Presence", 136, Rarity.UNCOMMON, mage.cards.e.EvilPresence.class)); + cards.add(new SetCardInfo("Fear", 137, Rarity.COMMON, mage.cards.f.Fear.class)); + cards.add(new SetCardInfo("Frozen Shade", 138, Rarity.COMMON, mage.cards.f.FrozenShade.class)); + cards.add(new SetCardInfo("Gloom", 139, Rarity.UNCOMMON, mage.cards.g.Gloom.class)); + cards.add(new SetCardInfo("Greed", 140, Rarity.RARE, mage.cards.g.Greed.class)); + cards.add(new SetCardInfo("Howl from Beyond", 141, Rarity.COMMON, mage.cards.h.HowlFromBeyond.class)); + cards.add(new SetCardInfo("Hypnotic Specter", 142, Rarity.UNCOMMON, mage.cards.h.HypnoticSpecter.class)); + cards.add(new SetCardInfo("Junún Efreet", 143, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class)); + cards.add(new SetCardInfo("Lord of the Pit", 144, Rarity.RARE, mage.cards.l.LordOfThePit.class)); + cards.add(new SetCardInfo("Lost Soul", 145, Rarity.COMMON, mage.cards.l.LostSoul.class)); + cards.add(new SetCardInfo("Marsh Gas", 146, Rarity.COMMON, mage.cards.m.MarshGas.class)); + cards.add(new SetCardInfo("Mind Twist", 147, Rarity.RARE, mage.cards.m.MindTwist.class)); + cards.add(new SetCardInfo("Murk Dwellers", 148, Rarity.COMMON, mage.cards.m.MurkDwellers.class)); + cards.add(new SetCardInfo("Nether Shadow", 149, Rarity.RARE, mage.cards.n.NetherShadow.class)); + cards.add(new SetCardInfo("Nightmare", 150, Rarity.RARE, mage.cards.n.Nightmare.class)); + cards.add(new SetCardInfo("Paralyze", 151, Rarity.COMMON, mage.cards.p.Paralyze.class)); + cards.add(new SetCardInfo("Pestilence", 152, Rarity.COMMON, mage.cards.p.Pestilence.class)); + cards.add(new SetCardInfo("Pit Scorpion", 153, Rarity.COMMON, mage.cards.p.PitScorpion.class)); + cards.add(new SetCardInfo("Plague Rats", 154, Rarity.COMMON, mage.cards.p.PlagueRats.class)); + cards.add(new SetCardInfo("Rag Man", 155, Rarity.RARE, mage.cards.r.RagMan.class)); + cards.add(new SetCardInfo("Raise Dead", 156, Rarity.COMMON, mage.cards.r.RaiseDead.class)); + cards.add(new SetCardInfo("Royal Assassin", 157, Rarity.RARE, mage.cards.r.RoyalAssassin.class)); + cards.add(new SetCardInfo("Scathe Zombies", 158, Rarity.COMMON, mage.cards.s.ScatheZombies.class)); + cards.add(new SetCardInfo("Scavenging Ghoul", 159, Rarity.UNCOMMON, mage.cards.s.ScavengingGhoul.class)); + cards.add(new SetCardInfo("Sengir Vampire", 160, Rarity.UNCOMMON, mage.cards.s.SengirVampire.class)); + cards.add(new SetCardInfo("Simulacrum", 161, Rarity.UNCOMMON, mage.cards.s.Simulacrum.class)); + cards.add(new SetCardInfo("Sorceress Queen", 162, Rarity.RARE, mage.cards.s.SorceressQueen.class)); + cards.add(new SetCardInfo("Spirit Shackle", 163, Rarity.UNCOMMON, mage.cards.s.SpiritShackle.class)); + cards.add(new SetCardInfo("Terror", 164, Rarity.COMMON, mage.cards.t.Terror.class)); + cards.add(new SetCardInfo("Uncle Istvan", 165, Rarity.UNCOMMON, mage.cards.u.UncleIstvan.class)); + cards.add(new SetCardInfo("Unholy Strength", 166, Rarity.COMMON, mage.cards.u.UnholyStrength.class)); + cards.add(new SetCardInfo("Vampire Bats", 167, Rarity.COMMON, mage.cards.v.VampireBats.class)); + cards.add(new SetCardInfo("Wall of Bone", 168, Rarity.UNCOMMON, mage.cards.w.WallOfBone.class)); + cards.add(new SetCardInfo("Warp Artifact", 169, Rarity.RARE, mage.cards.w.WarpArtifact.class)); + cards.add(new SetCardInfo("Weakness", 170, Rarity.COMMON, mage.cards.w.Weakness.class)); + cards.add(new SetCardInfo("Will-o'-the-Wisp", 171, Rarity.RARE, mage.cards.w.WillOTheWisp.class)); + cards.add(new SetCardInfo("Word of Binding", 172, Rarity.COMMON, mage.cards.w.WordOfBinding.class)); + cards.add(new SetCardInfo("Xenic Poltergeist", 173, Rarity.RARE, mage.cards.x.XenicPoltergeist.class)); + cards.add(new SetCardInfo("Zombie Master", 174, Rarity.RARE, mage.cards.z.ZombieMaster.class)); cards.add(new SetCardInfo("Air Elemental", 59, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); - cards.add(new SetCardInfo("Alabaster Potion", 251, Rarity.COMMON, mage.cards.a.AlabasterPotion.class)); - cards.add(new SetCardInfo("Aladdin's Lamp", 309, Rarity.RARE, mage.cards.a.AladdinsLamp.class)); - cards.add(new SetCardInfo("Aladdin's Ring", 310, Rarity.RARE, mage.cards.a.AladdinsRing.class)); - cards.add(new SetCardInfo("Ali Baba", 193, Rarity.UNCOMMON, mage.cards.a.AliBaba.class)); - cards.add(new SetCardInfo("Amrou Kithkin", 252, Rarity.COMMON, mage.cards.a.AmrouKithkin.class)); - cards.add(new SetCardInfo("Amulet of Kroog", 311, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class)); - cards.add(new SetCardInfo("Angry Mob", 253, Rarity.UNCOMMON, mage.cards.a.AngryMob.class)); cards.add(new SetCardInfo("Animate Artifact", 60, Rarity.UNCOMMON, mage.cards.a.AnimateArtifact.class)); - cards.add(new SetCardInfo("Animate Dead", 2, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class)); - cards.add(new SetCardInfo("Animate Wall", 254, Rarity.RARE, mage.cards.a.AnimateWall.class)); - cards.add(new SetCardInfo("Ankh of Mishra", 312, Rarity.RARE, mage.cards.a.AnkhOfMishra.class)); cards.add(new SetCardInfo("Apprentice Wizard", 61, Rarity.COMMON, mage.cards.a.ApprenticeWizard.class)); - cards.add(new SetCardInfo("Armageddon", 255, Rarity.RARE, mage.cards.a.Armageddon.class)); - cards.add(new SetCardInfo("Armageddon Clock", 313, Rarity.RARE, mage.cards.a.ArmageddonClock.class)); - cards.add(new SetCardInfo("Ashes to Ashes", 3, Rarity.UNCOMMON, mage.cards.a.AshesToAshes.class)); - cards.add(new SetCardInfo("Ashnod's Battle Gear", 314, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class)); - cards.add(new SetCardInfo("Aspect of Wolf", 117, Rarity.RARE, mage.cards.a.AspectOfWolf.class)); cards.add(new SetCardInfo("Backfire", 62, Rarity.UNCOMMON, mage.cards.b.Backfire.class)); - cards.add(new SetCardInfo("Bad Moon", 4, Rarity.RARE, mage.cards.b.BadMoon.class)); - cards.add(new SetCardInfo("Balance", 256, Rarity.RARE, mage.cards.b.Balance.class)); - cards.add(new SetCardInfo("Ball Lightning", 194, Rarity.RARE, mage.cards.b.BallLightning.class)); - cards.add(new SetCardInfo("Bird Maiden", 195, Rarity.COMMON, mage.cards.b.BirdMaiden.class)); - cards.add(new SetCardInfo("Birds of Paradise", 118, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); - cards.add(new SetCardInfo("Black Knight", 5, Rarity.UNCOMMON, mage.cards.b.BlackKnight.class)); - cards.add(new SetCardInfo("Black Mana Battery", 316, Rarity.RARE, mage.cards.b.BlackManaBattery.class)); - cards.add(new SetCardInfo("Black Vise", 317, Rarity.UNCOMMON, mage.cards.b.BlackVise.class)); - cards.add(new SetCardInfo("Black Ward", 258, Rarity.UNCOMMON, mage.cards.b.BlackWard.class)); - cards.add(new SetCardInfo("Blessing", 259, Rarity.RARE, mage.cards.b.Blessing.class)); - cards.add(new SetCardInfo("Blight", 6, Rarity.UNCOMMON, mage.cards.b.Blight.class)); - cards.add(new SetCardInfo("Blood Lust", 196, Rarity.COMMON, mage.cards.b.BloodLust.class)); cards.add(new SetCardInfo("Blue Elemental Blast", 63, Rarity.COMMON, mage.cards.b.BlueElementalBlast.class)); - cards.add(new SetCardInfo("Blue Mana Battery", 318, Rarity.RARE, mage.cards.b.BlueManaBattery.class)); - cards.add(new SetCardInfo("Blue Ward", 260, Rarity.UNCOMMON, mage.cards.b.BlueWard.class)); - cards.add(new SetCardInfo("Bog Imp", 7, Rarity.COMMON, mage.cards.b.BogImp.class)); - cards.add(new SetCardInfo("Bog Wraith", 8, Rarity.UNCOMMON, mage.cards.b.BogWraith.class)); - cards.add(new SetCardInfo("Bottle of Suleiman", 319, Rarity.RARE, mage.cards.b.BottleOfSuleiman.class)); - cards.add(new SetCardInfo("Brainwash", 261, Rarity.COMMON, mage.cards.b.Brainwash.class)); - cards.add(new SetCardInfo("Brass Man", 320, Rarity.UNCOMMON, mage.cards.b.BrassMan.class)); - cards.add(new SetCardInfo("Brothers of Fire", 197, Rarity.COMMON, mage.cards.b.BrothersOfFire.class)); - cards.add(new SetCardInfo("Burrowing", 198, Rarity.UNCOMMON, mage.cards.b.Burrowing.class)); - cards.add(new SetCardInfo("Carnivorous Plant", 119, Rarity.COMMON, mage.cards.c.CarnivorousPlant.class)); - cards.add(new SetCardInfo("Carrion Ants", 9, Rarity.UNCOMMON, mage.cards.c.CarrionAnts.class)); - cards.add(new SetCardInfo("Castle", 262, Rarity.UNCOMMON, mage.cards.c.Castle.class)); - cards.add(new SetCardInfo("Cave People", 199, Rarity.UNCOMMON, mage.cards.c.CavePeople.class)); - cards.add(new SetCardInfo("Celestial Prism", 322, Rarity.UNCOMMON, mage.cards.c.CelestialPrism.class)); - cards.add(new SetCardInfo("Channel", 120, Rarity.UNCOMMON, mage.cards.c.Channel.class)); - cards.add(new SetCardInfo("Chaoslace", 200, Rarity.RARE, mage.cards.c.Chaoslace.class)); - cards.add(new SetCardInfo("Circle of Protection: Artifacts", 263, Rarity.COMMON, mage.cards.c.CircleOfProtectionArtifacts.class)); - cards.add(new SetCardInfo("Circle of Protection: Black", 264, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlack.class)); - cards.add(new SetCardInfo("Circle of Protection: Blue", 265, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlue.class)); - cards.add(new SetCardInfo("Circle of Protection: Green", 266, Rarity.COMMON, mage.cards.c.CircleOfProtectionGreen.class)); - cards.add(new SetCardInfo("Circle of Protection: Red", 267, Rarity.COMMON, mage.cards.c.CircleOfProtectionRed.class)); - cards.add(new SetCardInfo("Circle of Protection: White", 268, Rarity.COMMON, mage.cards.c.CircleOfProtectionWhite.class)); - cards.add(new SetCardInfo("Clay Statue", 323, Rarity.COMMON, mage.cards.c.ClayStatue.class)); - cards.add(new SetCardInfo("Clockwork Avian", 324, Rarity.RARE, mage.cards.c.ClockworkAvian.class)); - cards.add(new SetCardInfo("Clockwork Beast", 325, Rarity.RARE, mage.cards.c.ClockworkBeast.class)); - cards.add(new SetCardInfo("Cockatrice", 121, Rarity.RARE, mage.cards.c.Cockatrice.class)); - cards.add(new SetCardInfo("Colossus of Sardia", 326, Rarity.RARE, mage.cards.c.ColossusOfSardia.class)); - cards.add(new SetCardInfo("Conservator", 327, Rarity.UNCOMMON, mage.cards.c.Conservator.class)); cards.add(new SetCardInfo("Control Magic", 64, Rarity.UNCOMMON, mage.cards.c.ControlMagic.class)); - cards.add(new SetCardInfo("Conversion", 269, Rarity.UNCOMMON, mage.cards.c.Conversion.class)); - cards.add(new SetCardInfo("Coral Helm", 328, Rarity.RARE, mage.cards.c.CoralHelm.class)); - cards.add(new SetCardInfo("Cosmic Horror", 10, Rarity.RARE, mage.cards.c.CosmicHorror.class)); cards.add(new SetCardInfo("Counterspell", 65, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); - cards.add(new SetCardInfo("Craw Wurm", 122, Rarity.COMMON, mage.cards.c.CrawWurm.class)); cards.add(new SetCardInfo("Creature Bond", 66, Rarity.COMMON, mage.cards.c.CreatureBond.class)); - cards.add(new SetCardInfo("Crimson Manticore", 201, Rarity.RARE, mage.cards.c.CrimsonManticore.class)); - cards.add(new SetCardInfo("Crumble", 123, Rarity.UNCOMMON, mage.cards.c.Crumble.class)); - cards.add(new SetCardInfo("Crusade", 270, Rarity.RARE, mage.cards.c.Crusade.class)); - cards.add(new SetCardInfo("Crystal Rod", 329, Rarity.UNCOMMON, mage.cards.c.CrystalRod.class)); - cards.add(new SetCardInfo("Cursed Land", 11, Rarity.UNCOMMON, mage.cards.c.CursedLand.class)); - cards.add(new SetCardInfo("Cursed Rack", 330, Rarity.UNCOMMON, mage.cards.c.CursedRack.class)); - cards.add(new SetCardInfo("Cyclopean Mummy", 12, Rarity.COMMON, mage.cards.c.CyclopeanMummy.class)); - cards.add(new SetCardInfo("Dancing Scimitar", 331, Rarity.RARE, mage.cards.d.DancingScimitar.class)); - cards.add(new SetCardInfo("Dark Ritual", 13, Rarity.COMMON, mage.cards.d.DarkRitual.class)); - cards.add(new SetCardInfo("Deathgrip", 14, Rarity.UNCOMMON, mage.cards.d.Deathgrip.class)); - cards.add(new SetCardInfo("Deathlace", 15, Rarity.RARE, mage.cards.d.Deathlace.class)); - cards.add(new SetCardInfo("Death Ward", 271, Rarity.COMMON, mage.cards.d.DeathWard.class)); - cards.add(new SetCardInfo("Desert Twister", 124, Rarity.UNCOMMON, mage.cards.d.DesertTwister.class)); - cards.add(new SetCardInfo("Detonate", 202, Rarity.UNCOMMON, mage.cards.d.Detonate.class)); - cards.add(new SetCardInfo("Diabolic Machine", 332, Rarity.UNCOMMON, mage.cards.d.DiabolicMachine.class)); - cards.add(new SetCardInfo("Dingus Egg", 333, Rarity.RARE, mage.cards.d.DingusEgg.class)); - cards.add(new SetCardInfo("Disenchant", 272, Rarity.COMMON, mage.cards.d.Disenchant.class)); - cards.add(new SetCardInfo("Disintegrate", 203, Rarity.COMMON, mage.cards.d.Disintegrate.class)); - cards.add(new SetCardInfo("Disrupting Scepter", 334, Rarity.RARE, mage.cards.d.DisruptingScepter.class)); - cards.add(new SetCardInfo("Divine Transformation", 273, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class)); - cards.add(new SetCardInfo("Dragon Engine", 335, Rarity.RARE, mage.cards.d.DragonEngine.class)); - cards.add(new SetCardInfo("Dragon Whelp", 204, Rarity.UNCOMMON, mage.cards.d.DragonWhelp.class)); - cards.add(new SetCardInfo("Drain Life", 16, Rarity.COMMON, mage.cards.d.DrainLife.class)); - cards.add(new SetCardInfo("Drudge Skeletons", 17, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class)); - cards.add(new SetCardInfo("Durkwood Boars", 125, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); - cards.add(new SetCardInfo("Dwarven Warriors", 205, Rarity.COMMON, mage.cards.d.DwarvenWarriors.class)); - cards.add(new SetCardInfo("Earth Elemental", 206, Rarity.UNCOMMON, mage.cards.e.EarthElemental.class)); - cards.add(new SetCardInfo("Earthquake", 207, Rarity.RARE, mage.cards.e.Earthquake.class)); - cards.add(new SetCardInfo("Ebony Horse", 336, Rarity.RARE, mage.cards.e.EbonyHorse.class)); - cards.add(new SetCardInfo("El-Hajjaj", 18, Rarity.RARE, mage.cards.e.ElHajjaj.class)); - cards.add(new SetCardInfo("Elder Land Wurm", 274, Rarity.RARE, mage.cards.e.ElderLandWurm.class)); - cards.add(new SetCardInfo("Elven Riders", 126, Rarity.UNCOMMON, mage.cards.e.ElvenRiders.class)); - cards.add(new SetCardInfo("Elvish Archers", 127, Rarity.RARE, mage.cards.e.ElvishArchers.class)); cards.add(new SetCardInfo("Energy Flux", 68, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class)); cards.add(new SetCardInfo("Energy Tap", 69, Rarity.COMMON, mage.cards.e.EnergyTap.class)); - cards.add(new SetCardInfo("Erg Raiders", 19, Rarity.COMMON, mage.cards.e.ErgRaiders.class)); - cards.add(new SetCardInfo("Eternal Warrior", 208, Rarity.COMMON, mage.cards.e.EternalWarrior.class)); - cards.add(new SetCardInfo("Evil Presence", 20, Rarity.UNCOMMON, mage.cards.e.EvilPresence.class)); - cards.add(new SetCardInfo("Eye for an Eye", 275, Rarity.RARE, mage.cards.e.EyeForAnEye.class)); - cards.add(new SetCardInfo("Fear", 21, Rarity.COMMON, mage.cards.f.Fear.class)); cards.add(new SetCardInfo("Feedback", 71, Rarity.UNCOMMON, mage.cards.f.Feedback.class)); - cards.add(new SetCardInfo("Fellwar Stone", 337, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class)); - cards.add(new SetCardInfo("Fireball", 210, Rarity.COMMON, mage.cards.f.Fireball.class)); - cards.add(new SetCardInfo("Firebreathing", 211, Rarity.COMMON, mage.cards.f.Firebreathing.class)); - cards.add(new SetCardInfo("Fire Elemental", 209, Rarity.UNCOMMON, mage.cards.f.FireElemental.class)); - cards.add(new SetCardInfo("Fissure", 212, Rarity.COMMON, mage.cards.f.Fissure.class)); - cards.add(new SetCardInfo("Flashfires", 213, Rarity.UNCOMMON, mage.cards.f.Flashfires.class)); cards.add(new SetCardInfo("Flight", 72, Rarity.COMMON, mage.cards.f.Flight.class)); cards.add(new SetCardInfo("Flood", 73, Rarity.COMMON, mage.cards.f.Flood.class)); - cards.add(new SetCardInfo("Flying Carpet", 338, Rarity.RARE, mage.cards.f.FlyingCarpet.class)); - cards.add(new SetCardInfo("Fog", 128, Rarity.COMMON, mage.cards.f.Fog.class)); - cards.add(new SetCardInfo("Force of Nature", 129, Rarity.RARE, mage.cards.f.ForceOfNature.class)); - cards.add(new SetCardInfo("Forest", 175, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 176, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 177, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Frozen Shade", 22, Rarity.COMMON, mage.cards.f.FrozenShade.class)); - cards.add(new SetCardInfo("Fungusaur", 130, Rarity.RARE, mage.cards.f.Fungusaur.class)); - cards.add(new SetCardInfo("Gaea's Liege", 131, Rarity.RARE, mage.cards.g.GaeasLiege.class)); cards.add(new SetCardInfo("Gaseous Form", 74, Rarity.COMMON, mage.cards.g.GaseousForm.class)); cards.add(new SetCardInfo("Ghost Ship", 75, Rarity.UNCOMMON, mage.cards.g.GhostShip.class)); - cards.add(new SetCardInfo("Giant Growth", 132, Rarity.COMMON, mage.cards.g.GiantGrowth.class)); - cards.add(new SetCardInfo("Giant Spider", 133, Rarity.COMMON, mage.cards.g.GiantSpider.class)); - cards.add(new SetCardInfo("Giant Strength", 214, Rarity.COMMON, mage.cards.g.GiantStrength.class)); cards.add(new SetCardInfo("Giant Tortoise", 76, Rarity.COMMON, mage.cards.g.GiantTortoise.class)); - cards.add(new SetCardInfo("Glasses of Urza", 339, Rarity.UNCOMMON, mage.cards.g.GlassesOfUrza.class)); - cards.add(new SetCardInfo("Gloom", 23, Rarity.UNCOMMON, mage.cards.g.Gloom.class)); - cards.add(new SetCardInfo("Goblin Balloon Brigade", 215, Rarity.UNCOMMON, mage.cards.g.GoblinBalloonBrigade.class)); - cards.add(new SetCardInfo("Goblin King", 216, Rarity.RARE, mage.cards.g.GoblinKing.class)); - cards.add(new SetCardInfo("Grapeshot Catapult", 340, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class)); - cards.add(new SetCardInfo("Gray Ogre", 218, Rarity.COMMON, mage.cards.g.GrayOgre.class)); - cards.add(new SetCardInfo("Greed", 24, Rarity.RARE, mage.cards.g.Greed.class)); - cards.add(new SetCardInfo("Green Mana Battery", 341, Rarity.RARE, mage.cards.g.GreenManaBattery.class)); - cards.add(new SetCardInfo("Green Ward", 277, Rarity.UNCOMMON, mage.cards.g.GreenWard.class)); - cards.add(new SetCardInfo("Grizzly Bears", 134, Rarity.COMMON, mage.cards.g.GrizzlyBears.class)); - cards.add(new SetCardInfo("Healing Salve", 278, Rarity.COMMON, mage.cards.h.HealingSalve.class)); - cards.add(new SetCardInfo("Hill Giant", 219, Rarity.COMMON, mage.cards.h.HillGiant.class)); - cards.add(new SetCardInfo("Holy Armor", 279, Rarity.COMMON, mage.cards.h.HolyArmor.class)); - cards.add(new SetCardInfo("Holy Strength", 280, Rarity.COMMON, mage.cards.h.HolyStrength.class)); - cards.add(new SetCardInfo("Howl from Beyond", 25, Rarity.COMMON, mage.cards.h.HowlFromBeyond.class)); - cards.add(new SetCardInfo("Howling Mine", 343, Rarity.RARE, mage.cards.h.HowlingMine.class)); cards.add(new SetCardInfo("Hurkyl's Recall", 77, Rarity.RARE, mage.cards.h.HurkylsRecall.class)); - cards.add(new SetCardInfo("Hurloon Minotaur", 220, Rarity.COMMON, mage.cards.h.HurloonMinotaur.class)); - cards.add(new SetCardInfo("Hurricane", 135, Rarity.UNCOMMON, mage.cards.h.Hurricane.class)); - cards.add(new SetCardInfo("Hurr Jackal", 221, Rarity.RARE, mage.cards.h.HurrJackal.class)); - cards.add(new SetCardInfo("Hypnotic Specter", 26, Rarity.UNCOMMON, mage.cards.h.HypnoticSpecter.class)); - cards.add(new SetCardInfo("Immolation", 222, Rarity.COMMON, mage.cards.i.Immolation.class)); - cards.add(new SetCardInfo("Inferno", 223, Rarity.RARE, mage.cards.i.Inferno.class)); - cards.add(new SetCardInfo("Instill Energy", 136, Rarity.UNCOMMON, mage.cards.i.InstillEnergy.class)); - cards.add(new SetCardInfo("Ironclaw Orcs", 224, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); - cards.add(new SetCardInfo("Ironroot Treefolk", 137, Rarity.COMMON, mage.cards.i.IronrootTreefolk.class)); - cards.add(new SetCardInfo("Iron Star", 344, Rarity.UNCOMMON, mage.cards.i.IronStar.class)); - cards.add(new SetCardInfo("Island", 178, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 179, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 180, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island Fish Jasconius", 78, Rarity.RARE, mage.cards.i.IslandFishJasconius.class)); - cards.add(new SetCardInfo("Island Sanctuary", 281, Rarity.RARE, mage.cards.i.IslandSanctuary.class)); - cards.add(new SetCardInfo("Ivory Cup", 345, Rarity.UNCOMMON, mage.cards.i.IvoryCup.class)); - cards.add(new SetCardInfo("Ivory Tower", 346, Rarity.RARE, mage.cards.i.IvoryTower.class)); - cards.add(new SetCardInfo("Jade Monolith", 347, Rarity.RARE, mage.cards.j.JadeMonolith.class)); - cards.add(new SetCardInfo("Jandor's Saddlebags", 348, Rarity.RARE, mage.cards.j.JandorsSaddlebags.class)); - cards.add(new SetCardInfo("Jayemdae Tome", 349, Rarity.RARE, mage.cards.j.JayemdaeTome.class)); cards.add(new SetCardInfo("Jump", 79, Rarity.COMMON, mage.cards.j.Jump.class)); - cards.add(new SetCardInfo("Junún Efreet", 27, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class)); - cards.add(new SetCardInfo("Karma", 282, Rarity.UNCOMMON, mage.cards.k.Karma.class)); - cards.add(new SetCardInfo("Keldon Warlord", 225, Rarity.UNCOMMON, mage.cards.k.KeldonWarlord.class)); - cards.add(new SetCardInfo("Killer Bees", 138, Rarity.UNCOMMON, mage.cards.k.KillerBees.class)); - cards.add(new SetCardInfo("Kismet", 283, Rarity.UNCOMMON, mage.cards.k.Kismet.class)); - cards.add(new SetCardInfo("Kormus Bell", 350, Rarity.RARE, mage.cards.k.KormusBell.class)); - cards.add(new SetCardInfo("Land Leeches", 139, Rarity.COMMON, mage.cards.l.LandLeeches.class)); - cards.add(new SetCardInfo("Land Tax", 284, Rarity.RARE, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Leviathan", 80, Rarity.RARE, mage.cards.l.Leviathan.class)); - cards.add(new SetCardInfo("Ley Druid", 140, Rarity.UNCOMMON, mage.cards.l.LeyDruid.class)); - cards.add(new SetCardInfo("Library of Leng", 351, Rarity.UNCOMMON, mage.cards.l.LibraryOfLeng.class)); - cards.add(new SetCardInfo("Lifeforce", 141, Rarity.UNCOMMON, mage.cards.l.Lifeforce.class)); - cards.add(new SetCardInfo("Lifelace", 142, Rarity.RARE, mage.cards.l.Lifelace.class)); cards.add(new SetCardInfo("Lifetap", 81, Rarity.UNCOMMON, mage.cards.l.Lifetap.class)); - cards.add(new SetCardInfo("Lightning Bolt", 226, Rarity.COMMON, mage.cards.l.LightningBolt.class)); - cards.add(new SetCardInfo("Living Artifact", 143, Rarity.RARE, mage.cards.l.LivingArtifact.class)); - cards.add(new SetCardInfo("Living Lands", 144, Rarity.RARE, mage.cards.l.LivingLands.class)); - cards.add(new SetCardInfo("Llanowar Elves", 145, Rarity.COMMON, mage.cards.l.LlanowarElves.class)); cards.add(new SetCardInfo("Lord of Atlantis", 82, Rarity.RARE, mage.cards.l.LordOfAtlantis.class)); - cards.add(new SetCardInfo("Lord of the Pit", 28, Rarity.RARE, mage.cards.l.LordOfThePit.class)); - cards.add(new SetCardInfo("Lost Soul", 29, Rarity.COMMON, mage.cards.l.LostSoul.class)); - cards.add(new SetCardInfo("Lure", 146, Rarity.UNCOMMON, mage.cards.l.Lure.class)); - cards.add(new SetCardInfo("Magnetic Mountain", 227, Rarity.RARE, mage.cards.m.MagneticMountain.class)); cards.add(new SetCardInfo("Mahamoti Djinn", 84, Rarity.RARE, mage.cards.m.MahamotiDjinn.class)); - cards.add(new SetCardInfo("Manabarbs", 230, Rarity.RARE, mage.cards.m.Manabarbs.class)); - cards.add(new SetCardInfo("Mana Clash", 228, Rarity.RARE, mage.cards.m.ManaClash.class)); - cards.add(new SetCardInfo("Mana Flare", 229, Rarity.RARE, mage.cards.m.ManaFlare.class)); cards.add(new SetCardInfo("Mana Short", 85, Rarity.RARE, mage.cards.m.ManaShort.class)); - cards.add(new SetCardInfo("Mana Vault", 352, Rarity.RARE, mage.cards.m.ManaVault.class)); - cards.add(new SetCardInfo("Marsh Gas", 30, Rarity.COMMON, mage.cards.m.MarshGas.class)); - cards.add(new SetCardInfo("Marsh Viper", 147, Rarity.COMMON, mage.cards.m.MarshViper.class)); - cards.add(new SetCardInfo("Meekstone", 353, Rarity.RARE, mage.cards.m.Meekstone.class)); cards.add(new SetCardInfo("Merfolk of the Pearl Trident", 86, Rarity.COMMON, mage.cards.m.MerfolkOfThePearlTrident.class)); - cards.add(new SetCardInfo("Millstone", 354, Rarity.RARE, mage.cards.m.Millstone.class)); cards.add(new SetCardInfo("Mind Bomb", 87, Rarity.UNCOMMON, mage.cards.m.MindBomb.class)); - cards.add(new SetCardInfo("Mind Twist", 31, Rarity.RARE, mage.cards.m.MindTwist.class)); - cards.add(new SetCardInfo("Mishra's Factory", 181, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); - cards.add(new SetCardInfo("Mons's Goblin Raiders", 231, Rarity.COMMON, mage.cards.m.MonssGoblinRaiders.class)); - cards.add(new SetCardInfo("Morale", 288, Rarity.COMMON, mage.cards.m.Morale.class)); - cards.add(new SetCardInfo("Mountain", 182, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 183, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 184, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Murk Dwellers", 32, Rarity.COMMON, mage.cards.m.MurkDwellers.class)); - cards.add(new SetCardInfo("Nafs Asp", 148, Rarity.COMMON, NafsAsp.class)); - cards.add(new SetCardInfo("Nether Shadow", 33, Rarity.RARE, mage.cards.n.NetherShadow.class)); - cards.add(new SetCardInfo("Nevinyrral's Disk", 356, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); - cards.add(new SetCardInfo("Nightmare", 34, Rarity.RARE, mage.cards.n.Nightmare.class)); - cards.add(new SetCardInfo("Northern Paladin", 287, Rarity.RARE, mage.cards.n.NorthernPaladin.class)); - cards.add(new SetCardInfo("Oasis", 185, Rarity.UNCOMMON, mage.cards.o.Oasis.class)); - cards.add(new SetCardInfo("Obsianus Golem", 357, Rarity.UNCOMMON, mage.cards.o.ObsianusGolem.class)); - cards.add(new SetCardInfo("Onulet", 358, Rarity.RARE, mage.cards.o.Onulet.class)); - cards.add(new SetCardInfo("Orcish Artillery", 232, Rarity.UNCOMMON, mage.cards.o.OrcishArtillery.class)); - cards.add(new SetCardInfo("Orcish Oriflamme", 233, Rarity.UNCOMMON, mage.cards.o.OrcishOriflamme.class)); - cards.add(new SetCardInfo("Ornithopter", 359, Rarity.UNCOMMON, mage.cards.o.Ornithopter.class)); - cards.add(new SetCardInfo("Osai Vultures", 288, Rarity.UNCOMMON, mage.cards.o.OsaiVultures.class)); - cards.add(new SetCardInfo("Paralyze", 35, Rarity.COMMON, mage.cards.p.Paralyze.class)); - cards.add(new SetCardInfo("Pearled Unicorn", 289, Rarity.COMMON, mage.cards.p.PearledUnicorn.class)); - cards.add(new SetCardInfo("Personal Incarnation", 290, Rarity.RARE, mage.cards.p.PersonalIncarnation.class)); - cards.add(new SetCardInfo("Pestilence", 36, Rarity.COMMON, mage.cards.p.Pestilence.class)); cards.add(new SetCardInfo("Phantasmal Forces", 88, Rarity.UNCOMMON, mage.cards.p.PhantasmalForces.class)); cards.add(new SetCardInfo("Phantasmal Terrain", 89, Rarity.COMMON, mage.cards.p.PhantasmalTerrain.class)); cards.add(new SetCardInfo("Phantom Monster", 90, Rarity.UNCOMMON, mage.cards.p.PhantomMonster.class)); - cards.add(new SetCardInfo("Piety", 291, Rarity.COMMON, Piety.class)); cards.add(new SetCardInfo("Pirate Ship", 91, Rarity.RARE, mage.cards.p.PirateShip.class)); - cards.add(new SetCardInfo("Pit Scorpion", 37, Rarity.COMMON, mage.cards.p.PitScorpion.class)); - cards.add(new SetCardInfo("Plague Rats", 38, Rarity.COMMON, mage.cards.p.PlagueRats.class)); - cards.add(new SetCardInfo("Plains", 186, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 187, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 188, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Power Sink", 93, Rarity.COMMON, mage.cards.p.PowerSink.class)); - cards.add(new SetCardInfo("Power Surge", 234, Rarity.RARE, mage.cards.p.PowerSurge.class)); - cards.add(new SetCardInfo("Pradesh Gypsies", 149, Rarity.COMMON, mage.cards.p.PradeshGypsies.class)); - cards.add(new SetCardInfo("Primal Clay", 360, Rarity.RARE, mage.cards.p.PrimalClay.class)); cards.add(new SetCardInfo("Prodigal Sorcerer", 94, Rarity.COMMON, mage.cards.p.ProdigalSorcerer.class)); cards.add(new SetCardInfo("Psionic Entity", 95, Rarity.RARE, mage.cards.p.PsionicEntity.class)); cards.add(new SetCardInfo("Psychic Venom", 96, Rarity.COMMON, mage.cards.p.PsychicVenom.class)); - cards.add(new SetCardInfo("Purelace", 293, Rarity.RARE, mage.cards.p.Purelace.class)); - cards.add(new SetCardInfo("Pyrotechnics", 235, Rarity.UNCOMMON, mage.cards.p.Pyrotechnics.class)); - cards.add(new SetCardInfo("Radjan Spirit", 150, Rarity.UNCOMMON, mage.cards.r.RadjanSpirit.class)); - cards.add(new SetCardInfo("Rag Man", 39, Rarity.RARE, mage.cards.r.RagMan.class)); - cards.add(new SetCardInfo("Raise Dead", 40, Rarity.COMMON, mage.cards.r.RaiseDead.class)); - cards.add(new SetCardInfo("Red Elemental Blast", 236, Rarity.COMMON, mage.cards.r.RedElementalBlast.class)); - cards.add(new SetCardInfo("Red Mana Battery", 361, Rarity.RARE, mage.cards.r.RedManaBattery.class)); - cards.add(new SetCardInfo("Red Ward", 294, Rarity.UNCOMMON, mage.cards.r.RedWard.class)); - cards.add(new SetCardInfo("Regeneration", 152, Rarity.COMMON, mage.cards.r.Regeneration.class)); - cards.add(new SetCardInfo("Reverse Damage", 295, Rarity.RARE, mage.cards.r.ReverseDamage.class)); - cards.add(new SetCardInfo("Righteousness", 296, Rarity.RARE, mage.cards.r.Righteousness.class)); - cards.add(new SetCardInfo("Rod of Ruin", 362, Rarity.UNCOMMON, mage.cards.r.RodOfRuin.class)); - cards.add(new SetCardInfo("Royal Assassin", 41, Rarity.RARE, mage.cards.r.RoyalAssassin.class)); - cards.add(new SetCardInfo("Samite Healer", 297, Rarity.COMMON, mage.cards.s.SamiteHealer.class)); - cards.add(new SetCardInfo("Sandstorm", 153, Rarity.COMMON, mage.cards.s.Sandstorm.class)); - cards.add(new SetCardInfo("Savannah Lions", 298, Rarity.RARE, mage.cards.s.SavannahLions.class)); - cards.add(new SetCardInfo("Scathe Zombies", 42, Rarity.COMMON, mage.cards.s.ScatheZombies.class)); - cards.add(new SetCardInfo("Scavenging Ghoul", 43, Rarity.UNCOMMON, mage.cards.s.ScavengingGhoul.class)); - cards.add(new SetCardInfo("Scryb Sprites", 154, Rarity.COMMON, mage.cards.s.ScrybSprites.class)); cards.add(new SetCardInfo("Sea Serpent", 98, Rarity.COMMON, mage.cards.s.SeaSerpent.class)); - cards.add(new SetCardInfo("Seeker", 299, Rarity.COMMON, mage.cards.s.Seeker.class)); cards.add(new SetCardInfo("Segovian Leviathan", 99, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); - cards.add(new SetCardInfo("Sengir Vampire", 44, Rarity.UNCOMMON, mage.cards.s.SengirVampire.class)); - cards.add(new SetCardInfo("Serra Angel", 300, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class)); - cards.add(new SetCardInfo("Shanodin Dryads", 155, Rarity.COMMON, mage.cards.s.ShanodinDryads.class)); - cards.add(new SetCardInfo("Shapeshifter", 363, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); - cards.add(new SetCardInfo("Shatter", 237, Rarity.COMMON, mage.cards.s.Shatter.class)); - cards.add(new SetCardInfo("Shivan Dragon", 238, Rarity.RARE, mage.cards.s.ShivanDragon.class)); - cards.add(new SetCardInfo("Simulacrum", 45, Rarity.UNCOMMON, mage.cards.s.Simulacrum.class)); cards.add(new SetCardInfo("Sindbad", 100, Rarity.UNCOMMON, mage.cards.s.Sindbad.class)); cards.add(new SetCardInfo("Siren's Call", 101, Rarity.UNCOMMON, mage.cards.s.SirensCall.class)); - cards.add(new SetCardInfo("Sisters of the Flame", 239, Rarity.COMMON, mage.cards.s.SistersOfTheFlame.class)); - cards.add(new SetCardInfo("Smoke", 240, Rarity.RARE, mage.cards.s.Smoke.class)); - cards.add(new SetCardInfo("Sorceress Queen", 46, Rarity.RARE, mage.cards.s.SorceressQueen.class)); - cards.add(new SetCardInfo("Soul Net", 364, Rarity.UNCOMMON, mage.cards.s.SoulNet.class)); cards.add(new SetCardInfo("Spell Blast", 103, Rarity.COMMON, mage.cards.s.SpellBlast.class)); - cards.add(new SetCardInfo("Spirit Link", 301, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class)); - cards.add(new SetCardInfo("Spirit Shackle", 47, Rarity.UNCOMMON, mage.cards.s.SpiritShackle.class)); cards.add(new SetCardInfo("Stasis", 104, Rarity.RARE, mage.cards.s.Stasis.class)); cards.add(new SetCardInfo("Steal Artifact", 105, Rarity.UNCOMMON, mage.cards.s.StealArtifact.class)); - cards.add(new SetCardInfo("Stone Giant", 241, Rarity.UNCOMMON, mage.cards.s.StoneGiant.class)); - cards.add(new SetCardInfo("Stone Rain", 242, Rarity.COMMON, mage.cards.s.StoneRain.class)); - cards.add(new SetCardInfo("Stream of Life", 156, Rarity.COMMON, mage.cards.s.StreamOfLife.class)); - cards.add(new SetCardInfo("Strip Mine", 189, Rarity.UNCOMMON, mage.cards.s.StripMine.class)); - cards.add(new SetCardInfo("Sunglasses of Urza", 365, Rarity.RARE, mage.cards.s.SunglassesOfUrza.class)); cards.add(new SetCardInfo("Sunken City", 106, Rarity.COMMON, mage.cards.s.SunkenCity.class)); - cards.add(new SetCardInfo("Swamp", 190, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 191, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 192, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swords to Plowshares", 302, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); - cards.add(new SetCardInfo("Sylvan Library", 157, Rarity.RARE, mage.cards.s.SylvanLibrary.class)); - cards.add(new SetCardInfo("Tawnos's Wand", 366, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class)); - cards.add(new SetCardInfo("Tawnos's Weaponry", 367, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class)); - cards.add(new SetCardInfo("Terror", 48, Rarity.COMMON, mage.cards.t.Terror.class)); - cards.add(new SetCardInfo("Tetravus", 368, Rarity.RARE, mage.cards.t.Tetravus.class)); - cards.add(new SetCardInfo("The Brute", 244, Rarity.COMMON, mage.cards.t.TheBrute.class)); - cards.add(new SetCardInfo("The Hive", 369, Rarity.RARE, mage.cards.t.TheHive.class)); - cards.add(new SetCardInfo("The Rack", 370, Rarity.UNCOMMON, mage.cards.t.TheRack.class)); - cards.add(new SetCardInfo("Thicket Basilisk", 158, Rarity.UNCOMMON, mage.cards.t.ThicketBasilisk.class)); cards.add(new SetCardInfo("Thoughtlace", 107, Rarity.RARE, mage.cards.t.Thoughtlace.class)); - cards.add(new SetCardInfo("Throne of Bone", 371, Rarity.UNCOMMON, mage.cards.t.ThroneOfBone.class)); cards.add(new SetCardInfo("Time Elemental", 108, Rarity.RARE, mage.cards.t.TimeElemental.class)); - cards.add(new SetCardInfo("Titania's Song", 160, Rarity.RARE, mage.cards.t.TitaniasSong.class)); - cards.add(new SetCardInfo("Tranquility", 161, Rarity.COMMON, mage.cards.t.Tranquility.class)); - cards.add(new SetCardInfo("Triskelion", 372, Rarity.RARE, mage.cards.t.Triskelion.class)); - cards.add(new SetCardInfo("Tsunami", 162, Rarity.UNCOMMON, mage.cards.t.Tsunami.class)); - cards.add(new SetCardInfo("Tundra Wolves", 303, Rarity.COMMON, mage.cards.t.TundraWolves.class)); - cards.add(new SetCardInfo("Tunnel", 245, Rarity.UNCOMMON, mage.cards.t.Tunnel.class)); cards.add(new SetCardInfo("Twiddle", 109, Rarity.COMMON, mage.cards.t.Twiddle.class)); - cards.add(new SetCardInfo("Uncle Istvan", 49, Rarity.UNCOMMON, mage.cards.u.UncleIstvan.class)); - cards.add(new SetCardInfo("Unholy Strength", 50, Rarity.COMMON, mage.cards.u.UnholyStrength.class)); cards.add(new SetCardInfo("Unstable Mutation", 110, Rarity.COMMON, mage.cards.u.UnstableMutation.class)); cards.add(new SetCardInfo("Unsummon", 111, Rarity.COMMON, mage.cards.u.Unsummon.class)); - cards.add(new SetCardInfo("Untamed Wilds", 163, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); - cards.add(new SetCardInfo("Uthden Troll", 246, Rarity.UNCOMMON, mage.cards.u.UthdenTroll.class)); - cards.add(new SetCardInfo("Vampire Bats", 51, Rarity.COMMON, mage.cards.v.VampireBats.class)); - cards.add(new SetCardInfo("Venom", 164, Rarity.COMMON, mage.cards.v.Venom.class)); - cards.add(new SetCardInfo("Verduran Enchantress", 165, Rarity.RARE, mage.cards.v.VerduranEnchantress.class)); cards.add(new SetCardInfo("Volcanic Eruption", 112, Rarity.RARE, mage.cards.v.VolcanicEruption.class)); cards.add(new SetCardInfo("Wall of Air", 113, Rarity.UNCOMMON, mage.cards.w.WallOfAir.class)); - cards.add(new SetCardInfo("Wall of Bone", 52, Rarity.UNCOMMON, mage.cards.w.WallOfBone.class)); - cards.add(new SetCardInfo("Wall of Brambles", 166, Rarity.UNCOMMON, mage.cards.w.WallOfBrambles.class)); - cards.add(new SetCardInfo("Wall of Fire", 248, Rarity.UNCOMMON, mage.cards.w.WallOfFire.class)); - cards.add(new SetCardInfo("Wall of Ice", 167, Rarity.UNCOMMON, mage.cards.w.WallOfIce.class)); - cards.add(new SetCardInfo("Wall of Spears", 374, Rarity.COMMON, mage.cards.w.WallOfSpears.class)); - cards.add(new SetCardInfo("Wall of Stone", 249, Rarity.UNCOMMON, mage.cards.w.WallOfStone.class)); - cards.add(new SetCardInfo("Wall of Swords", 305, Rarity.UNCOMMON, mage.cards.w.WallOfSwords.class)); cards.add(new SetCardInfo("Wall of Water", 114, Rarity.UNCOMMON, mage.cards.w.WallOfWater.class)); - cards.add(new SetCardInfo("Wall of Wood", 168, Rarity.COMMON, mage.cards.w.WallOfWood.class)); - cards.add(new SetCardInfo("Wanderlust", 169, Rarity.UNCOMMON, mage.cards.w.Wanderlust.class)); - cards.add(new SetCardInfo("War Mammoth", 170, Rarity.COMMON, mage.cards.w.WarMammoth.class)); - cards.add(new SetCardInfo("Warp Artifact", 53, Rarity.RARE, mage.cards.w.WarpArtifact.class)); cards.add(new SetCardInfo("Water Elemental", 115, Rarity.UNCOMMON, mage.cards.w.WaterElemental.class)); - cards.add(new SetCardInfo("Weakness", 54, Rarity.COMMON, mage.cards.w.Weakness.class)); - cards.add(new SetCardInfo("Web", 171, Rarity.RARE, mage.cards.w.Web.class)); - cards.add(new SetCardInfo("Whirling Dervish", 172, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class)); - cards.add(new SetCardInfo("White Knight", 306, Rarity.UNCOMMON, mage.cards.w.WhiteKnight.class)); - cards.add(new SetCardInfo("White Mana Battery", 375, Rarity.RARE, mage.cards.w.WhiteManaBattery.class)); - cards.add(new SetCardInfo("White Ward", 307, Rarity.UNCOMMON, mage.cards.w.WhiteWard.class)); - cards.add(new SetCardInfo("Wild Growth", 173, Rarity.COMMON, mage.cards.w.WildGrowth.class)); - cards.add(new SetCardInfo("Will-o'-the-Wisp", 55, Rarity.RARE, mage.cards.w.WillOTheWisp.class)); - cards.add(new SetCardInfo("Winds of Change", 250, Rarity.RARE, mage.cards.w.WindsOfChange.class)); - cards.add(new SetCardInfo("Winter Blast", 174, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class)); - cards.add(new SetCardInfo("Winter Orb", 376, Rarity.RARE, mage.cards.w.WinterOrb.class)); - cards.add(new SetCardInfo("Wooden Sphere", 377, Rarity.UNCOMMON, mage.cards.w.WoodenSphere.class)); - cards.add(new SetCardInfo("Word of Binding", 56, Rarity.COMMON, mage.cards.w.WordOfBinding.class)); - cards.add(new SetCardInfo("Wrath of God", 308, Rarity.RARE, mage.cards.w.WrathOfGod.class)); - cards.add(new SetCardInfo("Xenic Poltergeist", 57, Rarity.RARE, mage.cards.x.XenicPoltergeist.class)); - cards.add(new SetCardInfo("Yotian Soldier", 378, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); cards.add(new SetCardInfo("Zephyr Falcon", 116, Rarity.COMMON, mage.cards.z.ZephyrFalcon.class)); - cards.add(new SetCardInfo("Zombie Master", 58, Rarity.RARE, mage.cards.z.ZombieMaster.class)); + cards.add(new SetCardInfo("Aspect of Wolf", 233, Rarity.RARE, mage.cards.a.AspectOfWolf.class)); + cards.add(new SetCardInfo("Birds of Paradise", 234, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); + cards.add(new SetCardInfo("Carnivorous Plant", 235, Rarity.COMMON, mage.cards.c.CarnivorousPlant.class)); + cards.add(new SetCardInfo("Channel", 236, Rarity.UNCOMMON, mage.cards.c.Channel.class)); + cards.add(new SetCardInfo("Cockatrice", 237, Rarity.RARE, mage.cards.c.Cockatrice.class)); + cards.add(new SetCardInfo("Craw Wurm", 238, Rarity.COMMON, mage.cards.c.CrawWurm.class)); + cards.add(new SetCardInfo("Crumble", 239, Rarity.UNCOMMON, mage.cards.c.Crumble.class)); + cards.add(new SetCardInfo("Desert Twister", 240, Rarity.UNCOMMON, mage.cards.d.DesertTwister.class)); + cards.add(new SetCardInfo("Durkwood Boars", 241, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); + cards.add(new SetCardInfo("Elven Riders", 242, Rarity.UNCOMMON, mage.cards.e.ElvenRiders.class)); + cards.add(new SetCardInfo("Elvish Archers", 243, Rarity.RARE, mage.cards.e.ElvishArchers.class)); + cards.add(new SetCardInfo("Fog", 244, Rarity.COMMON, mage.cards.f.Fog.class)); + cards.add(new SetCardInfo("Force of Nature", 245, Rarity.RARE, mage.cards.f.ForceOfNature.class)); + cards.add(new SetCardInfo("Fungusaur", 246, Rarity.RARE, mage.cards.f.Fungusaur.class)); + cards.add(new SetCardInfo("Gaea's Liege", 247, Rarity.RARE, mage.cards.g.GaeasLiege.class)); + cards.add(new SetCardInfo("Giant Growth", 248, Rarity.COMMON, mage.cards.g.GiantGrowth.class)); + cards.add(new SetCardInfo("Giant Spider", 249, Rarity.COMMON, mage.cards.g.GiantSpider.class)); + cards.add(new SetCardInfo("Grizzly Bears", 250, Rarity.COMMON, mage.cards.g.GrizzlyBears.class)); + cards.add(new SetCardInfo("Hurricane", 251, Rarity.UNCOMMON, mage.cards.h.Hurricane.class)); + cards.add(new SetCardInfo("Instill Energy", 252, Rarity.UNCOMMON, mage.cards.i.InstillEnergy.class)); + cards.add(new SetCardInfo("Ironroot Treefolk", 253, Rarity.COMMON, mage.cards.i.IronrootTreefolk.class)); + cards.add(new SetCardInfo("Killer Bees", 254, Rarity.UNCOMMON, mage.cards.k.KillerBees.class)); + cards.add(new SetCardInfo("Land Leeches", 255, Rarity.COMMON, mage.cards.l.LandLeeches.class)); + cards.add(new SetCardInfo("Ley Druid", 256, Rarity.UNCOMMON, mage.cards.l.LeyDruid.class)); + cards.add(new SetCardInfo("Lifeforce", 257, Rarity.UNCOMMON, mage.cards.l.Lifeforce.class)); + cards.add(new SetCardInfo("Lifelace", 258, Rarity.RARE, mage.cards.l.Lifelace.class)); + cards.add(new SetCardInfo("Living Artifact", 259, Rarity.RARE, mage.cards.l.LivingArtifact.class)); + cards.add(new SetCardInfo("Living Lands", 260, Rarity.RARE, mage.cards.l.LivingLands.class)); + cards.add(new SetCardInfo("Llanowar Elves", 261, Rarity.COMMON, mage.cards.l.LlanowarElves.class)); + cards.add(new SetCardInfo("Lure", 262, Rarity.UNCOMMON, mage.cards.l.Lure.class)); + cards.add(new SetCardInfo("Marsh Viper", 263, Rarity.COMMON, mage.cards.m.MarshViper.class)); + cards.add(new SetCardInfo("Nafs Asp", 264, Rarity.COMMON, NafsAsp.class)); + cards.add(new SetCardInfo("Pradesh Gypsies", 265, Rarity.COMMON, mage.cards.p.PradeshGypsies.class)); + cards.add(new SetCardInfo("Radjan Spirit", 266, Rarity.UNCOMMON, mage.cards.r.RadjanSpirit.class)); + cards.add(new SetCardInfo("Regeneration", 268, Rarity.COMMON, mage.cards.r.Regeneration.class)); + cards.add(new SetCardInfo("Sandstorm", 269, Rarity.COMMON, mage.cards.s.Sandstorm.class)); + cards.add(new SetCardInfo("Scryb Sprites", 270, Rarity.COMMON, mage.cards.s.ScrybSprites.class)); + cards.add(new SetCardInfo("Shanodin Dryads", 271, Rarity.COMMON, mage.cards.s.ShanodinDryads.class)); + cards.add(new SetCardInfo("Stream of Life", 272, Rarity.COMMON, mage.cards.s.StreamOfLife.class)); + cards.add(new SetCardInfo("Sylvan Library", 273, Rarity.RARE, mage.cards.s.SylvanLibrary.class)); + cards.add(new SetCardInfo("Thicket Basilisk", 274, Rarity.UNCOMMON, mage.cards.t.ThicketBasilisk.class)); + cards.add(new SetCardInfo("Titania's Song", 276, Rarity.RARE, mage.cards.t.TitaniasSong.class)); + cards.add(new SetCardInfo("Tranquility", 277, Rarity.COMMON, mage.cards.t.Tranquility.class)); + cards.add(new SetCardInfo("Tsunami", 278, Rarity.UNCOMMON, mage.cards.t.Tsunami.class)); + cards.add(new SetCardInfo("Untamed Wilds", 279, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); + cards.add(new SetCardInfo("Venom", 280, Rarity.COMMON, mage.cards.v.Venom.class)); + cards.add(new SetCardInfo("Verduran Enchantress", 281, Rarity.RARE, mage.cards.v.VerduranEnchantress.class)); + cards.add(new SetCardInfo("Wall of Brambles", 282, Rarity.UNCOMMON, mage.cards.w.WallOfBrambles.class)); + cards.add(new SetCardInfo("Wall of Ice", 283, Rarity.UNCOMMON, mage.cards.w.WallOfIce.class)); + cards.add(new SetCardInfo("Wall of Wood", 284, Rarity.COMMON, mage.cards.w.WallOfWood.class)); + cards.add(new SetCardInfo("Wanderlust", 285, Rarity.UNCOMMON, mage.cards.w.Wanderlust.class)); + cards.add(new SetCardInfo("War Mammoth", 286, Rarity.COMMON, mage.cards.w.WarMammoth.class)); + cards.add(new SetCardInfo("Web", 287, Rarity.RARE, mage.cards.w.Web.class)); + cards.add(new SetCardInfo("Whirling Dervish", 288, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class)); + cards.add(new SetCardInfo("Wild Growth", 289, Rarity.COMMON, mage.cards.w.WildGrowth.class)); + cards.add(new SetCardInfo("Winter Blast", 290, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class)); + cards.add(new SetCardInfo("Forest", 376, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 377, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 378, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 367, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 368, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 369, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mishra's Factory", 361, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); + cards.add(new SetCardInfo("Mountain", 373, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 374, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 375, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Oasis", 362, Rarity.UNCOMMON, mage.cards.o.Oasis.class)); + cards.add(new SetCardInfo("Plains", 364, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 365, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 366, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Strip Mine", 363, Rarity.UNCOMMON, mage.cards.s.StripMine.class)); + cards.add(new SetCardInfo("Swamp", 370, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 371, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 372, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ali Baba", 175, Rarity.UNCOMMON, mage.cards.a.AliBaba.class)); + cards.add(new SetCardInfo("Ball Lightning", 176, Rarity.RARE, mage.cards.b.BallLightning.class)); + cards.add(new SetCardInfo("Bird Maiden", 177, Rarity.COMMON, mage.cards.b.BirdMaiden.class)); + cards.add(new SetCardInfo("Blood Lust", 178, Rarity.COMMON, mage.cards.b.BloodLust.class)); + cards.add(new SetCardInfo("Brothers of Fire", 179, Rarity.COMMON, mage.cards.b.BrothersOfFire.class)); + cards.add(new SetCardInfo("Burrowing", 180, Rarity.UNCOMMON, mage.cards.b.Burrowing.class)); + cards.add(new SetCardInfo("Cave People", 181, Rarity.UNCOMMON, mage.cards.c.CavePeople.class)); + cards.add(new SetCardInfo("Chaoslace", 182, Rarity.RARE, mage.cards.c.Chaoslace.class)); + cards.add(new SetCardInfo("Crimson Manticore", 183, Rarity.RARE, mage.cards.c.CrimsonManticore.class)); + cards.add(new SetCardInfo("Detonate", 184, Rarity.UNCOMMON, mage.cards.d.Detonate.class)); + cards.add(new SetCardInfo("Disintegrate", 185, Rarity.COMMON, mage.cards.d.Disintegrate.class)); + cards.add(new SetCardInfo("Dragon Whelp", 186, Rarity.UNCOMMON, mage.cards.d.DragonWhelp.class)); + cards.add(new SetCardInfo("Dwarven Warriors", 187, Rarity.COMMON, mage.cards.d.DwarvenWarriors.class)); + cards.add(new SetCardInfo("Earth Elemental", 188, Rarity.UNCOMMON, mage.cards.e.EarthElemental.class)); + cards.add(new SetCardInfo("Earthquake", 189, Rarity.RARE, mage.cards.e.Earthquake.class)); + cards.add(new SetCardInfo("Eternal Warrior", 190, Rarity.COMMON, mage.cards.e.EternalWarrior.class)); + cards.add(new SetCardInfo("Fire Elemental", 191, Rarity.UNCOMMON, mage.cards.f.FireElemental.class)); + cards.add(new SetCardInfo("Fireball", 192, Rarity.COMMON, mage.cards.f.Fireball.class)); + cards.add(new SetCardInfo("Firebreathing", 193, Rarity.COMMON, mage.cards.f.Firebreathing.class)); + cards.add(new SetCardInfo("Fissure", 194, Rarity.COMMON, mage.cards.f.Fissure.class)); + cards.add(new SetCardInfo("Flashfires", 195, Rarity.UNCOMMON, mage.cards.f.Flashfires.class)); + cards.add(new SetCardInfo("Giant Strength", 196, Rarity.COMMON, mage.cards.g.GiantStrength.class)); + cards.add(new SetCardInfo("Goblin Balloon Brigade", 197, Rarity.UNCOMMON, mage.cards.g.GoblinBalloonBrigade.class)); + cards.add(new SetCardInfo("Goblin King", 198, Rarity.RARE, mage.cards.g.GoblinKing.class)); + cards.add(new SetCardInfo("Gray Ogre", 200, Rarity.COMMON, mage.cards.g.GrayOgre.class)); + cards.add(new SetCardInfo("Hill Giant", 201, Rarity.COMMON, mage.cards.h.HillGiant.class)); + cards.add(new SetCardInfo("Hurloon Minotaur", 202, Rarity.COMMON, mage.cards.h.HurloonMinotaur.class)); + cards.add(new SetCardInfo("Hurr Jackal", 203, Rarity.RARE, mage.cards.h.HurrJackal.class)); + cards.add(new SetCardInfo("Immolation", 204, Rarity.COMMON, mage.cards.i.Immolation.class)); + cards.add(new SetCardInfo("Inferno", 205, Rarity.RARE, mage.cards.i.Inferno.class)); + cards.add(new SetCardInfo("Ironclaw Orcs", 206, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); + cards.add(new SetCardInfo("Keldon Warlord", 207, Rarity.UNCOMMON, mage.cards.k.KeldonWarlord.class)); + cards.add(new SetCardInfo("Lightning Bolt", 208, Rarity.COMMON, mage.cards.l.LightningBolt.class)); + cards.add(new SetCardInfo("Magnetic Mountain", 209, Rarity.RARE, mage.cards.m.MagneticMountain.class)); + cards.add(new SetCardInfo("Mana Clash", 210, Rarity.RARE, mage.cards.m.ManaClash.class)); + cards.add(new SetCardInfo("Mana Flare", 211, Rarity.RARE, mage.cards.m.ManaFlare.class)); + cards.add(new SetCardInfo("Manabarbs", 212, Rarity.RARE, mage.cards.m.Manabarbs.class)); + cards.add(new SetCardInfo("Mons's Goblin Raiders", 213, Rarity.COMMON, mage.cards.m.MonssGoblinRaiders.class)); + cards.add(new SetCardInfo("Orcish Artillery", 214, Rarity.UNCOMMON, mage.cards.o.OrcishArtillery.class)); + cards.add(new SetCardInfo("Orcish Oriflamme", 215, Rarity.UNCOMMON, mage.cards.o.OrcishOriflamme.class)); + cards.add(new SetCardInfo("Power Surge", 216, Rarity.RARE, mage.cards.p.PowerSurge.class)); + cards.add(new SetCardInfo("Pyrotechnics", 217, Rarity.UNCOMMON, mage.cards.p.Pyrotechnics.class)); + cards.add(new SetCardInfo("Red Elemental Blast", 218, Rarity.COMMON, mage.cards.r.RedElementalBlast.class)); + cards.add(new SetCardInfo("Shatter", 219, Rarity.COMMON, mage.cards.s.Shatter.class)); + cards.add(new SetCardInfo("Shivan Dragon", 220, Rarity.RARE, mage.cards.s.ShivanDragon.class)); + cards.add(new SetCardInfo("Sisters of the Flame", 221, Rarity.COMMON, mage.cards.s.SistersOfTheFlame.class)); + cards.add(new SetCardInfo("Smoke", 222, Rarity.RARE, mage.cards.s.Smoke.class)); + cards.add(new SetCardInfo("Stone Giant", 223, Rarity.UNCOMMON, mage.cards.s.StoneGiant.class)); + cards.add(new SetCardInfo("Stone Rain", 224, Rarity.COMMON, mage.cards.s.StoneRain.class)); + cards.add(new SetCardInfo("The Brute", 226, Rarity.COMMON, mage.cards.t.TheBrute.class)); + cards.add(new SetCardInfo("Tunnel", 227, Rarity.UNCOMMON, mage.cards.t.Tunnel.class)); + cards.add(new SetCardInfo("Uthden Troll", 228, Rarity.UNCOMMON, mage.cards.u.UthdenTroll.class)); + cards.add(new SetCardInfo("Wall of Fire", 230, Rarity.UNCOMMON, mage.cards.w.WallOfFire.class)); + cards.add(new SetCardInfo("Wall of Stone", 231, Rarity.UNCOMMON, mage.cards.w.WallOfStone.class)); + cards.add(new SetCardInfo("Winds of Change", 232, Rarity.RARE, mage.cards.w.WindsOfChange.class)); + cards.add(new SetCardInfo("Alabaster Potion", 1, Rarity.COMMON, mage.cards.a.AlabasterPotion.class)); + cards.add(new SetCardInfo("Amrou Kithkin", 2, Rarity.COMMON, mage.cards.a.AmrouKithkin.class)); + cards.add(new SetCardInfo("Angry Mob", 3, Rarity.UNCOMMON, mage.cards.a.AngryMob.class)); + cards.add(new SetCardInfo("Animate Wall", 4, Rarity.RARE, mage.cards.a.AnimateWall.class)); + cards.add(new SetCardInfo("Armageddon", 5, Rarity.RARE, mage.cards.a.Armageddon.class)); + cards.add(new SetCardInfo("Balance", 6, Rarity.RARE, mage.cards.b.Balance.class)); + cards.add(new SetCardInfo("Black Ward", 8, Rarity.UNCOMMON, mage.cards.b.BlackWard.class)); + cards.add(new SetCardInfo("Blessing", 9, Rarity.RARE, mage.cards.b.Blessing.class)); + cards.add(new SetCardInfo("Blue Ward", 10, Rarity.UNCOMMON, mage.cards.b.BlueWard.class)); + cards.add(new SetCardInfo("Brainwash", 11, Rarity.COMMON, mage.cards.b.Brainwash.class)); + cards.add(new SetCardInfo("Castle", 12, Rarity.UNCOMMON, mage.cards.c.Castle.class)); + cards.add(new SetCardInfo("Circle of Protection: Artifacts", 13, Rarity.COMMON, mage.cards.c.CircleOfProtectionArtifacts.class)); + cards.add(new SetCardInfo("Circle of Protection: Black", 14, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlack.class)); + cards.add(new SetCardInfo("Circle of Protection: Blue", 15, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlue.class)); + cards.add(new SetCardInfo("Circle of Protection: Green", 16, Rarity.COMMON, mage.cards.c.CircleOfProtectionGreen.class)); + cards.add(new SetCardInfo("Circle of Protection: Red", 17, Rarity.COMMON, mage.cards.c.CircleOfProtectionRed.class)); + cards.add(new SetCardInfo("Circle of Protection: White", 18, Rarity.COMMON, mage.cards.c.CircleOfProtectionWhite.class)); + cards.add(new SetCardInfo("Conversion", 19, Rarity.UNCOMMON, mage.cards.c.Conversion.class)); + cards.add(new SetCardInfo("Crusade", 20, Rarity.RARE, mage.cards.c.Crusade.class)); + cards.add(new SetCardInfo("Death Ward", 21, Rarity.COMMON, mage.cards.d.DeathWard.class)); + cards.add(new SetCardInfo("Disenchant", 22, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Divine Transformation", 23, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class)); + cards.add(new SetCardInfo("Elder Land Wurm", 24, Rarity.RARE, mage.cards.e.ElderLandWurm.class)); + cards.add(new SetCardInfo("Eye for an Eye", 25, Rarity.RARE, mage.cards.e.EyeForAnEye.class)); + cards.add(new SetCardInfo("Green Ward", 27, Rarity.UNCOMMON, mage.cards.g.GreenWard.class)); + cards.add(new SetCardInfo("Healing Salve", 28, Rarity.COMMON, mage.cards.h.HealingSalve.class)); + cards.add(new SetCardInfo("Holy Armor", 29, Rarity.COMMON, mage.cards.h.HolyArmor.class)); + cards.add(new SetCardInfo("Holy Strength", 30, Rarity.COMMON, mage.cards.h.HolyStrength.class)); + cards.add(new SetCardInfo("Island Sanctuary", 31, Rarity.RARE, mage.cards.i.IslandSanctuary.class)); + cards.add(new SetCardInfo("Karma", 32, Rarity.UNCOMMON, mage.cards.k.Karma.class)); + cards.add(new SetCardInfo("Kismet", 33, Rarity.UNCOMMON, mage.cards.k.Kismet.class)); + cards.add(new SetCardInfo("Land Tax", 34, Rarity.RARE, mage.cards.l.LandTax.class)); + cards.add(new SetCardInfo("Northern Paladin", 37, Rarity.RARE, mage.cards.n.NorthernPaladin.class)); + cards.add(new SetCardInfo("Osai Vultures", 38, Rarity.UNCOMMON, mage.cards.o.OsaiVultures.class)); + cards.add(new SetCardInfo("Pearled Unicorn", 39, Rarity.COMMON, mage.cards.p.PearledUnicorn.class)); + cards.add(new SetCardInfo("Personal Incarnation", 40, Rarity.RARE, mage.cards.p.PersonalIncarnation.class)); + cards.add(new SetCardInfo("Piety", 41, Rarity.COMMON, Piety.class)); + cards.add(new SetCardInfo("Purelace", 43, Rarity.RARE, mage.cards.p.Purelace.class)); + cards.add(new SetCardInfo("Red Ward", 44, Rarity.UNCOMMON, mage.cards.r.RedWard.class)); + cards.add(new SetCardInfo("Reverse Damage", 45, Rarity.RARE, mage.cards.r.ReverseDamage.class)); + 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)); + cards.add(new SetCardInfo("Tundra Wolves", 53, Rarity.COMMON, mage.cards.t.TundraWolves.class)); + cards.add(new SetCardInfo("Wall of Swords", 55, Rarity.UNCOMMON, mage.cards.w.WallOfSwords.class)); + cards.add(new SetCardInfo("White Knight", 56, Rarity.UNCOMMON, mage.cards.w.WhiteKnight.class)); + cards.add(new SetCardInfo("White Ward", 57, Rarity.UNCOMMON, mage.cards.w.WhiteWard.class)); + cards.add(new SetCardInfo("Wrath of God", 58, Rarity.RARE, mage.cards.w.WrathOfGod.class)); + cards.add(new SetCardInfo("Aladdin's Lamp", 291, Rarity.RARE, mage.cards.a.AladdinsLamp.class)); + cards.add(new SetCardInfo("Aladdin's Ring", 292, Rarity.RARE, mage.cards.a.AladdinsRing.class)); + cards.add(new SetCardInfo("Amulet of Kroog", 293, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class)); + cards.add(new SetCardInfo("Ankh of Mishra", 294, Rarity.RARE, mage.cards.a.AnkhOfMishra.class)); + cards.add(new SetCardInfo("Armageddon Clock", 295, Rarity.RARE, mage.cards.a.ArmageddonClock.class)); + cards.add(new SetCardInfo("Ashnod's Battle Gear", 296, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class)); + cards.add(new SetCardInfo("Black Mana Battery", 298, Rarity.RARE, mage.cards.b.BlackManaBattery.class)); + cards.add(new SetCardInfo("Black Vise", 299, Rarity.UNCOMMON, mage.cards.b.BlackVise.class)); + cards.add(new SetCardInfo("Blue Mana Battery", 300, Rarity.RARE, mage.cards.b.BlueManaBattery.class)); + cards.add(new SetCardInfo("Bottle of Suleiman", 301, Rarity.RARE, mage.cards.b.BottleOfSuleiman.class)); + cards.add(new SetCardInfo("Brass Man", 302, Rarity.UNCOMMON, mage.cards.b.BrassMan.class)); + cards.add(new SetCardInfo("Celestial Prism", 304, Rarity.UNCOMMON, mage.cards.c.CelestialPrism.class)); + cards.add(new SetCardInfo("Clay Statue", 305, Rarity.COMMON, mage.cards.c.ClayStatue.class)); + cards.add(new SetCardInfo("Clockwork Avian", 306, Rarity.RARE, mage.cards.c.ClockworkAvian.class)); + cards.add(new SetCardInfo("Clockwork Beast", 307, Rarity.RARE, mage.cards.c.ClockworkBeast.class)); + cards.add(new SetCardInfo("Colossus of Sardia", 308, Rarity.RARE, mage.cards.c.ColossusOfSardia.class)); + cards.add(new SetCardInfo("Conservator", 309, Rarity.UNCOMMON, mage.cards.c.Conservator.class)); + cards.add(new SetCardInfo("Coral Helm", 310, Rarity.RARE, mage.cards.c.CoralHelm.class)); + cards.add(new SetCardInfo("Crystal Rod", 311, Rarity.UNCOMMON, mage.cards.c.CrystalRod.class)); + cards.add(new SetCardInfo("Cursed Rack", 312, Rarity.UNCOMMON, mage.cards.c.CursedRack.class)); + cards.add(new SetCardInfo("Dancing Scimitar", 313, Rarity.RARE, mage.cards.d.DancingScimitar.class)); + cards.add(new SetCardInfo("Diabolic Machine", 314, Rarity.UNCOMMON, mage.cards.d.DiabolicMachine.class)); + cards.add(new SetCardInfo("Dingus Egg", 315, Rarity.RARE, mage.cards.d.DingusEgg.class)); + cards.add(new SetCardInfo("Disrupting Scepter", 316, Rarity.RARE, mage.cards.d.DisruptingScepter.class)); + cards.add(new SetCardInfo("Dragon Engine", 317, Rarity.RARE, mage.cards.d.DragonEngine.class)); + cards.add(new SetCardInfo("Ebony Horse", 318, Rarity.RARE, mage.cards.e.EbonyHorse.class)); + cards.add(new SetCardInfo("Fellwar Stone", 319, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class)); + cards.add(new SetCardInfo("Flying Carpet", 320, Rarity.RARE, mage.cards.f.FlyingCarpet.class)); + cards.add(new SetCardInfo("Glasses of Urza", 321, Rarity.UNCOMMON, mage.cards.g.GlassesOfUrza.class)); + cards.add(new SetCardInfo("Grapeshot Catapult", 322, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class)); + cards.add(new SetCardInfo("Green Mana Battery", 323, Rarity.RARE, mage.cards.g.GreenManaBattery.class)); + cards.add(new SetCardInfo("Howling Mine", 325, Rarity.RARE, mage.cards.h.HowlingMine.class)); + cards.add(new SetCardInfo("Iron Star", 326, Rarity.UNCOMMON, mage.cards.i.IronStar.class)); + cards.add(new SetCardInfo("Ivory Cup", 327, Rarity.UNCOMMON, mage.cards.i.IvoryCup.class)); + cards.add(new SetCardInfo("Ivory Tower", 328, Rarity.RARE, mage.cards.i.IvoryTower.class)); + cards.add(new SetCardInfo("Jade Monolith", 329, Rarity.RARE, mage.cards.j.JadeMonolith.class)); + cards.add(new SetCardInfo("Jandor's Saddlebags", 330, Rarity.RARE, mage.cards.j.JandorsSaddlebags.class)); + cards.add(new SetCardInfo("Jayemdae Tome", 331, Rarity.RARE, mage.cards.j.JayemdaeTome.class)); + cards.add(new SetCardInfo("Kormus Bell", 332, Rarity.RARE, mage.cards.k.KormusBell.class)); + cards.add(new SetCardInfo("Library of Leng", 333, Rarity.UNCOMMON, mage.cards.l.LibraryOfLeng.class)); + cards.add(new SetCardInfo("Mana Vault", 334, Rarity.RARE, mage.cards.m.ManaVault.class)); + cards.add(new SetCardInfo("Meekstone", 335, Rarity.RARE, mage.cards.m.Meekstone.class)); + cards.add(new SetCardInfo("Millstone", 336, Rarity.RARE, mage.cards.m.Millstone.class)); + cards.add(new SetCardInfo("Nevinyrral's Disk", 338, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); + cards.add(new SetCardInfo("Obsianus Golem", 339, Rarity.UNCOMMON, mage.cards.o.ObsianusGolem.class)); + cards.add(new SetCardInfo("Onulet", 340, Rarity.RARE, mage.cards.o.Onulet.class)); + cards.add(new SetCardInfo("Ornithopter", 341, Rarity.UNCOMMON, mage.cards.o.Ornithopter.class)); + cards.add(new SetCardInfo("Primal Clay", 342, Rarity.RARE, mage.cards.p.PrimalClay.class)); + cards.add(new SetCardInfo("Red Mana Battery", 343, Rarity.RARE, mage.cards.r.RedManaBattery.class)); + cards.add(new SetCardInfo("Rod of Ruin", 344, Rarity.UNCOMMON, mage.cards.r.RodOfRuin.class)); + cards.add(new SetCardInfo("Shapeshifter", 345, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); + cards.add(new SetCardInfo("Soul Net", 346, Rarity.UNCOMMON, mage.cards.s.SoulNet.class)); + cards.add(new SetCardInfo("Sunglasses of Urza", 347, Rarity.RARE, mage.cards.s.SunglassesOfUrza.class)); + cards.add(new SetCardInfo("Tawnos's Wand", 348, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class)); + cards.add(new SetCardInfo("Tawnos's Weaponry", 349, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class)); + cards.add(new SetCardInfo("Tetravus", 350, Rarity.RARE, mage.cards.t.Tetravus.class)); + cards.add(new SetCardInfo("The Hive", 351, Rarity.RARE, mage.cards.t.TheHive.class)); + cards.add(new SetCardInfo("The Rack", 352, Rarity.UNCOMMON, mage.cards.t.TheRack.class)); + cards.add(new SetCardInfo("Throne of Bone", 353, Rarity.UNCOMMON, mage.cards.t.ThroneOfBone.class)); + cards.add(new SetCardInfo("Triskelion", 354, Rarity.RARE, mage.cards.t.Triskelion.class)); + cards.add(new SetCardInfo("Wall of Spears", 356, Rarity.COMMON, mage.cards.w.WallOfSpears.class)); + cards.add(new SetCardInfo("White Mana Battery", 357, Rarity.RARE, mage.cards.w.WhiteManaBattery.class)); + cards.add(new SetCardInfo("Winter Orb", 358, Rarity.RARE, mage.cards.w.WinterOrb.class)); + cards.add(new SetCardInfo("Wooden Sphere", 359, Rarity.UNCOMMON, mage.cards.w.WoodenSphere.class)); + cards.add(new SetCardInfo("Yotian Soldier", 360, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); + cards.add(new SetCardInfo("Morale", 36, Rarity.COMMON, mage.cards.m.Morale.class)); } } From ab3128975acb158ec1b3b27e7e115ce73295a858 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:01:35 +0100 Subject: [PATCH 114/142] Overflow check methods in CardUtil --- Mage/src/main/java/mage/util/CardUtil.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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; + } + } From 2bb4f07df2a6c1dd7c0f010c9b26fb8a81526af1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:17:53 +0100 Subject: [PATCH 115/142] CardUtil overflow --- Mage/src/main/java/mage/players/PlayerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index a9914519a39..64c9fde58e0 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1760,7 +1760,7 @@ 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 = game.subtractWithOverflowCheck(this.life, event.getAmount()); + this.life = CardUtil.subtractWithOverflowCheck(this.life, event.getAmount()); if (!game.isSimulation()) { game.informPlayers(this.getLogName() + " loses " + event.getAmount() + " life"); } @@ -1792,7 +1792,7 @@ public abstract class PlayerImpl implements Player, Serializable { // 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 = game.addWithOverflowCheck(this.life, event.getAmount()); + this.life = CardUtil.addWithOverflowCheck(this.life, event.getAmount()); if (!game.isSimulation()) { game.informPlayers(this.getLogName() + " gains " + event.getAmount() + " life"); } From 88e421918e7b8306a49ac63a8ba0f601aa77877c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:19:33 +0100 Subject: [PATCH 116/142] CardUtil overflow --- Mage/src/main/java/mage/game/permanent/PermanentImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 34659ec7841..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; @@ -888,7 +889,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { } } else { // this.damage += actualDamage; - this.damage = game.addWithOverflowCheck(this.damage, actualDamage); + this.damage = CardUtil.addWithOverflowCheck(this.damage, actualDamage); } game.fireEvent(new DamagedCreatureEvent(objectId, sourceId, controllerId, actualDamage, combat)); return actualDamage; From c9fb762d28d4268295951455a5439572c339b731 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:30:19 +0100 Subject: [PATCH 117/142] CardUtil overflow --- Mage.Sets/src/mage/cards/a/AngrathsMarauders.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java index b7d3baf22f0..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 6314d0b3584eada9a391bafc8ea513e812c111cf Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:30:52 +0100 Subject: [PATCH 118/142] CardUtil overflow --- Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java b/Mage.Sets/src/mage/cards/a/AnthemOfRakdos.java index 46e3457cb37..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 51431c4e1b67f5c4a95285aed3e4e67ec2bab3c6 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:31:38 +0100 Subject: [PATCH 119/142] CardUtil overflow --- Mage.Sets/src/mage/cards/b/BitterFeud.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/b/BitterFeud.java b/Mage.Sets/src/mage/cards/b/BitterFeud.java index e97d01e2306..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From ae6eb7f19eae062d80fef4ffd52b96b9d3bbcdce Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:32:47 +0100 Subject: [PATCH 120/142] CardUtil overflow --- Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java b/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java index 156ef33fa17..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,7 +112,7 @@ class CurseOfBloodlettingEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } From efe2331ec4e3a3da05b0f9ac9dbfa2369aef7c9c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:34:00 +0100 Subject: [PATCH 121/142] CardUtil overflow --- Mage.Sets/src/mage/cards/d/DesperateGambit.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DesperateGambit.java b/Mage.Sets/src/mage/cards/d/DesperateGambit.java index 6e4f4b2f880..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); this.discard(); } else { preventDamageAction(event, source, game); From 4f8bcc3ce6a9c0dbb990ccc8bd8d30c2a5e3182a Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:35:13 +0100 Subject: [PATCH 122/142] CardUtil overflow --- Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java b/Mage.Sets/src/mage/cards/d/DictateOfTheTwinGods.java index bdc2dac7a71..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(game.addWithOverflowCheck(damageEvent.getAmount(), damageEvent.getAmount()), 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(game.addWithOverflowCheck(damageEvent.getAmount(), damageEvent.getAmount()), 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; } } From 43cffd10549696fe8e7e44f4a06730f182bf251b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:37:10 +0100 Subject: [PATCH 123/142] CardUtil overflow --- Mage.Sets/src/mage/cards/d/Dracoplasm.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/Dracoplasm.java b/Mage.Sets/src/mage/cards/d/Dracoplasm.java index 48d56455f1f..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 = game.addWithOverflowCheck(power, targetCreature.getPower().getValue()); - toughness = game.addWithOverflowCheck(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); From 331428b1aeee9cac2d19afbaa6ab838bc991a76e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:37:51 +0100 Subject: [PATCH 124/142] CardUtil overflow --- Mage.Sets/src/mage/cards/e/EmbermawHellion.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/e/EmbermawHellion.java b/Mage.Sets/src/mage/cards/e/EmbermawHellion.java index d56d7c9a1c6..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(game.addWithOverflowCheck(event.getAmount(), 1)); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), 1)); return false; } From a35ee6837f37ba17e55df027540940aab5a7eb52 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:38:52 +0100 Subject: [PATCH 125/142] CardUtil overflow --- Mage.Sets/src/mage/cards/f/FarrelsMantle.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/f/FarrelsMantle.java b/Mage.Sets/src/mage/cards/f/FarrelsMantle.java index b2eee44e85f..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,7 @@ class FarrelsMantleEffect extends OneShotEffect{ @Override public boolean apply(Game game, Ability source) { Permanent perm = game.getPermanent(source.getSourceId()); - int damage = game.addWithOverflowCheck(perm.getPower().getValue(), 2); + int damage = CardUtil.addWithOverflowCheck(perm.getPower().getValue(), 2); DamageTargetEffect dmgEffect = new DamageTargetEffect(damage); return dmgEffect.apply(game, source); } From c0423d96562ebd4ae1efe5aa24f283d1eed5a28a Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:39:45 +0100 Subject: [PATCH 126/142] CardUtil overflow --- Mage.Sets/src/mage/cards/f/FireServant.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/f/FireServant.java b/Mage.Sets/src/mage/cards/f/FireServant.java index b084bb2631d..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } From 8acc38e24c7041a5d02342d3f54f18a48693a76b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:40:51 +0100 Subject: [PATCH 127/142] CardUtil overflow --- Mage.Sets/src/mage/cards/f/FurnaceOfRath.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java b/Mage.Sets/src/mage/cards/f/FurnaceOfRath.java index 41e06785d73..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 8ea40bc385c929fcd7917586391b90a08b7c6166 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:41:44 +0100 Subject: [PATCH 128/142] CardUtil overflow --- Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java index ff0cd7caa0c..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + 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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); } } } From fbe280bf91154869cdc2a1893d4adfc1b0916d49 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:43:12 +0100 Subject: [PATCH 129/142] CardUtil overflow --- Mage.Sets/src/mage/cards/g/GoldnightCastigator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java b/Mage.Sets/src/mage/cards/g/GoldnightCastigator.java index b461de60e8e..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + 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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); } } } From 17e5bbbd5450ff2cc39b1b4581a36492c53c65d3 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:43:57 +0100 Subject: [PATCH 130/142] CardUtil overflow --- Mage.Sets/src/mage/cards/g/GratuitousViolence.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/g/GratuitousViolence.java b/Mage.Sets/src/mage/cards/g/GratuitousViolence.java index 7dab860ff64..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 67d495e1cebe88f40ef50a180284926dbc1aac10 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:45:21 +0100 Subject: [PATCH 131/142] CardUtil overflow --- Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java b/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java index 7fc226aa004..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); this.discard(); } else { preventDamageAction(event, source, game); From a098b12d3c6f104d6ab745043ba8a92e13d6d12d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:46:28 +0100 Subject: [PATCH 132/142] CardUtil overflow --- Mage.Sets/src/mage/cards/i/InquisitorsFlail.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java b/Mage.Sets/src/mage/cards/i/InquisitorsFlail.java index 7cb40b89162..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } From b10bb83727c5c9a03b4b5bb8506eda26d392d7be Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:47:24 +0100 Subject: [PATCH 133/142] CardUtil overflow --- Mage.Sets/src/mage/cards/i/InsultInjury.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/InsultInjury.java b/Mage.Sets/src/mage/cards/i/InsultInjury.java index 3e22fc7d0da..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 2643f552e4c6f9dacb51978c9401486a20bae0ba Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:49:39 +0100 Subject: [PATCH 134/142] CardUtil overflow --- Mage.Sets/src/mage/cards/o/Overblaze.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/Overblaze.java b/Mage.Sets/src/mage/cards/o/Overblaze.java index 836f1d1fce1..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,7 +104,7 @@ class FireServantEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } From c7db369effdca082d0284b11be0bbf9f5d0e6651 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:50:52 +0100 Subject: [PATCH 135/142] CardUtil overflow --- Mage.Sets/src/mage/cards/p/Phthisis.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/Phthisis.java b/Mage.Sets/src/mage/cards/p/Phthisis.java index b3c8fff54b1..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 = game.addWithOverflowCheck(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); From 34282dbd724789d31964c2803349cf7d17c8f0a4 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:51:41 +0100 Subject: [PATCH 136/142] CardUtil overflow --- Mage.Sets/src/mage/cards/p/PredatorsRapport.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/PredatorsRapport.java b/Mage.Sets/src/mage/cards/p/PredatorsRapport.java index 989e0258ed3..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 game.addWithOverflowCheck(sourcePermanent.getPower().getValue(), sourcePermanent.getToughness().getValue()); + return CardUtil.addWithOverflowCheck(sourcePermanent.getPower().getValue(), sourcePermanent.getToughness().getValue()); } return 0; } From 88e89b1f7814c385684d260630d8965c4d393b8a Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:52:54 +0100 Subject: [PATCH 137/142] CardUtil overflow --- Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java b/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java index 7f9cdbe2025..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(game.addWithOverflowCheck(event.getAmount(), 2)); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), 2)); return false; } From 628ae05f54a38594fbad9e3cbf218161f82a33f0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:53:27 +0100 Subject: [PATCH 138/142] CardUtil overflow --- Mage.Sets/src/mage/cards/p/PyromancersSwath.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/PyromancersSwath.java b/Mage.Sets/src/mage/cards/p/PyromancersSwath.java index 4e012805316..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(game.addWithOverflowCheck(event.getAmount(), 2)); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), 2)); return false; } From 6dc7d6e403236be19d2c62e45f9558db0d694c4b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:54:12 +0100 Subject: [PATCH 139/142] CardUtil overflow --- Mage.Sets/src/mage/cards/q/QuestForPureFlame.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java b/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java index 90cf5b24b1d..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(game.addWithOverflowCheck(event.getAmount(), event.getAmount())); + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } From 2174f4d303b156a35b25c772f2598432ece62780 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:55:39 +0100 Subject: [PATCH 140/142] CardUtil overflow --- Mage.Sets/src/mage/cards/s/Sentinel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/Sentinel.java b/Mage.Sets/src/mage/cards/s/Sentinel.java index d5d2518b1fe..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 = game.addWithOverflowCheck(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; } From c4334ef0436227a25885dec3b88d3fbb111e064b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:58:31 +0100 Subject: [PATCH 141/142] Moved overflow check method to CardUtil --- Mage/src/main/java/mage/game/GameImpl.java | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index f755e673343..7b5e10477b5 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -3000,26 +3000,4 @@ public abstract class GameImpl implements Game, Serializable { fireEvent(new GameEvent(GameEvent.EventType.BECOMES_MONARCH, monarchId, source == null ? null : source.getSourceId(), monarchId)); } } - - @Override - public 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; - } - - @Override - public 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; - } } From 688e0658b7f4e269c4d5ac65144b907572761dc0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sat, 23 Dec 2017 23:58:40 +0100 Subject: [PATCH 142/142] Moved overflow check method to CardUtil --- Mage/src/main/java/mage/game/Game.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index af57f22d9c8..3956dd24b7b 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -466,8 +466,4 @@ public interface Game extends MageItem, Serializable { UUID getMonarchId(); void setMonarchId(Ability source, UUID monarchId); - - int addWithOverflowCheck(int base, int increment); - - int subtractWithOverflowCheck(int base, int decrement); }