diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AvacynsJudgment.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AvacynsJudgment.java new file mode 100644 index 0000000000..82ca6beeb3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AvacynsJudgment.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.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.game.Game; +import mage.target.common.TargetCreatureOrPlayerAmount; + +/** + * + * @author LevelX2 + */ +public class AvacynsJudgment extends CardImpl { + + public AvacynsJudgment(UUID ownerId) { + super(ownerId, 145, "Avacyn's Judgment", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{1}{R}"); + this.expansionSetCode = "SOI"; + + // Madness {X}{R} + Ability ability = new MadnessAbility(this, new ManaCostsImpl("{X}{R}")); + ability.setRuleAtTheTop(true); + this.addAbility(ability); + + // Avacyn's Judgment deals 2 damage divided as you choose among any number of target creatures and/or players. If Avacyn's Judgment's madness cost was paid, it deals X damage divided as you choose among those creatures and/or players instead. + DynamicValue xValue = new AvacynsJudgmentManacostVariableValue(); + Effect effect = new DamageMultiEffect(xValue); + effect.setText("{this} deals 2 damage divided as you choose among any number of target creatures and/or players. If {this}'s madness cost was paid, it deals X damage divided as you choose among those creatures and/or players instead."); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayerAmount(xValue)); + } + + public AvacynsJudgment(final AvacynsJudgment card) { + super(card); + } + + @Override + public AvacynsJudgment copy() { + return new AvacynsJudgment(this); + } +} + +class AvacynsJudgmentManacostVariableValue implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + ManaCosts manaCosts = sourceAbility.getManaCostsToPay(); + if (manaCosts.getVariableCosts().isEmpty()) { + return 2; + } + return sourceAbility.getManaCostsToPay().getX(); + } + + @Override + public AvacynsJudgmentManacostVariableValue copy() { + return new AvacynsJudgmentManacostVariableValue(); + } + + @Override + public String toString() { + return "X"; + } + + @Override + public String getMessage() { + return ""; + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/BloodmadVampire.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/BloodmadVampire.java new file mode 100644 index 0000000000..58edd29472 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/BloodmadVampire.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; + +/** + * + * @author LevelX2 + */ +public class BloodmadVampire extends CardImpl { + + public BloodmadVampire(UUID ownerId) { + super(ownerId, 146, "Bloodmad Vampire", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "SOI"; + this.subtype.add("Vampire"); + this.subtype.add("Berserker"); + this.power = new MageInt(4); + this.toughness = new MageInt(1); + + // Whenever Bloodmad Vampire deals combat damage to a player, put a +1/+1 counter on it. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), false)); + + // Madness {1}{R} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}"))); + } + + public BloodmadVampire(final BloodmadVampire card) { + super(card); + } + + @Override + public BloodmadVampire copy() { + return new BloodmadVampire(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/DissensionInTheRank.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/DissensionInTheRank.java new file mode 100644 index 0000000000..234991863e --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/DissensionInTheRank.java @@ -0,0 +1,97 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.BlockingPredicate; +import mage.game.Game; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class DissensionInTheRank extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("blocking creature"); + + static { + filter.add(new BlockingPredicate()); + } + + public DissensionInTheRank(UUID ownerId) { + super(ownerId, 152, "Dissension in the Rank", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{3}{R}{R}"); + this.expansionSetCode = "SOI"; + + // Target blocking creature fights another target blocking creature. + this.getSpellAbility().addEffect(new FightTargetsEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().addTarget(new TargetOtherCreaturePermanent(filter)); + + } + + public DissensionInTheRank(final DissensionInTheRank card) { + super(card); + } + + @Override + public DissensionInTheRank copy() { + return new DissensionInTheRank(this); + } +} + +class TargetOtherCreaturePermanent extends TargetCreaturePermanent { + + public TargetOtherCreaturePermanent(FilterCreaturePermanent filter) { + super(1, 1, filter, false); + } + + public TargetOtherCreaturePermanent(final TargetOtherCreaturePermanent target) { + super(target); + } + + @Override + public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { + if (source.getTargets().get(0).getTargets().contains(id)) { + return false; + } + return super.canTarget(controllerId, id, source, game); + } + + @Override + public TargetOtherCreaturePermanent copy() { + return new TargetOtherCreaturePermanent(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/DualShot.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/DualShot.java new file mode 100644 index 0000000000..8e833b23e6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/DualShot.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.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class DualShot extends CardImpl { + + public DualShot(UUID ownerId) { + super(ownerId, 153, "Dual Shot", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "SOI"; + + // Dual Shot deals 1 damage to each of up to two target creatures. + Effect effect = new DamageTargetEffect(1); + effect.setText("{this} deals 1 damage to each of up to two target creatures"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + } + + public DualShot(final DualShot card) { + super(card); + } + + @Override + public DualShot copy() { + return new DualShot(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GatstafArsonists.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GatstafArsonists.java new file mode 100644 index 0000000000..47e67fc86b --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GatstafArsonists.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.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author LevelX2 + */ +public class GatstafArsonists extends CardImpl { + + public GatstafArsonists(UUID ownerId) { + super(ownerId, 158, "Gatstaf Arsonists", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{R}"); + this.expansionSetCode = "SOI"; + this.subtype.add("Human"); + this.subtype.add("Werewolf"); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + this.canTransform = true; + this.secondSideCard = new GatstafRavagers(ownerId); + + // At the beginning of each upkeep, if no spells were cast last turn, transform Gatstaf Arsonists. + this.addAbility(new TransformAbility()); + TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false); + this.addAbility(new ConditionalTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.NO_SPELLS_TRANSFORM_RULE)); + } + + public GatstafArsonists(final GatstafArsonists card) { + super(card); + } + + @Override + public GatstafArsonists copy() { + return new GatstafArsonists(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GatstafRavagers.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GatstafRavagers.java new file mode 100644 index 0000000000..d2e94c23b6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GatstafRavagers.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author LevelX2 + */ +public class GatstafRavagers extends CardImpl { + + public GatstafRavagers(UUID ownerId) { + super(ownerId, 158, "Gatstaf Ravagers", Rarity.COMMON, new CardType[]{CardType.CREATURE}, ""); + this.expansionSetCode = "SOI"; + this.subtype.add("Werewolf"); + this.power = new MageInt(6); + this.toughness = new MageInt(5); + + this.canTransform = true; + this.nightCard = true; + + // Menace + this.addAbility(new MenaceAbility()); + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Gatstaf Ravagers. + TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false); + this.addAbility(new ConditionalTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE)); + } + + public GatstafRavagers(final GatstafRavagers card) { + super(card); + } + + @Override + public GatstafRavagers copy() { + return new GatstafRavagers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GeierReachBandit.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GeierReachBandit.java new file mode 100644 index 0000000000..ae4e72bff8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/GeierReachBandit.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.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author LevelX2 + */ +public class GeierReachBandit extends CardImpl { + + public GeierReachBandit(UUID ownerId) { + super(ownerId, 159, "Geier Reach Bandit", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "SOI"; + this.subtype.add("Human"); + this.subtype.add("Rogue"); + this.subtype.add("Werewolf"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + this.canTransform = true; + this.secondSideCard = new VildinPackAlpha(ownerId); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // At the beginning of each upkeep, if no spells were cast last turn, transform Geier Reach Bandit. + this.addAbility(new TransformAbility()); + TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false); + this.addAbility(new ConditionalTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.NO_SPELLS_TRANSFORM_RULE)); + } + + public GeierReachBandit(final GeierReachBandit card) { + super(card); + } + + @Override + public GeierReachBandit copy() { + return new GeierReachBandit(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/Geistblast.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/Geistblast.java new file mode 100644 index 0000000000..f4d8f7503e --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/Geistblast.java @@ -0,0 +1,90 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.ExileSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CopyTargetSpellEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetSpell; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LevelX2 + */ +public class Geistblast extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("instant or sorcery spell you control"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY))); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public Geistblast(UUID ownerId) { + super(ownerId, 160, "Geistblast", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{R}"); + this.expansionSetCode = "SOI"; + + // Geistblast deals 2 damage to target creature or player. + this.getSpellAbility().addEffect(new DamageTargetEffect(2)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + + // {2}{U}, Exile Geist from your graveyard: Copy target instant or sorcery you control. You may choose new targets for the copy. + Ability ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new CopyTargetSpellEffect(), new ManaCostsImpl<>("{2}{U}")); + ability.addTarget(new TargetSpell(filter)); + ExileSourceCost cost = new ExileSourceCost(); + cost.setText("Exile {this} from your graveyard"); + ability.addCost(cost); + this.addAbility(ability); + + } + + public Geistblast(final Geistblast card) { + super(card); + } + + @Override + public Geistblast copy() { + return new Geistblast(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/HowlpackWolf.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/HowlpackWolf.java new file mode 100644 index 0000000000..ca2707659d --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/HowlpackWolf.java @@ -0,0 +1,108 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.shadowsoverinnistrad; + +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.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +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.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class HowlpackWolf extends CardImpl { + + public HowlpackWolf(UUID ownerId) { + super(ownerId, 164, "Howlpack Wolf", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "SOI"; + this.subtype.add("Wolf"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Howlpack Wolf can't block unless you control another Wolf or Werewolf. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HowlpackWolfRestrictionEffect())); + } + + public HowlpackWolf(final HowlpackWolf card) { + super(card); + } + + @Override + public HowlpackWolf copy() { + return new HowlpackWolf(this); + } +} + +class HowlpackWolfRestrictionEffect extends RestrictionEffect { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Wolf or Werewolf"); + + static { + filter.add(Predicates.or(new SubtypePredicate("Wolf"), new SubtypePredicate("Werewolf"))); + filter.add(new AnotherPredicate()); + } + + public HowlpackWolfRestrictionEffect() { + super(Duration.WhileOnBattlefield); + + staticText = "{this} can't block unless you control another Wolf or Werewolf"; + } + + public HowlpackWolfRestrictionEffect(final HowlpackWolfRestrictionEffect effect) { + super(effect); + } + + @Override + public HowlpackWolfRestrictionEffect copy() { + return new HowlpackWolfRestrictionEffect(this); + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { + return false; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return permanent.getId().equals(source.getSourceId()) + && game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) == 0; + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/VildinPackAlpha.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/VildinPackAlpha.java new file mode 100644 index 0000000000..9f1035d811 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/VildinPackAlpha.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.shadowsoverinnistrad; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class VildinPackAlpha extends CardImpl { + + public VildinPackAlpha(UUID ownerId) { + super(ownerId, 159, "Vildin-Pack Alpha", Rarity.RARE, new CardType[]{CardType.CREATURE}, ""); + this.expansionSetCode = "SOI"; + this.subtype.add("Werewolf"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + this.canTransform = true; + this.nightCard = true; + + // Whenever a Werewolf enters the battlefield under your control, you may transform it. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new VildinPackAlphaEffect(), new FilterCreaturePermanent("Werewolf", "a Werewolf"), true, SetTargetPointer.PERMANENT, null)); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Vildin-Pack Alpha. + TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false); + this.addAbility(new ConditionalTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE)); + + } + + public VildinPackAlpha(final VildinPackAlpha card) { + super(card); + } + + @Override + public VildinPackAlpha copy() { + return new VildinPackAlpha(this); + } +} + +class VildinPackAlphaEffect extends OneShotEffect { + + public VildinPackAlphaEffect() { + super(Outcome.Benefit); + this.staticText = "you may transform it"; + } + + public VildinPackAlphaEffect(final VildinPackAlphaEffect effect) { + super(effect); + } + + @Override + public VildinPackAlphaEffect copy() { + return new VildinPackAlphaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent werewolf = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (werewolf != null && werewolf.canTransform()) { + werewolf.transform(game); + } + return true; + } + game.getBattlefield().getAllActivePermanents(controllerPermanentId); + return false; + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MadnessTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MadnessTest.java index 5a21a905c9..f21b2e3256 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MadnessTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MadnessTest.java @@ -129,4 +129,32 @@ public class MadnessTest extends CardTestPlayerBase { } + @Test + public void testAvacynsJudgment() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); + + // Madness {X}{R} + // Avacyn's Judgment deals 2 damage divided as you choose among any number of target creatures and/or players. If Avacyn's Judgment's madness cost was paid, it deals X damage divided as you choose among those creatures and/or players instead. + addCard(Zone.HAND, playerA, "Avacyn's Judgment", 1); + + addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 6); + // Target player discards two cards. If you cast this spell during your main phase, that player discards four cards instead. + addCard(Zone.HAND, playerB, "Haunting Hymn"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Haunting Hymn", playerA); + setChoice(playerA, "Yes"); + setChoice(playerA, "X=4"); + addTarget(playerA, "Pillarfield Ox"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, "Haunting Hymn", 1); + assertGraveyardCount(playerA, "Avacyn's Judgment", 1); + assertGraveyardCount(playerB, "Pillarfield Ox", 1); + + } + }