diff --git a/Mage.Client/release/sample-decks/2013/Standard/DailyMTG/Robert Seder's Esper Control.dck b/Mage.Client/release/sample-decks/2013/Standard/DailyMTG/Robert Seder's Esper Control.dck new file mode 100644 index 00000000000..a5e7c1ed67d --- /dev/null +++ b/Mage.Client/release/sample-decks/2013/Standard/DailyMTG/Robert Seder's Esper Control.dck @@ -0,0 +1,33 @@ +NAME:Robert Seder's Esper Control +1 [DKA:142] Sorin, Lord of Innistrad +1 [DGM:11] AEtherling +4 [M13:225] Glacial Fortress +3 [ISD:83] Think Twice +3 [RTR:145] Azorius Charm +4 [ISD:78] Snapcaster Mage +2 [RTR:54] Syncopate +4 [GTC:249] Watery Grave +1 [M13:56] Jace, Memory Adept +1 [RTR:35] Cyclonic Rift +1 [AVR:79] Tamiyo, the Moon Sage +1 [AVR:32] Restoration Angel +2 [RTR:44] Jace, Architect of Thought +4 [ISD:242] Isolated Chapel +4 [DGM:127] Far // Away +4 [ISD:245] Nephalia Drownyard +2 [ISD:53] Dissipate +4 [AVR:38] Terminus +4 [RTR:241] Hallowed Fountain +4 [M13:223] Drowned Catacomb +3 [GTC:242] Godless Shrine +4 [RTR:200] Sphinx's Revelation +SB: 2 [DKA:76] Tragic Slip +SB: 2 [M13:26] Planar Cleansing +SB: 1 [GTC:63] Devour Flesh +SB: 1 [ISD:212] Evil Twin +SB: 1 [RTR:18] Rest in Peace +SB: 1 [ISD:27] Purify the Grave +SB: 3 [M13:62] Negate +SB: 1 [RTR:47] Psychic Spiral +SB: 1 [M13:56] Jace, Memory Adept +SB: 1 [ISD:119] Tribute to Hunger diff --git a/Mage.Sets/src/mage/sets/Magic2014.java b/Mage.Sets/src/mage/sets/Magic2014.java new file mode 100644 index 00000000000..390c116dec7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/Magic2014.java @@ -0,0 +1,55 @@ +/* + * 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; + +import java.util.GregorianCalendar; +import mage.cards.ExpansionSet; +import mage.constants.SetType; + +/** + * + * @author North + */ +public class Magic2014 extends ExpansionSet { + + private static final Magic2014 fINSTANCE = new Magic2014(); + + public static Magic2014 getInstance() { + return fINSTANCE; + } + + private Magic2014() { + super("Magic 2014", "M14", "mage.sets.magic2014", new GregorianCalendar(2013, 19, 7).getTime(), SetType.CORE); + this.hasBoosters = true; + this.numBoosterLands = 1; + this.numBoosterCommon = 10; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 8; + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/DeathbringerThoctar.java b/Mage.Sets/src/mage/sets/alarareborn/DeathbringerThoctar.java new file mode 100644 index 00000000000..9723565992d --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/DeathbringerThoctar.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.alarareborn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author jeffwadsworth + */ +public class DeathbringerThoctar extends CardImpl { + + public DeathbringerThoctar(UUID ownerId) { + super(ownerId, 36, "Deathbringer Thoctar", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{B}{R}"); + this.expansionSetCode = "ARB"; + this.subtype.add("Zombie"); + this.subtype.add("Beast"); + + this.color.setRed(true); + this.color.setBlack(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever another creature dies, you may put a +1/+1 counter on Deathbringer Thoctar. + this.addAbility(new DiesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true, true)); + + // Remove a +1/+1 counter from Deathbringer Thoctar: Deathbringer Thoctar deals 1 damage to target creature or player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public DeathbringerThoctar(final DeathbringerThoctar card) { + super(card); + } + + @Override + public DeathbringerThoctar copy() { + return new DeathbringerThoctar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/DoubleNegative.java b/Mage.Sets/src/mage/sets/alarareborn/DoubleNegative.java new file mode 100644 index 00000000000..4fb2cadd7d6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/DoubleNegative.java @@ -0,0 +1,67 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterSpell; +import mage.target.TargetSpell; + +/** + * + * @author jeffwadsworth + */ +public class DoubleNegative extends CardImpl { + + public DoubleNegative(UUID ownerId) { + super(ownerId, 87, "Double Negative", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{U}{U}{R}"); + this.expansionSetCode = "ARB"; + + this.color.setRed(true); + this.color.setBlue(true); + + // Counter up to two target spells. + Effect effect = new CounterTargetEffect(); + effect.setText("Counter up to two target spells"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetSpell(0, 2, new FilterSpell())); + } + + public DoubleNegative(final DoubleNegative card) { + super(card); + } + + @Override + public DoubleNegative copy() { + return new DoubleNegative(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/DragonAppeasement.java b/Mage.Sets/src/mage/sets/alarareborn/DragonAppeasement.java new file mode 100644 index 00000000000..7ebc43da3ca --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/DragonAppeasement.java @@ -0,0 +1,143 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author jeffwadsworth + */ +public class DragonAppeasement extends CardImpl { + + public DragonAppeasement(UUID ownerId) { + super(ownerId, 115, "Dragon Appeasement", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{R}{G}"); + this.expansionSetCode = "ARB"; + + this.color.setRed(true); + this.color.setGreen(true); + this.color.setBlack(true); + + // Skip your draw step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipYourDrawStepEffect())); + + // Whenever you sacrifice a creature, you may draw a card. + this.addAbility(new DragonAppeasementTriggeredAbility()); + + } + + public DragonAppeasement(final DragonAppeasement card) { + super(card); + } + + @Override + public DragonAppeasement copy() { + return new DragonAppeasement(this); + } +} + +class SkipYourDrawStepEffect extends ReplacementEffectImpl { + + public SkipYourDrawStepEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + staticText = "Skip your draw step"; + } + + public SkipYourDrawStepEffect(final SkipYourDrawStepEffect effect) { + super(effect); + } + + @Override + public SkipYourDrawStepEffect copy() { + return new SkipYourDrawStepEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == GameEvent.EventType.DRAW_STEP + && (event.getPlayerId().equals(source.getControllerId()))) { + return true; + } + return false; + } +} + +class DragonAppeasementTriggeredAbility extends TriggeredAbilityImpl { + + public DragonAppeasementTriggeredAbility() { + super(Zone.BATTLEFIELD, new DrawCardControllerEffect(1), true); + } + + public DragonAppeasementTriggeredAbility(final DragonAppeasementTriggeredAbility ability) { + super(ability); + } + + @Override + public DragonAppeasementTriggeredAbility copy() { + return new DragonAppeasementTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT + && event.getPlayerId().equals(this.getControllerId()) + && game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).getCardType().contains(CardType.CREATURE)) { + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you sacrifice a creature, " + super.getRule(); + } +} + diff --git a/Mage.Sets/src/mage/sets/alarareborn/GodtrackerOfJund.java b/Mage.Sets/src/mage/sets/alarareborn/GodtrackerOfJund.java new file mode 100644 index 00000000000..3477f083c94 --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/GodtrackerOfJund.java @@ -0,0 +1,80 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.Filter; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; + +/** + * + * @author jeffwadsworth + */ +public class GodtrackerOfJund extends CardImpl { + + final private static FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(new PowerPredicate(Filter.ComparisonType.GreaterThan, 4)); + } + + String rule = "Whenever a creature with power 5 or greater enters the battlefield under your control, you may put a +1/+1 counter on Godtracker of Jund."; + + public GodtrackerOfJund(UUID ownerId) { + super(ownerId, 55, "Godtracker of Jund", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}{G}"); + this.expansionSetCode = "ARB"; + this.subtype.add("Elf"); + this.subtype.add("Shaman"); + + this.color.setRed(true); + this.color.setGreen(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever a creature with power 5 or greater enters the battlefield under your control, you may put a +1/+1 counter on Godtracker of Jund. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter, true, rule, true)); + } + + public GodtrackerOfJund(final GodtrackerOfJund card) { + super(card); + } + + @Override + public GodtrackerOfJund copy() { + return new GodtrackerOfJund(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/JundSojourners.java b/Mage.Sets/src/mage/sets/alarareborn/JundSojourners.java new file mode 100644 index 00000000000..f3fd621bd93 --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/JundSojourners.java @@ -0,0 +1,81 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.CycleTriggeredAbility; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author jeffwadsworth + */ +public class JundSojourners extends CardImpl { + + public JundSojourners(UUID ownerId) { + super(ownerId, 116, "Jund Sojourners", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{B}{R}{G}"); + this.expansionSetCode = "ARB"; + this.subtype.add("Viashino"); + this.subtype.add("Shaman"); + + this.color.setRed(true); + this.color.setGreen(true); + this.color.setBlack(true); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When you cycle Jund Sojourners or it dies, you may have it deal 1 damage to target creature or player. + Ability ability1 = new CycleTriggeredAbility(new DamageTargetEffect(1)); + Ability ability2 = new DiesTriggeredAbility(new DamageTargetEffect(1)); + ability1.addTarget(new TargetCreatureOrPlayer()); + ability2.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability1); + this.addAbility(ability2); + + // Cycling {2}{R} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}{R}"))); + } + + public JundSojourners(final JundSojourners card) { + super(card); + } + + @Override + public JundSojourners copy() { + return new JundSojourners(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/KarrthusTyrantOfJund.java b/Mage.Sets/src/mage/sets/alarareborn/KarrthusTyrantOfJund.java new file mode 100644 index 00000000000..7f5033748ee --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/KarrthusTyrantOfJund.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.sets.alarareborn; + +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continious.GainAbilityAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author jeffwadsworth + */ +public class KarrthusTyrantOfJund extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("all dragons you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new SubtypePredicate("Dragon")); + } + + public KarrthusTyrantOfJund(UUID ownerId) { + super(ownerId, 117, "Karrthus, Tyrant of Jund", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{4}{B}{R}{G}"); + this.expansionSetCode = "ARB"; + this.supertype.add("Legendary"); + this.subtype.add("Dragon"); + + this.color.setRed(true); + this.color.setGreen(true); + this.color.setBlack(true); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // When Karrthus, Tyrant of Jund enters the battlefield, gain control of all Dragons, then untap all Dragons. + this.addAbility(new EntersBattlefieldTriggeredAbility(new KarrthusEffect())); + + // Other Dragon creatures you control have haste. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true))); + + } + + public KarrthusTyrantOfJund(final KarrthusTyrantOfJund card) { + super(card); + } + + @Override + public KarrthusTyrantOfJund copy() { + return new KarrthusTyrantOfJund(this); + } +} + +class KarrthusEffect extends OneShotEffect { + + public KarrthusEffect() { + super(Outcome.GainControl); + this.staticText = "gain control of all dragons"; + } + + public KarrthusEffect(final KarrthusEffect effect) { + super(effect); + } + + @Override + public KarrthusEffect copy() { + return new KarrthusEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + FilterPermanent filter = new FilterPermanent(); + filter.add(new SubtypePredicate("Dragon")); + List dragons = game.getBattlefield().getAllActivePermanents(filter, game); + for (Permanent dragon : dragons) { + ContinuousEffect effect = new KarrthusControlEffect(source.getControllerId()); + effect.setTargetPointer(new FixedTarget(dragon.getId())); + game.addEffect(effect, source); + } + for (Permanent dragon : dragons) { + dragon.untap(game); + } + return true; + } +} + +class KarrthusControlEffect extends ContinuousEffectImpl { + + private UUID controllerId; + + public KarrthusControlEffect(UUID controllerId) { + super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); + this.controllerId = controllerId; + } + + public KarrthusControlEffect(final KarrthusControlEffect effect) { + super(effect); + this.controllerId = effect.controllerId; + } + + @Override + public KarrthusControlEffect copy() { + return new KarrthusControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent dragon = game.getPermanent(targetPointer.getFirst(game, source)); + if (dragon != null && controllerId != null) { + return dragon.changeControllerId(controllerId, game); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/KnightOfNewAlara.java b/Mage.Sets/src/mage/sets/alarareborn/KnightOfNewAlara.java new file mode 100644 index 00000000000..505fbc33c52 --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/KnightOfNewAlara.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.sets.alarareborn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.continious.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.MulticoloredPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author jeffwadsworth + */ +public class KnightOfNewAlara extends CardImpl { + + public KnightOfNewAlara(UUID ownerId) { + super(ownerId, 70, "Knight of New Alara", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{G}{W}"); + this.expansionSetCode = "ARB"; + this.subtype.add("Human"); + this.subtype.add("Knight"); + + this.color.setGreen(true); + this.color.setWhite(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Each other multicolored creature you control gets +1/+1 for each of its colors. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KnightOfNewAlaraEffect())); + + } + + public KnightOfNewAlara(final KnightOfNewAlara card) { + super(card); + } + + @Override + public KnightOfNewAlara copy() { + return new KnightOfNewAlara(this); + } +} + +class KnightOfNewAlaraEffect extends ContinuousEffectImpl { + + public KnightOfNewAlaraEffect() { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.BoostCreature); + staticText = "Each other multicolored creature you control gets +1/+1 for each of its colors"; + } + + public KnightOfNewAlaraEffect(final KnightOfNewAlaraEffect effect) { + super(effect); + } + + @Override + public KnightOfNewAlaraEffect copy() { + return new KnightOfNewAlaraEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); + filter.add(new MulticoloredPredicate()); + for (Permanent creature : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { + DynamicValue colors = new KnightOfNewAlaraColorCount(creature); + if (creature != null + && creature != game.getPermanent(source.getSourceId())) { + creature.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(colors, colors, Duration.WhileOnBattlefield)), source.getId(), game); + } + } + return true; + } +} + +class KnightOfNewAlaraColorCount implements DynamicValue { + + final Permanent creature; + private int count; + + public KnightOfNewAlaraColorCount(Permanent creature) { + this.creature = creature; + this.count = 0; + } + + public KnightOfNewAlaraColorCount(final KnightOfNewAlaraColorCount dynamicValue) { + this.creature = dynamicValue.creature; + this.count = dynamicValue.count; + } + + @Override + public int calculate(Game game, Ability source) { + if (creature != null) { + count = creature.getColor().getColorCount(); + } + return count; + } + + @Override + public DynamicValue copy() { + return new KnightOfNewAlaraColorCount(this); + } + + @Override + public String toString() { + return "1"; + } + + @Override + public String getMessage() { + return "of its colors"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/alarareborn/LeoninArmorguard.java b/Mage.Sets/src/mage/sets/alarareborn/LeoninArmorguard.java new file mode 100644 index 00000000000..17ffd5b5ebf --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/LeoninArmorguard.java @@ -0,0 +1,77 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continious.BoostAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author jeffwadsworth + */ +public class LeoninArmorguard extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public LeoninArmorguard(UUID ownerId) { + super(ownerId, 72, "Leonin Armorguard", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}{W}"); + this.expansionSetCode = "ARB"; + this.subtype.add("Cat"); + this.subtype.add("Soldier"); + + this.color.setGreen(true); + this.color.setWhite(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Leonin Armorguard enters the battlefield, creatures you control get +1/+1 until end of turn. + this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false))); + } + + public LeoninArmorguard(final LeoninArmorguard card) { + super(card); + } + + @Override + public LeoninArmorguard copy() { + return new LeoninArmorguard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/RebornHope.java b/Mage.Sets/src/mage/sets/alarareborn/RebornHope.java new file mode 100644 index 00000000000..2ee8ed947cc --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/RebornHope.java @@ -0,0 +1,71 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.MulticoloredPredicate; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author jeffwadsworth + */ +public class RebornHope extends CardImpl { + + private static final FilterCard filter = new FilterCard("multicolored card from your graveyard"); + + static { + filter.add(new MulticoloredPredicate()); + } + + public RebornHope(UUID ownerId) { + super(ownerId, 76, "Reborn Hope", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{G}{W}"); + this.expansionSetCode = "ARB"; + + this.color.setGreen(true); + this.color.setWhite(true); + + // Return target multicolored card from your graveyard to your hand. + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter)); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect()); + } + + public RebornHope(final RebornHope card) { + super(card); + } + + @Override + public RebornHope copy() { + return new RebornHope(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/ShieldOfTheRighteous.java b/Mage.Sets/src/mage/sets/alarareborn/ShieldOfTheRighteous.java new file mode 100644 index 00000000000..9f77c7164ac --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/ShieldOfTheRighteous.java @@ -0,0 +1,80 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.abilities.common.BlocksAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; +import mage.abilities.effects.common.continious.BoostEquippedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public class ShieldOfTheRighteous extends CardImpl { + + public ShieldOfTheRighteous(UUID ownerId) { + super(ownerId, 11, "Shield of the Righteous", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{W}{U}"); + this.expansionSetCode = "ARB"; + this.subtype.add("Equipment"); + + this.color.setBlue(true); + this.color.setWhite(true); + + // Equipped creature gets +0/+2 and has vigilance. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(0, 2))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT))); + + // Whenever equipped creature blocks a creature, that creature doesn't untap during its controller's next untap step. + this.addAbility(new BlocksAttachedTriggeredAbility(new SkipNextUntapTargetEffect("that creature"), "equipped", false, false, true)); + + // Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2), new TargetControlledCreaturePermanent())); + } + + public ShieldOfTheRighteous(final ShieldOfTheRighteous card) { + super(card); + } + + @Override + public ShieldOfTheRighteous copy() { + return new ShieldOfTheRighteous(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/ThoughtHemorrhage.java b/Mage.Sets/src/mage/sets/alarareborn/ThoughtHemorrhage.java new file mode 100644 index 00000000000..827e158f24f --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/ThoughtHemorrhage.java @@ -0,0 +1,133 @@ +/* + * 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.alarareborn; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.repository.CardRepository; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author jeffwadsworth + */ +public class ThoughtHemorrhage extends CardImpl { + + public ThoughtHemorrhage(UUID ownerId) { + super(ownerId, 47, "Thought Hemorrhage", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{B}{R}"); + this.expansionSetCode = "ARB"; + + this.color.setRed(true); + this.color.setBlack(true); + + // Name a nonland card. Target player reveals his or her hand. Thought Hemorrhage deals 3 damage to that player for each card with that name revealed this way. Search that player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library. + this.getSpellAbility().addTarget(new TargetPlayer()); + this.getSpellAbility().addEffect(new ThoughtHemorrhageEffect()); + } + + public ThoughtHemorrhage(final ThoughtHemorrhage card) { + super(card); + } + + @Override + public ThoughtHemorrhage copy() { + return new ThoughtHemorrhage(this); + } +} + +class ThoughtHemorrhageEffect extends OneShotEffect { + + String cardName; + final String rule = "Name a nonland card. Target player reveals his or her hand. Thought Hemorrhage deals 3 damage to that player for each card with that name revealed this way. Search that player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library"; + + public ThoughtHemorrhageEffect() { + super(Outcome.Detriment); + staticText = rule; + } + + public ThoughtHemorrhageEffect(final ThoughtHemorrhageEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player you = game.getPlayer(source.getControllerId()); + if (you != null) { + Choice cardChoice = new ChoiceImpl(); + cardChoice.setChoices(CardRepository.instance.getNonLandNames()); + cardChoice.clearChoice(); + while (!you.choose(Outcome.Detriment, cardChoice, game)) { + game.debugMessage("player canceled choosing name. retrying."); + } + cardName = cardChoice.getChoice(); + game.informPlayers("Thought Hemorrhage, named card: [" + cardName + "]"); + } + Player targetPlayer = game.getPlayer(source.getFirstTarget()); + if (targetPlayer != null) { + targetPlayer.revealCards("hand of target player", targetPlayer.getHand(), game); + for (Card card : targetPlayer.getHand().getCards(game)) { + if (card.getName().equals(cardName)) { + targetPlayer.damage(3, source.getId(), game, false, true); + } + } + for (Card card : targetPlayer.getGraveyard().getCards(game)) { + if (card.getName().equals(cardName)) { + card.moveToExile(null, "", source.getId(), game); + } + } + for (Card card : targetPlayer.getHand().getCards(game)) { + if (card.getName().equals(cardName)) { + card.moveToExile(null, "", source.getId(), game); + } + } + for (Card card : targetPlayer.getLibrary().getCards(game)) { + if (card.getName().equals(cardName)) { + card.moveToExile(null, "", source.getId(), game); + } + } + targetPlayer.shuffleLibrary(game); + return true; + } + return false; + } + + @Override + public ThoughtHemorrhageEffect copy() { + return new ThoughtHemorrhageEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/UnscytheKillerOfKings.java b/Mage.Sets/src/mage/sets/alarareborn/UnscytheKillerOfKings.java new file mode 100644 index 00000000000..b9e4fdc70bb --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/UnscytheKillerOfKings.java @@ -0,0 +1,207 @@ +/* + * 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.alarareborn; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continious.BoostEquippedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.ZombieToken; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.targetpointer.FixedTarget; +import mage.watchers.WatcherImpl; + +/** + * + * @author jeffwadsworth + */ +public class UnscytheKillerOfKings extends CardImpl { + + public UnscytheKillerOfKings(UUID ownerId) { + super(ownerId, 114, "Unscythe, Killer of Kings", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{R}"); + this.expansionSetCode = "ARB"; + this.supertype.add("Legendary"); + this.subtype.add("Equipment"); + + this.color.setRed(true); + this.color.setBlue(true); + this.color.setBlack(true); + + // Equipped creature gets +3/+3 and has first strike. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(3, 3))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT))); + + // Whenever a creature dealt damage by equipped creature this turn dies, you may exile that card. If you do, put a 2/2 black Zombie creature token onto the battlefield. + this.addAbility(new UnscytheKillerOfKingsTriggeredAbility(new UnscytheEffect())); + this.addWatcher(new EquippedDidDamageWatcher()); + + // Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2), new TargetControlledCreaturePermanent())); + } + + public UnscytheKillerOfKings(final UnscytheKillerOfKings card) { + super(card); + } + + @Override + public UnscytheKillerOfKings copy() { + return new UnscytheKillerOfKings(this); + } +} + +class UnscytheKillerOfKingsTriggeredAbility extends TriggeredAbilityImpl { + + public UnscytheKillerOfKingsTriggeredAbility(Effect effect) { + this(effect, true); + } + + public UnscytheKillerOfKingsTriggeredAbility(Effect effect, boolean optional) { + super(Zone.ALL, effect, optional); + } + + public UnscytheKillerOfKingsTriggeredAbility(final UnscytheKillerOfKingsTriggeredAbility ability) { + super(ability); + } + + @Override + public UnscytheKillerOfKingsTriggeredAbility copy() { + return new UnscytheKillerOfKingsTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) { + Card card = game.getCard(event.getTargetId()); + if (card != null) { + EquippedDidDamageWatcher watcher = (EquippedDidDamageWatcher) game.getState().getWatchers().get("equippedDamagedTargets", this.getSourceId()); + if (watcher != null + && watcher.equippedDamagedTargets.contains(event.getTargetId())) { + Effect effect = this.getEffects().get(0); + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + return true; + } + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a creature dealt damage by {this} this turn dies, " + super.getRule(); + } +} + +class UnscytheEffect extends OneShotEffect { + + public UnscytheEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "put a 2/2 black Zombie creature token onto the battlefield"; + } + + public UnscytheEffect(final UnscytheEffect effect) { + super(effect); + } + + @Override + public UnscytheEffect copy() { + return new UnscytheEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(targetPointer.getFirst(game, source)); + if (card != null) { + if (card.moveToExile(null, "Unscythe Exile", source.getId(), game)) { + ZombieToken zombie = new ZombieToken(); + return zombie.putOntoBattlefield(1, game, source.getId(), source.getControllerId()); + } + } + return false; + } +} + +class EquippedDidDamageWatcher extends WatcherImpl { + + public List equippedDamagedTargets = new ArrayList(); + + public EquippedDidDamageWatcher() { + super("equippedDamagedTargets", WatcherScope.CARD); + } + + public EquippedDidDamageWatcher(final EquippedDidDamageWatcher watcher) { + super(watcher); + this.equippedDamagedTargets.addAll(watcher.equippedDamagedTargets); + } + + @Override + public EquippedDidDamageWatcher copy() { + return new EquippedDidDamageWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == EventType.DAMAGED_CREATURE) { + Permanent permanent = game.getPermanent(event.getSourceId()); + if (permanent != null) { + if (permanent.getAttachments().contains(this.getSourceId())) { + if (!equippedDamagedTargets.contains(event.getTargetId())) { + equippedDamagedTargets.add(event.getTargetId()); + } + } + } + } + } + + @Override + public void reset() { + super.reset(); + equippedDamagedTargets.clear(); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/alarareborn/VectisDominator.java b/Mage.Sets/src/mage/sets/alarareborn/VectisDominator.java new file mode 100644 index 00000000000..e76cd593fe5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/alarareborn/VectisDominator.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.sets.alarareborn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public class VectisDominator extends CardImpl { + + public VectisDominator(UUID ownerId) { + super(ownerId, 84, "Vectis Dominator", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W}{B}"); + this.expansionSetCode = "ARB"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + + this.color.setBlack(true); + this.color.setWhite(true); + this.power = new MageInt(0); + this.toughness = new MageInt(2); + + // {tap}: Tap target creature unless its controller pays 2 life. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new VectisDominatorEffect(new PayLifeCost(2)), new ManaCostsImpl("{1}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public VectisDominator(final VectisDominator card) { + super(card); + } + + @Override + public VectisDominator copy() { + return new VectisDominator(this); + } +} + +class VectisDominatorEffect extends OneShotEffect { + + protected Cost cost; + + public VectisDominatorEffect(Cost cost) { + super(Outcome.Detriment); + this.staticText = "Tap target creature unless its controller pays 2 life"; + this.cost = cost; + } + + public VectisDominatorEffect(final VectisDominatorEffect effect) { + super(effect); + this.cost = effect.cost.copy(); + } + + @Override + public VectisDominatorEffect copy() { + return new VectisDominatorEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetCreature = game.getPermanent(source.getFirstTarget()); + if (targetCreature != null) { + Player player = game.getPlayer(targetCreature.getControllerId()); + if (player != null) { + cost.clearPaid(); + final StringBuilder sb = new StringBuilder("Pay 2 life otherwise ").append(targetCreature.getName()).append(" will be tapped)"); + if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true); + } + if (!cost.isPaid()) { + return targetCreature.tap(game); + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/HorobisWhisper.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/HorobisWhisper.java new file mode 100644 index 00000000000..32fe18a1506 --- /dev/null +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/HorobisWhisper.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.betrayersofkamigawa; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.condition.common.ControlsPermanentCondition; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class HorobisWhisper extends CardImpl { + + private static final FilterCreaturePermanent filterTarget = new FilterCreaturePermanent("nonblack creature"); + private static final FilterLandPermanent filterCondition = new FilterLandPermanent("Swamp"); + + static { + filterTarget.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + filterCondition.add(new SubtypePredicate("Swamp")); + } + + public HorobisWhisper(UUID ownerId) { + super(ownerId, 70, "Horobi's Whisper", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{B}{B}"); + this.expansionSetCode = "BOK"; + this.subtype.add("Arcane"); + + this.color.setBlack(true); + + + // If you control a Swamp, destroy target nonblack creature. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DestroyTargetEffect(), + new ControlsPermanentCondition(filterCondition),"If you control a Swamp, destroy target nonblack creature")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filterTarget) ); + + // Splice onto Arcane-Exile four cards from your graveyard. + this.addAbility(new SpliceOntoArcaneAbility(new ExileFromGraveCost(new TargetCardInYourGraveyard(4,4, new FilterCard("cards"))))); + + + } + + public HorobisWhisper(final HorobisWhisper card) { + super(card); + } + + @Override + public HorobisWhisper copy() { + return new HorobisWhisper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/TorrentOfStone.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/TorrentOfStone.java new file mode 100644 index 00000000000..8c77e1470a5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/TorrentOfStone.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.betrayersofkamigawa; + +import java.util.UUID; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class TorrentOfStone extends CardImpl { + private static final FilterLandPermanent filterSacrifice = new FilterLandPermanent("two Mountains"); + + static { + filterSacrifice.add(new SubtypePredicate("Mountain")); + } + + public TorrentOfStone(UUID ownerId) { + super(ownerId, 119, "Torrent of Stone", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{R}"); + this.expansionSetCode = "BOK"; + this.subtype.add("Arcane"); + + this.color.setRed(true); + + // Torrent of Stone deals 4 damage to target creature. + this.getSpellAbility().addEffect(new DamageTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + // Splice onto Arcane-Sacrifice two Mountains. + this.addAbility(new SpliceOntoArcaneAbility(new SacrificeTargetCost(new TargetControlledPermanent(2,2, filterSacrifice, false)))); + } + + public TorrentOfStone(final TorrentOfStone card) { + super(card); + } + + @Override + public TorrentOfStone copy() { + return new TorrentOfStone(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/DampenThought.java b/Mage.Sets/src/mage/sets/championsofkamigawa/DampenThought.java new file mode 100644 index 00000000000..d055d3a1754 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/DampenThought.java @@ -0,0 +1,54 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class DampenThought extends mage.sets.modernmasters.DampenThought { + + public DampenThought(UUID ownerId) { + super(ownerId); + this.cardNumber = 57; + this.expansionSetCode = "CHK"; + this.rarity = Rarity.UNCOMMON; + } + + public DampenThought(final DampenThought card) { + super(card); + } + + @Override + public DampenThought copy() { + return new DampenThought(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/DesperateRitual.java b/Mage.Sets/src/mage/sets/championsofkamigawa/DesperateRitual.java new file mode 100644 index 00000000000..f77e08f550d --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/DesperateRitual.java @@ -0,0 +1,54 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class DesperateRitual extends mage.sets.modernmasters.DesperateRitual { + + public DesperateRitual(UUID ownerId) { + super(ownerId); + this.cardNumber = 163; + this.expansionSetCode = "CHK"; + this.rarity = Rarity.COMMON; + } + + public DesperateRitual(final DesperateRitual card) { + super(card); + } + + @Override + public DesperateRitual copy() { + return new DesperateRitual(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/GlacialRay.java b/Mage.Sets/src/mage/sets/championsofkamigawa/GlacialRay.java new file mode 100644 index 00000000000..4fcec2c79cb --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/GlacialRay.java @@ -0,0 +1,52 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class GlacialRay extends mage.sets.modernmasters.GlacialRay { + + public GlacialRay(UUID ownerId) { + super(ownerId); + this.cardNumber = 168; + this.expansionSetCode = "CHK"; + } + + public GlacialRay(final GlacialRay card) { + super(card); + } + + @Override + public GlacialRay copy() { + return new GlacialRay(this); + } +} diff --git a/Mage.Sets/src/mage/sets/conflux/EtherswornAdjudicator.java b/Mage.Sets/src/mage/sets/conflux/EtherswornAdjudicator.java index e858987dfbd..4451bc8fc3b 100644 --- a/Mage.Sets/src/mage/sets/conflux/EtherswornAdjudicator.java +++ b/Mage.Sets/src/mage/sets/conflux/EtherswornAdjudicator.java @@ -63,7 +63,7 @@ public class EtherswornAdjudicator extends CardImpl { public EtherswornAdjudicator(UUID ownerId) { super(ownerId, 26, "Ethersworn Adjudicator", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{U}"); this.expansionSetCode = "CON"; - this.supertype.add("Legendary"); + this.subtype.add("Vedalken"); this.subtype.add("Knight"); this.color.setBlue(true); diff --git a/Mage.Sets/src/mage/sets/eighthedition/FertileGround.java b/Mage.Sets/src/mage/sets/eighthedition/FertileGround.java new file mode 100644 index 00000000000..578e3953e2e --- /dev/null +++ b/Mage.Sets/src/mage/sets/eighthedition/FertileGround.java @@ -0,0 +1,52 @@ +/* + * 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.eighthedition; + +import java.util.UUID; + +/** + * + * @author Plopman + */ +public class FertileGround extends mage.sets.urzassaga.FertileGround { + + public FertileGround(UUID ownerId) { + super(ownerId); + this.cardNumber = 248; + this.expansionSetCode = "8ED"; + } + + public FertileGround(final FertileGround card) { + super(card); + } + + @Override + public FertileGround copy() { + return new FertileGround(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eventide/BelligerentHatchling.java b/Mage.Sets/src/mage/sets/eventide/BelligerentHatchling.java index a9d574a10e4..81236cbdf16 100644 --- a/Mage.Sets/src/mage/sets/eventide/BelligerentHatchling.java +++ b/Mage.Sets/src/mage/sets/eventide/BelligerentHatchling.java @@ -28,16 +28,16 @@ package mage.sets.eventide; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SpellCastTriggeredAbility; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -63,9 +63,14 @@ public class BelligerentHatchling extends CardImpl { this.color.setWhite(true); this.power = new MageInt(6); this.toughness = new MageInt(6); + + // First strike this.addAbility(FirstStrikeAbility.getInstance()); - this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)))); + // Belligerent Hatchling enters the battlefield with four -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)))); + // Whenever you cast a red spell, remove a -1/-1 counter from Belligerent Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance(1)), filterRedSpell, false)); + // Whenever you cast a white spell, remove a -1/-1 counter from Belligerent Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance(1)), filterWhiteSpell, false)); } diff --git a/Mage.Sets/src/mage/sets/eventide/CloutOfTheDominus.java b/Mage.Sets/src/mage/sets/eventide/CloutOfTheDominus.java new file mode 100644 index 00000000000..00e75989b87 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eventide/CloutOfTheDominus.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.eventide; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class CloutOfTheDominus extends CardImpl { + + public CloutOfTheDominus(UUID ownerId) { + super(ownerId, 99, "Clout of the Dominus", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{U/R}"); + this.expansionSetCode = "EVE"; + this.subtype.add("Aura"); + + this.color.setRed(true); + this.color.setBlue(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is blue, it gets +1/+1 and has shroud. + SimpleStaticAbility blueAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "As long as enchanted creature is black, it gets +1/+1")); + blueAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "and has deathtouch")); + this.addAbility(blueAbility); + // As long as enchanted creature is red, it gets +1/+1 and has haste. + SimpleStaticAbility redAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.RED), "As long as enchanted creature is red, it gets +1/+1")); + redAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.RED), "and has haste")); + this.addAbility(redAbility); + } + + public CloutOfTheDominus(final CloutOfTheDominus card) { + super(card); + } + + @Override + public CloutOfTheDominus copy() { + return new CloutOfTheDominus(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eventide/EdgeOfTheDivinity.java b/Mage.Sets/src/mage/sets/eventide/EdgeOfTheDivinity.java new file mode 100644 index 00000000000..29b3e28d798 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eventide/EdgeOfTheDivinity.java @@ -0,0 +1,86 @@ +/* + * 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.eventide; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.EnchantAbility; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class EdgeOfTheDivinity extends CardImpl { + + public EdgeOfTheDivinity(UUID ownerId) { + super(ownerId, 87, "Edge of the Divinity", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{W/B}"); + this.expansionSetCode = "EVE"; + this.subtype.add("Aura"); + + this.color.setBlack(true); + this.color.setWhite(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is white, it gets +1/+2. + SimpleStaticAbility whiteAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 2), new EnchantedCreatureColorCondition(ObjectColor.WHITE), "As long as enchanted creature is white, it gets +1/+2")); + this.addAbility(whiteAbility); + // As long as enchanted creature is black, it gets +2/+1. + SimpleStaticAbility blackAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(2, 1), new EnchantedCreatureColorCondition(ObjectColor.BLACK), "As long as enchanted creature is black, it gets +2/+1")); + this.addAbility(blackAbility); + } + + public EdgeOfTheDivinity(final EdgeOfTheDivinity card) { + super(card); + } + + @Override + public EdgeOfTheDivinity copy() { + return new EdgeOfTheDivinity(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eventide/FavorOfTheOverbeing.java b/Mage.Sets/src/mage/sets/eventide/FavorOfTheOverbeing.java new file mode 100644 index 00000000000..fb9bc329c90 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eventide/FavorOfTheOverbeing.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.eventide; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class FavorOfTheOverbeing extends CardImpl { + + public FavorOfTheOverbeing(UUID ownerId) { + super(ownerId, 151, "Favor of the Overbeing", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{G/U}"); + this.expansionSetCode = "EVE"; + this.subtype.add("Aura"); + + this.color.setBlue(true); + this.color.setGreen(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is green, it gets +1/+1 and has vigilance. + SimpleStaticAbility greenAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "As long as enchanted creature is green, it gets +1/+1")); + greenAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "and has vigilance")); + this.addAbility(greenAbility); + // As long as enchanted creature is blue, it gets +1/+1 and has flying. + SimpleStaticAbility blueAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "As long as enchanted creature is blue, it gets +1/+1")); + blueAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "and has flying")); + this.addAbility(blueAbility); + } + + public FavorOfTheOverbeing(final FavorOfTheOverbeing card) { + super(card); + } + + @Override + public FavorOfTheOverbeing copy() { + return new FavorOfTheOverbeing(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eventide/GiftOfTheDeity.java b/Mage.Sets/src/mage/sets/eventide/GiftOfTheDeity.java new file mode 100644 index 00000000000..5d83ce804e5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eventide/GiftOfTheDeity.java @@ -0,0 +1,89 @@ +/* + * 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.eventide; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.MustBlockAttachedEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class GiftOfTheDeity extends CardImpl { + + public GiftOfTheDeity(UUID ownerId) { + super(ownerId, 122, "Gift of the Deity", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{4}{B/G}"); + this.expansionSetCode = "EVE"; + this.subtype.add("Aura"); + + this.color.setGreen(true); + this.color.setBlack(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is black, it gets +1/+1 and has deathtouch. + SimpleStaticAbility blackAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.BLACK), "As long as enchanted creature is black, it gets +1/+1")); + blackAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(DeathtouchAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.BLACK), "and has deathtouch")); + this.addAbility(blackAbility); + // As long as enchanted creature is green, it gets +1/+1 and all creatures able to block it do so. + SimpleStaticAbility greenAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "As long as enchanted creature is green, it gets +1/+1")); + greenAbility.addEffect(new ConditionalContinousEffect(new MustBlockAttachedEffect(AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "and all creatures able to block it do so")); + this.addAbility(greenAbility); + } + + public GiftOfTheDeity(final GiftOfTheDeity card) { + super(card); + } + + @Override + public GiftOfTheDeity copy() { + return new GiftOfTheDeity(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eventide/NoxiousHatchling.java b/Mage.Sets/src/mage/sets/eventide/NoxiousHatchling.java index 5870e58d1c2..687dc3608f4 100644 --- a/Mage.Sets/src/mage/sets/eventide/NoxiousHatchling.java +++ b/Mage.Sets/src/mage/sets/eventide/NoxiousHatchling.java @@ -28,16 +28,16 @@ package mage.sets.eventide; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SpellCastTriggeredAbility; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.WitherAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -64,9 +64,14 @@ public class NoxiousHatchling extends CardImpl { this.color.setBlack(true); this.power = new MageInt(6); this.toughness = new MageInt(6); - this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)), false)); + + // Noxious Hatchling enters the battlefield with four -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)), true)); + // Wither (This deals damage to creatures in the form of -1/-1 counters.) this.addAbility(WitherAbility.getInstance()); + // Whenever you cast a black spell, remove a -1/-1 counter from Noxious Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance()), filterBlackSpell, false)); + // Whenever you cast a green spell, remove a -1/-1 counter from Noxious Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance()), filterGreenSpell, false)); } diff --git a/Mage.Sets/src/mage/sets/eventide/ScourgeOfTheNobilis.java b/Mage.Sets/src/mage/sets/eventide/ScourgeOfTheNobilis.java new file mode 100644 index 00000000000..ddd524ca43e --- /dev/null +++ b/Mage.Sets/src/mage/sets/eventide/ScourgeOfTheNobilis.java @@ -0,0 +1,92 @@ +/* + * 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.eventide; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.BoostSourceEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class ScourgeOfTheNobilis extends CardImpl { + + public ScourgeOfTheNobilis(UUID ownerId) { + super(ownerId, 146, "Scourge of the Nobilis", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{R/W}"); + this.expansionSetCode = "EVE"; + this.subtype.add("Aura"); + + this.color.setRed(true); + this.color.setWhite(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is red, it gets +1/+1 and has "{RW}: This creature gets +1/+0 until end of turn." + SimpleStaticAbility redAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.RED), "As long as enchanted creature is red, it gets +1/+1")); + redAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R/W}")), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.RED), "and has \"{R/W}: This creature gets +1/+0 until end of turn.\"")); + this.addAbility(redAbility); + // As long as enchanted creature is white, it gets +1/+1 and has lifelink. + SimpleStaticAbility whiteAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.WHITE), "As long as enchanted creature is white, it gets +1/+1")); + whiteAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.WHITE), "and has lifelink")); + this.addAbility(whiteAbility); + } + + public ScourgeOfTheNobilis(final ScourgeOfTheNobilis card) { + super(card); + } + + @Override + public ScourgeOfTheNobilis copy() { + return new ScourgeOfTheNobilis(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eventide/SturdyHatchling.java b/Mage.Sets/src/mage/sets/eventide/SturdyHatchling.java index 57f5a515d29..6041e058c7e 100644 --- a/Mage.Sets/src/mage/sets/eventide/SturdyHatchling.java +++ b/Mage.Sets/src/mage/sets/eventide/SturdyHatchling.java @@ -28,12 +28,9 @@ package mage.sets.eventide; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SpellCastTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -42,7 +39,9 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.ShroudAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterSpell; @@ -69,9 +68,14 @@ public class SturdyHatchling extends CardImpl { this.color.setGreen(true); this.power = new MageInt(6); this.toughness = new MageInt(6); - this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)), false)); + + // Sturdy Hatchling enters the battlefield with four -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)))); + // {G/U}: Sturdy Hatchling gains shroud until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(ShroudAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{G/U}"))); + // Whenever you cast a green spell, remove a -1/-1 counter from Sturdy Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance(1)), filterGreenSpell, false)); + // Whenever you cast a blue spell, remove a -1/-1 counter from Sturdy Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance(1)), filterBlueSpell, false)); } diff --git a/Mage.Sets/src/mage/sets/eventide/VoraciousHatchling.java b/Mage.Sets/src/mage/sets/eventide/VoraciousHatchling.java index f5147b5bd61..b31f7d971ea 100644 --- a/Mage.Sets/src/mage/sets/eventide/VoraciousHatchling.java +++ b/Mage.Sets/src/mage/sets/eventide/VoraciousHatchling.java @@ -28,16 +28,16 @@ package mage.sets.eventide; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SpellCastTriggeredAbility; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -63,9 +63,14 @@ public class VoraciousHatchling extends CardImpl { this.color.setWhite(true); this.power = new MageInt(6); this.toughness = new MageInt(6); + + // Lifelink this.addAbility(LifelinkAbility.getInstance()); - this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)))); + // Voracious Hatchling enters the battlefield with four -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)))); + // Whenever you cast a white spell, remove a -1/-1 counter from Voracious Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance(1)), filterWhiteSpell, false)); + // Whenever you cast a black spell, remove a -1/-1 counter from Voracious Hatchling. this.addAbility(new SpellCastTriggeredAbility(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance(1)), filterBlackSpell, false)); } diff --git a/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java b/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java index 145f12b3641..92fae347c3a 100644 --- a/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java +++ b/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java @@ -100,7 +100,11 @@ class ErraticPortalEffect extends OneShotEffect { Player player = game.getPlayer(targetCreature.getControllerId()); if (player != null) { cost.clearPaid(); - if (!cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), false)) { + final StringBuilder sb = new StringBuilder("Pay {1} otherwise ").append(targetCreature.getName()).append(" will be returned to its owner's hand)"); + if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true); + } + if (!cost.isPaid()) { return targetCreature.moveToZone(Zone.HAND, source.getSourceId(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/futuresight/JhoiraOfTheGhitu.java b/Mage.Sets/src/mage/sets/futuresight/JhoiraOfTheGhitu.java new file mode 100644 index 00000000000..33438ee7e40 --- /dev/null +++ b/Mage.Sets/src/mage/sets/futuresight/JhoiraOfTheGhitu.java @@ -0,0 +1,52 @@ +/* + * 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.futuresight; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class JhoiraOfTheGhitu extends mage.sets.modernmasters.JhoiraOfTheGhitu { + + public JhoiraOfTheGhitu(UUID ownerId) { + super(ownerId); + this.cardNumber = 157; + this.expansionSetCode = "FUT"; + } + + public JhoiraOfTheGhitu(final JhoiraOfTheGhitu card) { + super(card); + } + + @Override + public JhoiraOfTheGhitu copy() { + return new JhoiraOfTheGhitu(this); + } +} diff --git a/Mage.Sets/src/mage/sets/gatecrash/TruefirePaladin.java b/Mage.Sets/src/mage/sets/gatecrash/TruefirePaladin.java index 2d320a9ea64..ade6131e720 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/TruefirePaladin.java +++ b/Mage.Sets/src/mage/sets/gatecrash/TruefirePaladin.java @@ -68,7 +68,7 @@ public class TruefirePaladin extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2,0, Duration.EndOfTurn), new ManaCostsImpl("{R}{W}"))); // {R}{W}: Truefire Paladin gets first strike until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FirstStrikeAbility.getInstance()), new ManaCostsImpl("{R}{W}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{R}{W}"))); } diff --git a/Mage.Sets/src/mage/sets/iceage/Swamp1.java b/Mage.Sets/src/mage/sets/iceage/Swamp1.java index 0e127133355..4a7bca78159 100644 --- a/Mage.Sets/src/mage/sets/iceage/Swamp1.java +++ b/Mage.Sets/src/mage/sets/iceage/Swamp1.java @@ -36,7 +36,7 @@ import java.util.UUID; public class Swamp1 extends mage.cards.basiclands.Swamp { public Swamp1(UUID ownerId) { - super(ownerId, 351); + super(ownerId, 353); this.expansionSetCode = "ICE"; } diff --git a/Mage.Sets/src/mage/sets/iceage/Swamp2.java b/Mage.Sets/src/mage/sets/iceage/Swamp2.java index 6158384913f..9a0c2663498 100644 --- a/Mage.Sets/src/mage/sets/iceage/Swamp2.java +++ b/Mage.Sets/src/mage/sets/iceage/Swamp2.java @@ -36,7 +36,7 @@ import java.util.UUID; public class Swamp2 extends mage.cards.basiclands.Swamp { public Swamp2(UUID ownerId) { - super(ownerId, 352); + super(ownerId, 354); this.expansionSetCode = "ICE"; } diff --git a/Mage.Sets/src/mage/sets/iceage/Swamp3.java b/Mage.Sets/src/mage/sets/iceage/Swamp3.java index c515e8d56dd..0714bbe7893 100644 --- a/Mage.Sets/src/mage/sets/iceage/Swamp3.java +++ b/Mage.Sets/src/mage/sets/iceage/Swamp3.java @@ -36,7 +36,7 @@ import java.util.UUID; public class Swamp3 extends mage.cards.basiclands.Swamp { public Swamp3(UUID ownerId) { - super(ownerId, 353); + super(ownerId, 355); this.expansionSetCode = "ICE"; } diff --git a/Mage.Sets/src/mage/sets/invasion/FertileGround.java b/Mage.Sets/src/mage/sets/invasion/FertileGround.java new file mode 100644 index 00000000000..a92ac371a27 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/FertileGround.java @@ -0,0 +1,52 @@ +/* + * 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.invasion; + +import java.util.UUID; + +/** + * + * @author Plopman + */ +public class FertileGround extends mage.sets.urzassaga.FertileGround { + + public FertileGround(UUID ownerId) { + super(ownerId); + this.cardNumber = 188; + this.expansionSetCode = "INV"; + } + + public FertileGround(final FertileGround card) { + super(card); + } + + @Override + public FertileGround copy() { + return new FertileGround(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/VerdelothTheAncient.java b/Mage.Sets/src/mage/sets/invasion/VerdelothTheAncient.java new file mode 100644 index 00000000000..097592c3486 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/VerdelothTheAncient.java @@ -0,0 +1,128 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.MultikickerCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continious.BoostAllEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.game.Game; +import mage.game.permanent.token.SaprolingToken; + +/** + * + * @author LevelX2 + */ +public class VerdelothTheAncient extends CardImpl { + + public VerdelothTheAncient(UUID ownerId) { + super(ownerId, 220, "Verdeloth the Ancient", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + this.expansionSetCode = "INV"; + this.supertype.add("Legendary"); + this.subtype.add("Treefolk"); + + this.color.setGreen(true); + this.power = new MageInt(4); + this.toughness = new MageInt(7); + + // Kicker {X} + this.addAbility(new KickerAbility("{X}")); + // Saproling creatures and other Treefolk creatures get +1/+1. + FilterCreaturePermanent filter = new FilterCreaturePermanent("Saproling creatures and other Treefolk creatures"); + filter.add(Predicates.or( + Predicates.and(new SubtypePredicate("Treefolk"), Predicates.not(new PermanentIdPredicate(this.getId())), + new SubtypePredicate("Saproling")))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1, Duration.WhileOnBattlefield, filter, false))); + // When Verdeloth the Ancient enters the battlefield, if it was kicked, put X 1/1 green Saproling creature tokens onto the battlefield. + EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SaprolingToken(), new GetKickerXValue()), false); + this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.getInstance(), + "When {this} enters the battlefield, if it was kicked, put X 1/1 green Saproling creature tokens onto the battlefield.")); + } + + public VerdelothTheAncient(final VerdelothTheAncient card) { + super(card); + } + + @Override + public VerdelothTheAncient copy() { + return new VerdelothTheAncient(this); + } +} + +class GetKickerXValue implements DynamicValue { + + public GetKickerXValue() { + } + + @Override + public int calculate(Game game, Ability source) { + int count = 0; + Card card = game.getCard(source.getSourceId()); + if (card != null) { + for (Ability ability: card.getAbilities()) { + if (ability instanceof KickerAbility) { + count += ((KickerAbility) ability).getXManaValue(); + } + } + } + return count; + } + + @Override + public GetKickerXValue copy() { + return new GetKickerXValue(); + } + + @Override + public String toString() { + return "X"; + }; + + @Override + public String getMessage() { + return "X"; + }; +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/lorwyn/FertileGround.java b/Mage.Sets/src/mage/sets/lorwyn/FertileGround.java new file mode 100644 index 00000000000..9702a94bae7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/FertileGround.java @@ -0,0 +1,52 @@ +/* + * 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.lorwyn; + +import java.util.UUID; + +/** + * + * @author Plopman + */ +public class FertileGround extends mage.sets.urzassaga.FertileGround { + + public FertileGround(UUID ownerId) { + super(ownerId); + this.cardNumber = 211; + this.expansionSetCode = "LRW"; + } + + public FertileGround(final FertileGround card) { + super(card); + } + + @Override + public FertileGround copy() { + return new FertileGround(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java b/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java new file mode 100644 index 00000000000..f5093f9ff3a --- /dev/null +++ b/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java @@ -0,0 +1,135 @@ +/* + * 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.magic2014; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.Token; +import mage.players.Player; + +/** + * + * @author Plopman + */ +public class AjanisChosen extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + static { + filter.add(new CardTypePredicate(CardType.ENCHANTMENT)); + } + + public AjanisChosen(UUID ownerId) { + super(ownerId, 2, "Ajani's Chosen", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + this.expansionSetCode = "M14"; + this.subtype.add("Cat"); + this.subtype.add("Soldier"); + + this.color.setWhite(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever an enchantment enters the battlefield under your control, put a 2/2 white Cat creature token onto the battlefield. If that enchantment is an Aura, you may attach it to the token. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new AjanisChosenEffect(), filter, false, true, "Whenever an enchantment enters the battlefield under your control, put a 2/2 white Cat creature token onto the battlefield. If that enchantment is an Aura, you may attach it to the token")); + } + + public AjanisChosen(final AjanisChosen card) { + super(card); + } + + @Override + public AjanisChosen copy() { + return new AjanisChosen(this); + } +} + +class AjanisChosenEffect extends OneShotEffect { + + + public AjanisChosenEffect() { + super(Outcome.PutCreatureInPlay); + staticText = "put a 2/2 white Cat creature token onto the battlefield. If that enchantment is an Aura, you may attach it to the token"; + } + + public AjanisChosenEffect(final AjanisChosenEffect effect) { + super(effect); + } + + @Override + public AjanisChosenEffect copy() { + return new AjanisChosenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Token token = new CatToken(); + if(token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId())){ + Player player = game.getPlayer(source.getControllerId()); + Permanent enchantement = game.getPermanent(this.getTargetPointer().getFirst(game, source)); + Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken()); + if(player != null && enchantement != null && tokenPermanent != null && enchantement.getSubtype().contains("Aura")) + { + Permanent oldCreature = game.getPermanent(enchantement.getAttachedTo()); + + if(oldCreature != null && enchantement.getSpellAbility().getTargets().get(0).canTarget(tokenPermanent.getId(), game) && player.chooseUse(Outcome.Neutral, "Attach " + enchantement.getName() + " to the token ?", game)) + { + if(oldCreature.removeAttachment(enchantement.getId(), game)){ + tokenPermanent.addAttachment(enchantement.getId(), game); + } + } + } + return true; + } + return false; + } + +} + + +class CatToken extends Token { + public CatToken() { + super("Cat", "2/2 white Cat creature token"); + cardType.add(CardType.CREATURE); + color = ObjectColor.WHITE; + subtype.add("Cat"); + power = new MageInt(2); + toughness = new MageInt(2); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/magic2014/ArchangelOfThune.java b/Mage.Sets/src/mage/sets/magic2014/ArchangelOfThune.java new file mode 100644 index 00000000000..09ccc8cd1b2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magic2014/ArchangelOfThune.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magic2014; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author Plopman + */ +public class ArchangelOfThune extends CardImpl { + + public ArchangelOfThune(UUID ownerId) { + super(ownerId, 5, "Archangel of Thune", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); + this.expansionSetCode = "M14"; + this.subtype.add("Angel"); + + this.color.setWhite(true); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + // Whenever you gain life, put a +1/+1 counter on each creature you control. + this.addAbility(new ArchangelOfThuneAbility()); + + } + + public ArchangelOfThune(final ArchangelOfThune card) { + super(card); + } + + @Override + public ArchangelOfThune copy() { + return new ArchangelOfThune(this); + } +} + +class ArchangelOfThuneAbility extends TriggeredAbilityImpl { + + public ArchangelOfThuneAbility() { + super(Zone.BATTLEFIELD, new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()), false); + } + + public ArchangelOfThuneAbility(final ArchangelOfThuneAbility ability) { + super(ability); + } + + @Override + public ArchangelOfThuneAbility copy() { + return new ArchangelOfThuneAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.GAINED_LIFE && event.getPlayerId().equals(controllerId)) { + return true; + } + return false; + } + + @Override + public String getRule() { + return " Whenever you gain life, put a +1/+1 counter on each creature you control."; + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/magic2014/SentinelSliver.java b/Mage.Sets/src/mage/sets/magic2014/SentinelSliver.java new file mode 100644 index 00000000000..1fb3292340a --- /dev/null +++ b/Mage.Sets/src/mage/sets/magic2014/SentinelSliver.java @@ -0,0 +1,69 @@ +/* + * 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.magic2014; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continious.GainAbilityControlledEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; + +/** + * + * @author Plopman + */ +public class SentinelSliver extends CardImpl { + + public SentinelSliver(UUID ownerId) { + super(ownerId, 30, "Sentinel Sliver", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "M14"; + this.subtype.add("Sliver"); + + this.color.setWhite(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Sliver creatures you control have vigilance. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, new FilterControlledCreaturePermanent("Sliver", "Sliver creatures you control ")))); + } + + public SentinelSliver(final SentinelSliver card) { + super(card); + } + + @Override + public SentinelSliver copy() { + return new SentinelSliver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magic2014/SeraphOfTheSword.java b/Mage.Sets/src/mage/sets/magic2014/SeraphOfTheSword.java new file mode 100644 index 00000000000..9aec676afbc --- /dev/null +++ b/Mage.Sets/src/mage/sets/magic2014/SeraphOfTheSword.java @@ -0,0 +1,71 @@ +/* + * 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.magic2014; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PreventAllDamageSourceEffect; +import mage.abilities.effects.common.PreventCombatDamageSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author Plopman + */ +public class SeraphOfTheSword extends CardImpl { + + public SeraphOfTheSword(UUID ownerId) { + super(ownerId, 31, "Seraph of the Sword", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}"); + this.expansionSetCode = "M14"; + this.subtype.add("Angel"); + + this.color.setWhite(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Prevent all combat damage that would be dealt to Seraph of the Sword. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventCombatDamageSourceEffect(Duration.WhileOnBattlefield))); + } + + public SeraphOfTheSword(final SeraphOfTheSword card) { + super(card); + } + + @Override + public SeraphOfTheSword copy() { + return new SeraphOfTheSword(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magic2014/SteelformSliver.java b/Mage.Sets/src/mage/sets/magic2014/SteelformSliver.java new file mode 100644 index 00000000000..36186afb6cb --- /dev/null +++ b/Mage.Sets/src/mage/sets/magic2014/SteelformSliver.java @@ -0,0 +1,69 @@ +/* + * 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.magic2014; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continious.BoostAllEffect; +import mage.abilities.effects.common.continious.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author Plopman + */ +public class SteelformSliver extends CardImpl { + + public SteelformSliver(UUID ownerId) { + super(ownerId, 38, "Steelform Sliver", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "M14"; + this.subtype.add("Sliver"); + + this.color.setWhite(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Sliver creatures you control get +0/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(0, 1, Duration.WhileOnBattlefield, new FilterCreaturePermanent("Sliver", "Sliver creatures you control"), false))); + } + + public SteelformSliver(final SteelformSliver card) { + super(card); + } + + @Override + public SteelformSliver copy() { + return new SteelformSliver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirage/EarlyHarvest.java b/Mage.Sets/src/mage/sets/mirage/EarlyHarvest.java new file mode 100644 index 00000000000..5192a939d0e --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/EarlyHarvest.java @@ -0,0 +1,52 @@ +/* + * 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.mirage; + +import java.util.UUID; + +/** + * + * @author Plopman + */ +public class EarlyHarvest extends mage.sets.ninthedition.EarlyHarvest { + + public EarlyHarvest(UUID ownerId) { + super(ownerId); + this.cardNumber = 111; + this.expansionSetCode = "MIR"; + } + + public EarlyHarvest(final EarlyHarvest card) { + super(card); + } + + @Override + public EarlyHarvest copy() { + return new EarlyHarvest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/AuntiesSnitch.java b/Mage.Sets/src/mage/sets/modernmasters/AuntiesSnitch.java new file mode 100644 index 00000000000..d4c31390768 --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/AuntiesSnitch.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.sets.modernmasters; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.keyword.ProwlAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class AuntiesSnitch extends CardImpl { + + public AuntiesSnitch(UUID ownerId) { + super(ownerId, 72, "Auntie's Snitch", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "MMA"; + this.subtype.add("Goblin"); + this.subtype.add("Rogue"); + + this.color.setBlack(true); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Auntie's Snitch can't block. + this.addAbility(new CantBlockAbility()); + // Prowl {1}{B} + this.addAbility(new ProwlAbility(this, "{1}{B}")); + // Whenever a Goblin or Rogue you control deals combat damage to a player, if Auntie's Snitch is in your graveyard, you may return Auntie's Snitch to your hand. + this.addAbility(new AuntiesSnitchTriggeredAbility()); + } + + public AuntiesSnitch(final AuntiesSnitch card) { + super(card); + } + + @Override + public AuntiesSnitch copy() { + return new AuntiesSnitch(this); + } +} + +class AuntiesSnitchTriggeredAbility extends TriggeredAbilityImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Goblin or Rogue you control"); + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(Predicates.or(new SubtypePredicate("Goblin"), new SubtypePredicate("Rogue"))); + } + + public AuntiesSnitchTriggeredAbility() { + super(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), true); + } + + public AuntiesSnitchTriggeredAbility(final AuntiesSnitchTriggeredAbility ability) { + super(ability); + } + + @Override + public AuntiesSnitchTriggeredAbility copy() { + return new AuntiesSnitchTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event instanceof DamagedPlayerEvent) { + DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; + Permanent p = game.getPermanent(event.getSourceId()); + if (damageEvent.isCombatDamage() && p != null && filter.match(p, getSourceId(), getControllerId(), game)) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a Goblin or Rogue you control deals combat damage to a player, if {this} is in your graveyard, you may return {this} to your hand."; + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/DampenThought.java b/Mage.Sets/src/mage/sets/modernmasters/DampenThought.java new file mode 100644 index 00000000000..1d2afa8062b --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/DampenThought.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.sets.modernmasters; + +import java.util.UUID; +import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; +import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.TargetPlayer; + +/** + * + * @author LevelX2 + */ +public class DampenThought extends CardImpl { + + public DampenThought(UUID ownerId) { + super(ownerId, 39, "Dampen Thought", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); + this.expansionSetCode = "MMA"; + this.subtype.add("Arcane"); + + this.color.setBlue(true); + + // Target player puts the top four cards of his or her library into his or her graveyard. + this.getSpellAbility().addEffect(new PutLibraryIntoGraveTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetPlayer(true)); + // Splice onto Arcane {1}{U} + this.addAbility(new SpliceOntoArcaneAbility("{1}{U}")); + } + + public DampenThought(final DampenThought card) { + super(card); + } + + @Override + public DampenThought copy() { + return new DampenThought(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/DesperateRitual.java b/Mage.Sets/src/mage/sets/modernmasters/DesperateRitual.java new file mode 100644 index 00000000000..aa8e6837082 --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/DesperateRitual.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.sets.modernmasters; + +import java.util.UUID; +import mage.Mana; +import mage.abilities.effects.common.BasicManaEffect; +import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class DesperateRitual extends CardImpl { + + public DesperateRitual(UUID ownerId) { + super(ownerId, 110, "Desperate Ritual", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{R}"); + this.expansionSetCode = "MMA"; + this.subtype.add("Arcane"); + + this.color.setRed(true); + + // Add {R}{R}{R} to your mana pool. + this.getSpellAbility().addEffect(new BasicManaEffect(new Mana(3, 0, 0, 0, 0, 0, 0))); + // Splice onto Arcane {1}{R} + this.addAbility(new SpliceOntoArcaneAbility("{1}{R}")); + } + + public DesperateRitual(final DesperateRitual card) { + super(card); + } + + @Override + public DesperateRitual copy() { + return new DesperateRitual(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/EarwigSquad.java b/Mage.Sets/src/mage/sets/modernmasters/EarwigSquad.java new file mode 100644 index 00000000000..837e9287c17 --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/EarwigSquad.java @@ -0,0 +1,128 @@ +/* + * 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.modernmasters; + +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.ProwlCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.keyword.ProwlAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class EarwigSquad extends CardImpl { + + public EarwigSquad(UUID ownerId) { + super(ownerId, 82, "Earwig Squad", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.expansionSetCode = "MMA"; + this.subtype.add("Goblin"); + this.subtype.add("Rogue"); + + this.color.setBlack(true); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // Prowl {2}{B} + this.addAbility(new ProwlAbility(this, "{2}{B}")); + // When Earwig Squad enters the battlefield, if its prowl cost was paid, search target opponent's library for three cards and exile them. Then that player shuffles his or her library. + EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new EarwigSquadEffect(), false); + ability.addTarget(new TargetOpponent(true)); + this.addAbility(new ConditionalTriggeredAbility(ability, ProwlCondition.getInstance(), + "When {this} enters the battlefield, if its prowl cost was paid, search target opponent's library for three cards and exile them. Then that player shuffles his or her library.")); + + } + + public EarwigSquad(final EarwigSquad card) { + super(card); + } + + @Override + public EarwigSquad copy() { + return new EarwigSquad(this); + } +} + +class EarwigSquadEffect extends OneShotEffect { + + public EarwigSquadEffect() { + super(Outcome.Benefit); + staticText = "search target opponent's library for three cards and exile them. Then that player shuffles his or her library"; + } + + public EarwigSquadEffect(final EarwigSquadEffect effect) { + super(effect); + } + + @Override + public EarwigSquadEffect copy() { + return new EarwigSquadEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player opponent = game.getPlayer(source.getFirstTarget()); + Player player = game.getPlayer(source.getControllerId()); + if (player != null && opponent != null) { + Cards opponentLibrary = new CardsImpl(); + opponentLibrary.addAll(opponent.getLibrary().getCardList()); + + TargetCardInLibrary target = new TargetCardInLibrary(0, 3, new FilterCard("cards from opponents library to exile")); + if (player.choose(Outcome.Benefit, opponentLibrary, target, game)) { + List targets = target.getTargets(); + for (UUID targetId : targets) { + Card card = opponent.getLibrary().remove(targetId, game); + if (card != null) { + card.moveToExile(null, null, source.getId(), game); + } + } + } + opponent.shuffleLibrary(game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/GlacialRay.java b/Mage.Sets/src/mage/sets/modernmasters/GlacialRay.java new file mode 100644 index 00000000000..73b0f4b3471 --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/GlacialRay.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.sets.modernmasters; + +import java.util.UUID; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LevelX2 + */ +public class GlacialRay extends CardImpl { + + public GlacialRay(UUID ownerId) { + super(ownerId, 115, "Glacial Ray", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{R}"); + this.expansionSetCode = "MMA"; + this.subtype.add("Arcane"); + + this.color.setRed(true); + + // Glacial Ray deals 2 damage to target creature or player. + this.getSpellAbility().addEffect(new DamageTargetEffect(2)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer(true)); + // Splice onto Arcane {1}{R} + this.addAbility(new SpliceOntoArcaneAbility("{1}{R}")); + } + + public GlacialRay(final GlacialRay card) { + super(card); + } + + @Override + public GlacialRay copy() { + return new GlacialRay(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/HorobisWhisper.java b/Mage.Sets/src/mage/sets/modernmasters/HorobisWhisper.java new file mode 100644 index 00000000000..a184763a994 --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/HorobisWhisper.java @@ -0,0 +1,54 @@ +/* + * 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.modernmasters; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class HorobisWhisper extends mage.sets.betrayersofkamigawa.HorobisWhisper { + + public HorobisWhisper(UUID ownerId) { + super(ownerId); + this.cardNumber = 88; + this.expansionSetCode = "MMA"; + this.rarity = Rarity.UNCOMMON; + } + + public HorobisWhisper(final HorobisWhisper card) { + super(card); + } + + @Override + public HorobisWhisper copy() { + return new HorobisWhisper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/JhoiraOfTheGhitu.java b/Mage.Sets/src/mage/sets/modernmasters/JhoiraOfTheGhitu.java new file mode 100644 index 00000000000..01302ad44dd --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/JhoiraOfTheGhitu.java @@ -0,0 +1,156 @@ +/* + * 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.modernmasters; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Abilities; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileFromHandCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SuspendAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterNonlandCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +/** + * + * @author LevelX2 + */ +public class JhoiraOfTheGhitu extends CardImpl { + + public JhoiraOfTheGhitu(UUID ownerId) { + super(ownerId, 177, "Jhoira of the Ghitu", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}{R}"); + this.expansionSetCode = "MMA"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Wizard"); + + this.color.setRed(true); + this.color.setBlue(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {2}, Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new JhoiraOfTheGhituSuspendEffect(), new GenericManaCost(2)); + ability.addCost(new ExileFromHandCost(new TargetCardInHand(new FilterNonlandCard("a nonland card from your hand")))); + this.addAbility(ability); + + } + + public JhoiraOfTheGhitu(final JhoiraOfTheGhitu card) { + super(card); + } + + @Override + public JhoiraOfTheGhitu copy() { + return new JhoiraOfTheGhitu(this); + } +} + +class JhoiraOfTheGhituSuspendEffect extends OneShotEffect { + + public JhoiraOfTheGhituSuspendEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend (At the beginning of your upkeep, remove a time counter from that card. When the last is removed, cast it without paying its mana cost. If it's a creature, it has haste.)"; + } + + public JhoiraOfTheGhituSuspendEffect(final JhoiraOfTheGhituSuspendEffect effect) { + super(effect); + } + + @Override + public JhoiraOfTheGhituSuspendEffect copy() { + return new JhoiraOfTheGhituSuspendEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + List cards = new ArrayList(); + for (Cost cost: source.getCosts()) { + if (cost instanceof ExileFromHandCost) { + cards = ((ExileFromHandCost) cost).getCards(); + } + } + if (cards != null && !cards.isEmpty()) { + Card card = game.getCard(cards.get(0).getId()); + boolean hasSuspend = false; + for (Ability ability :card.getAbilities()) { + if (ability instanceof SuspendAbility) { + hasSuspend = true; + break; + } + } + + UUID exileId = (UUID) game.getState().getValue("SuspendExileId" + source.getControllerId().toString()); + if (exileId == null) { + exileId = UUID.randomUUID(); + game.getState().setValue("SuspendExileId" + source.getControllerId().toString(), exileId); + } + if (card.moveToExile(exileId, new StringBuilder("Suspended cards of ").append(controller.getName()).toString() , source.getSourceId(), game)) { + card.addCounters(CounterType.TIME.createInstance(4), game); + if (!hasSuspend) { + // add suspend ability + // TODO: Find a better solution for giving suspend to a card. + // If the exiled card leaves exile by another way, the abilites won't be removed from the card + Abilities oldAbilities = card.getAbilities().copy(); + SuspendAbility suspendAbility = new SuspendAbility(4, null, card); + card.addAbility(suspendAbility); + + for (Ability ability :card.getAbilities()) { + if (!oldAbilities.contains(ability)) { + ability.setControllerId(source.getControllerId()); + game.getState().addAbility(ability, card.getId(), card); + } + } + + } + game.informPlayers(new StringBuilder(controller.getName()).append(" suspends (").append(4).append(") ").append(card.getName()).toString()); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/LatchkeyFaerie.java b/Mage.Sets/src/mage/sets/modernmasters/LatchkeyFaerie.java new file mode 100644 index 00000000000..14dd89fc3ff --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/LatchkeyFaerie.java @@ -0,0 +1,77 @@ +/* + * 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.modernmasters; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.ProwlCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ProwlAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class LatchkeyFaerie extends CardImpl { + + public LatchkeyFaerie(UUID ownerId) { + super(ownerId, 50, "Latchkey Faerie", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "MMA"; + this.subtype.add("Faerie"); + this.subtype.add("Rogue"); + + this.color.setBlue(true); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Prowl {2}{U} + this.addAbility(new ProwlAbility(this, "{2}{U}")); + // When Latchkey Faerie enters the battlefield, if its prowl cost was paid, draw a card. + EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DrawCardControllerEffect(1), false); + this.addAbility(new ConditionalTriggeredAbility(ability, ProwlCondition.getInstance(), + "When {this} enters the battlefield, if its prowl cost was paid, draw a card.")); + + } + + public LatchkeyFaerie(final LatchkeyFaerie card) { + super(card); + } + + @Override + public LatchkeyFaerie copy() { + return new LatchkeyFaerie(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java b/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java index 5a6d40d80d7..280f0d16d32 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java +++ b/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java @@ -142,7 +142,7 @@ class ThievingSpriteEffect extends OneShotEffect { Card card = revealedCards.get(targetInHand.getFirstTarget(), game); if (card != null) { targetPlayer.discard(card, source, game); - game.informPlayers(new StringBuilder("Thieving Sprite").append(targetPlayer.getName()).append("discarded ").append(card.getName()).toString()); + game.informPlayers(new StringBuilder("Thieving Sprite: ").append(targetPlayer.getName()).append(" discarded ").append(card.getName()).toString()); } } return true; diff --git a/Mage.Sets/src/mage/sets/modernmasters/TorrentOfStone.java b/Mage.Sets/src/mage/sets/modernmasters/TorrentOfStone.java new file mode 100644 index 00000000000..bc8ba0e686c --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/TorrentOfStone.java @@ -0,0 +1,52 @@ +/* + * 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.modernmasters; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class TorrentOfStone extends mage.sets.betrayersofkamigawa.TorrentOfStone { + + public TorrentOfStone(UUID ownerId) { + super(ownerId); + this.cardNumber = 137; + this.expansionSetCode = "MMA"; + } + + public TorrentOfStone(final TorrentOfStone card) { + super(card); + } + + @Override + public TorrentOfStone copy() { + return new TorrentOfStone(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/VerdelothTheAncient.java b/Mage.Sets/src/mage/sets/modernmasters/VerdelothTheAncient.java new file mode 100644 index 00000000000..7fcc11e8189 --- /dev/null +++ b/Mage.Sets/src/mage/sets/modernmasters/VerdelothTheAncient.java @@ -0,0 +1,52 @@ +/* + * 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.modernmasters; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class VerdelothTheAncient extends mage.sets.invasion.VerdelothTheAncient { + + public VerdelothTheAncient(UUID ownerId) { + super(ownerId); + this.cardNumber = 172; + this.expansionSetCode = "MMA"; + } + + public VerdelothTheAncient(final VerdelothTheAncient card) { + super(card); + } + + @Override + public VerdelothTheAncient copy() { + return new VerdelothTheAncient(this); + } +} diff --git a/Mage.Sets/src/mage/sets/morningtide/AuntiesSnitch.java b/Mage.Sets/src/mage/sets/morningtide/AuntiesSnitch.java new file mode 100644 index 00000000000..619eb63da4b --- /dev/null +++ b/Mage.Sets/src/mage/sets/morningtide/AuntiesSnitch.java @@ -0,0 +1,54 @@ +/* + * 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.morningtide; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class AuntiesSnitch extends mage.sets.modernmasters.AuntiesSnitch { + + public AuntiesSnitch(UUID ownerId) { + super(ownerId); + this.cardNumber = 57; + this.expansionSetCode = "MOR"; + this.rarity = Rarity.RARE; + } + + public AuntiesSnitch(final AuntiesSnitch card) { + super(card); + } + + @Override + public AuntiesSnitch copy() { + return new AuntiesSnitch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/morningtide/EarwigSquad.java b/Mage.Sets/src/mage/sets/morningtide/EarwigSquad.java new file mode 100644 index 00000000000..ebdc6e0be78 --- /dev/null +++ b/Mage.Sets/src/mage/sets/morningtide/EarwigSquad.java @@ -0,0 +1,52 @@ +/* + * 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.morningtide; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class EarwigSquad extends mage.sets.modernmasters.EarwigSquad { + + public EarwigSquad(UUID ownerId) { + super(ownerId); + this.cardNumber = 60; + this.expansionSetCode = "MOR"; + } + + public EarwigSquad(final EarwigSquad card) { + super(card); + } + + @Override + public EarwigSquad copy() { + return new EarwigSquad(this); + } +} diff --git a/Mage.Sets/src/mage/sets/morningtide/LatchkeyFaerie.java b/Mage.Sets/src/mage/sets/morningtide/LatchkeyFaerie.java new file mode 100644 index 00000000000..93dbb9c7482 --- /dev/null +++ b/Mage.Sets/src/mage/sets/morningtide/LatchkeyFaerie.java @@ -0,0 +1,52 @@ +/* + * 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.morningtide; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class LatchkeyFaerie extends mage.sets.modernmasters.LatchkeyFaerie { + + public LatchkeyFaerie(UUID ownerId) { + super(ownerId); + this.cardNumber = 39; + this.expansionSetCode = "MOR"; + } + + public LatchkeyFaerie(final LatchkeyFaerie card) { + super(card); + } + + @Override + public LatchkeyFaerie copy() { + return new LatchkeyFaerie(this); + } +} diff --git a/Mage.Sets/src/mage/sets/morningtide/NogginWhack.java b/Mage.Sets/src/mage/sets/morningtide/NogginWhack.java new file mode 100644 index 00000000000..c8a5be67391 --- /dev/null +++ b/Mage.Sets/src/mage/sets/morningtide/NogginWhack.java @@ -0,0 +1,143 @@ +/* + * 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.morningtide; + +import java.util.List; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.ProwlAbility; +import mage.cards.Card; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPlayer; + +/** + * + * @author LevelX2 + */ +public class NogginWhack extends CardImpl { + + public NogginWhack(UUID ownerId) { + super(ownerId, 70, "Noggin Whack", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); + this.expansionSetCode = "MOR"; + this.supertype.add("Tribal"); + this.subtype.add("Rogue"); + + this.color.setBlack(true); + + // Prowl {1}{B} + this.addAbility(new ProwlAbility(this, "{1}{B}")); + // Target player reveals three cards from his or her hand. You choose two of them. That player discards those cards. + this.getSpellAbility().addEffect(new NogginWhackEffect()); + this.getSpellAbility().addTarget(new TargetPlayer(true)); + + } + + public NogginWhack(final NogginWhack card) { + super(card); + } + + @Override + public NogginWhack copy() { + return new NogginWhack(this); + } +} + +class NogginWhackEffect extends OneShotEffect { + + public NogginWhackEffect() { + super(Outcome.Benefit); + this.staticText = "Target player reveals three cards from his or her hand. You choose two of them. That player discards those cards"; + } + + public NogginWhackEffect(final NogginWhackEffect effect) { + super(effect); + } + + @Override + public NogginWhackEffect copy() { + return new NogginWhackEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetPlayer = game.getPlayer(source.getFirstTarget()); + Card sourceCard = game.getCard(source.getSourceId()); + if (controller != null && targetPlayer != null && sourceCard != null) { + Cards cardsInHand = new CardsImpl(); + cardsInHand.addAll(targetPlayer.getHand()); + + int count = Math.min(cardsInHand.size(), 3); + + TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard()); + target.setRequired(true); + Cards revealedCards = new CardsImpl(); + + if (targetPlayer.chooseTarget(Outcome.Discard, cardsInHand, target, source, game)) { + List targets = target.getTargets(); + for (UUID targetId : targets) { + Card card = game.getCard(targetId); + if (card != null) { + revealedCards.add(card); + } + } + } + + int cardsToDiscard = Math.min(revealedCards.size(), 2); + TargetCard targetInHand = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, new FilterCard("card to discard")); + targetInHand.setRequired(true); + + if (!revealedCards.isEmpty()) { + targetPlayer.revealCards("Noggin Whack", revealedCards, game); + controller.chooseTarget(Outcome.Exile, revealedCards, targetInHand, source, game); + for (UUID cardId : (List) targetInHand.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); + game.informPlayers(new StringBuilder(sourceCard.getName()).append(": Discarded card ").append(card.getName()).toString()); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/morningtide/WalkerOfTheGrove.java b/Mage.Sets/src/mage/sets/morningtide/WalkerOfTheGrove.java index 4fb0692805e..1f542adb0df 100644 --- a/Mage.Sets/src/mage/sets/morningtide/WalkerOfTheGrove.java +++ b/Mage.Sets/src/mage/sets/morningtide/WalkerOfTheGrove.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.constants.CardType; import mage.constants.Rarity; import mage.MageInt; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.keyword.EvokeAbility; import mage.cards.CardImpl; @@ -53,7 +53,7 @@ public class WalkerOfTheGrove extends CardImpl { this.toughness = new MageInt(7); // When Walker of the Grove leaves the battlefield, put a 4/4 green Elemental creature token onto the battlefield. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WalkerOfTheGroveToken(),1))); + this.addAbility(new LeavesBattlefieldTriggeredAbility(new CreateTokenEffect(new WalkerOfTheGroveToken(),1),false)); // Evoke {4}{G} this.addAbility(new EvokeAbility(this, "{4}{G}")); } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/LifesFinale.java b/Mage.Sets/src/mage/sets/newphyrexia/LifesFinale.java index 7792c363caf..20e3dad0276 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/LifesFinale.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/LifesFinale.java @@ -112,9 +112,9 @@ class LifesFinaleEffect extends OneShotEffect { } } } + opponent.shuffleLibrary(game); + return true; } - - opponent.shuffleLibrary(game); - return true; + return false; } } diff --git a/Mage.Sets/src/mage/sets/ninthedition/EarlyHarvest.java b/Mage.Sets/src/mage/sets/ninthedition/EarlyHarvest.java new file mode 100644 index 00000000000..00c5b8ab080 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ninthedition/EarlyHarvest.java @@ -0,0 +1,98 @@ +/* + * 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.ninthedition; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterLandPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author Plopman + */ +public class EarlyHarvest extends CardImpl { + + public EarlyHarvest(UUID ownerId) { + super(ownerId, 235, "Early Harvest", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{1}{G}{G}"); + this.expansionSetCode = "9ED"; + + this.color.setGreen(true); + + // Target player untaps all basic lands he or she controls. + this.getSpellAbility().addEffect(new UntapAllLandsTargetEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public EarlyHarvest(final EarlyHarvest card) { + super(card); + } + + @Override + public EarlyHarvest copy() { + return new EarlyHarvest(this); + } +} + +class UntapAllLandsTargetEffect extends OneShotEffect { + + public UntapAllLandsTargetEffect() { + super(Outcome.Untap); + staticText = "Target player untaps all basic lands he or she controls"; + } + + public UntapAllLandsTargetEffect(final UntapAllLandsTargetEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (player != null) { + for (Permanent land: game.getBattlefield().getAllActivePermanents(new FilterLandPermanent(), player.getId(), game)) { + land.untap(game); + } + return true; + } + return false; + } + + @Override + public UntapAllLandsTargetEffect copy() { + return new UntapAllLandsTargetEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/planarchaos/RathiTrapper.java b/Mage.Sets/src/mage/sets/planarchaos/RathiTrapper.java index 7a55cb292ea..954a91b4900 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/RathiTrapper.java +++ b/Mage.Sets/src/mage/sets/planarchaos/RathiTrapper.java @@ -34,6 +34,7 @@ import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; @@ -58,6 +59,7 @@ public class RathiTrapper extends CardImpl { // {B}, {tap}: Tap target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new ManaCostsImpl("{B}")); + ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/planechase/FertileGround.java b/Mage.Sets/src/mage/sets/planechase/FertileGround.java new file mode 100644 index 00000000000..5668ee980ee --- /dev/null +++ b/Mage.Sets/src/mage/sets/planechase/FertileGround.java @@ -0,0 +1,52 @@ +/* + * 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.planechase; + +import java.util.UUID; + +/** + * + * @author Plopman + */ +public class FertileGround extends mage.sets.urzassaga.FertileGround { + + public FertileGround(UUID ownerId) { + super(ownerId); + this.cardNumber = 71; + this.expansionSetCode = "HOP"; + } + + public FertileGround(final FertileGround card) { + super(card); + } + + @Override + public FertileGround copy() { + return new FertileGround(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java b/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java index cc029e3339f..58307e8acb9 100644 --- a/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java +++ b/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java @@ -94,18 +94,17 @@ class ThirstforKnowledgeEffect extends OneShotEffect { filter.add(new CardTypePredicate(CardType.ARTIFACT)); if (you != null && you.getHand().count(filter, game) > 0 - && you.chooseUse(Outcome.Discard, "Do you want to discard an artifact? If you do not, you must discard 2 cards", game)) { + && you.chooseUse(Outcome.Discard, "Do you want to discard an artifact? If you don't, you must discard 2 cards", game)) { Cost cost = new DiscardTargetCost(new TargetCardInHand(filter)); - if (cost.canPay(you.getId(), you.getId(), game)) { - if (!cost.pay(source, game, you.getId(), you.getId(), false)) { - you.discard(2, source, game); + if (cost.canPay(source.getSourceId(), you.getId(), game)) { + if (cost.pay(source, game, source.getSourceId(), you.getId(), false)) { + return true; } - return true; } } - if (you != null - && you.getHand().count(filter, game) == 0) { + if (you != null) { you.discard(2, source, game); + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java index 1eadb801427..fff7c40f60e 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/GenesisWave.java @@ -106,7 +106,7 @@ class GenesisWaveEffect extends OneShotEffect { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); + card.putOntoBattlefield(game, Zone.PICK, source.getSourceId(), source.getControllerId()); } target1.clearChosen(); } diff --git a/Mage.Sets/src/mage/sets/seventhedition/EarlyHarvest.java b/Mage.Sets/src/mage/sets/seventhedition/EarlyHarvest.java new file mode 100644 index 00000000000..61a9948cb44 --- /dev/null +++ b/Mage.Sets/src/mage/sets/seventhedition/EarlyHarvest.java @@ -0,0 +1,52 @@ +/* + * 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.seventhedition; + +import java.util.UUID; + +/** + * + * @author Plopman + */ +public class EarlyHarvest extends mage.sets.ninthedition.EarlyHarvest { + + public EarlyHarvest(UUID ownerId) { + super(ownerId); + this.cardNumber = 237; + this.expansionSetCode = "7ED"; + } + + public EarlyHarvest(final EarlyHarvest card) { + super(card); + } + + @Override + public EarlyHarvest copy() { + return new EarlyHarvest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/FistsOfTheDemigod.java b/Mage.Sets/src/mage/sets/shadowmoor/FistsOfTheDemigod.java new file mode 100644 index 00000000000..0598b992789 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/FistsOfTheDemigod.java @@ -0,0 +1,89 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.WitherAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class FistsOfTheDemigod extends CardImpl { + + public FistsOfTheDemigod(UUID ownerId) { + super(ownerId, 187, "Fists of the Demigod", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{B/R}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Aura"); + + this.color.setRed(true); + this.color.setBlack(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is black, it gets +1/+1 and has wither. + SimpleStaticAbility blackAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.BLACK), "As long as enchanted creature is black, it gets +1/+1")); + blackAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(WitherAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.BLACK), "and has wither")); + this.addAbility(blackAbility); + // As long as enchanted creature is red, it gets +1/+1 and has first strike. + SimpleStaticAbility redAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.RED), "As long as enchanted creature is red, it gets +1/+1")); + redAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.RED), "and has first strike")); + this.addAbility(redAbility); + } + + public FistsOfTheDemigod(final FistsOfTheDemigod card) { + super(card); + } + + @Override + public FistsOfTheDemigod copy() { + return new FistsOfTheDemigod(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/HelmOfTheGhastlord.java b/Mage.Sets/src/mage/sets/shadowmoor/HelmOfTheGhastlord.java new file mode 100644 index 00000000000..f0e24efdb8d --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/HelmOfTheGhastlord.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.shadowmoor; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DiscardTargetEffect; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class HelmOfTheGhastlord extends CardImpl { + + public HelmOfTheGhastlord(UUID ownerId) { + super(ownerId, 166, "Helm of the Ghastlord", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{U/B}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Aura"); + + this.color.setBlue(true); + this.color.setBlack(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is blue, it gets +1/+1 and has "Whenever this creature deals damage to an opponent, draw a card." + SimpleStaticAbility blueAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "As long as enchanted creature is blue, it gets +1/+1")); + blueAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardControllerEffect(1),false), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "and has \"Whenever this creature deals damage to an opponent, draw a card.\"")); + this.addAbility(blueAbility); + // As long as enchanted creature is black, it gets +1/+1 and has "Whenever this creature deals damage to an opponent, that player discards a card." + SimpleStaticAbility blackAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.BLACK), "As long as enchanted creature is black, it gets +1/+1")); + blackAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(new DealsCombatDamageToAPlayerTriggeredAbility(new DiscardTargetEffect(1), false, true), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.BLACK), "and has \"Whenever this creature deals damage to an opponent, that player discards a card.\"")); + this.addAbility(blackAbility); + } + + public HelmOfTheGhastlord(final HelmOfTheGhastlord card) { + super(card); + } + + @Override + public HelmOfTheGhastlord copy() { + return new HelmOfTheGhastlord(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/RunesOfTheDeus.java b/Mage.Sets/src/mage/sets/shadowmoor/RunesOfTheDeus.java new file mode 100644 index 00000000000..fd088d802a8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/RunesOfTheDeus.java @@ -0,0 +1,89 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class RunesOfTheDeus extends CardImpl { + + public RunesOfTheDeus(UUID ownerId) { + super(ownerId, 215, "Runes of the Deus", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{4}{R/G}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Aura"); + + this.color.setRed(true); + this.color.setGreen(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is red, it gets +1/+1 and has double strike. + SimpleStaticAbility redAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.RED), "As long as enchanted creature is red, it gets +1/+1")); + redAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(DoubleStrikeAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.RED), "and has double strike")); + this.addAbility(redAbility); + // As long as enchanted creature is green, it gets +1/+1 and has trample. + SimpleStaticAbility greenAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "As long as enchanted creature is green, it gets +1/+1")); + greenAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "and has trample")); + this.addAbility(greenAbility); + } + + public RunesOfTheDeus(final RunesOfTheDeus card) { + super(card); + } + + @Override + public RunesOfTheDeus copy() { + return new RunesOfTheDeus(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/ShieldOfTheOversoul.java b/Mage.Sets/src/mage/sets/shadowmoor/ShieldOfTheOversoul.java new file mode 100644 index 00000000000..2cc3a43b4d7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/ShieldOfTheOversoul.java @@ -0,0 +1,89 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class ShieldOfTheOversoul extends CardImpl { + + public ShieldOfTheOversoul(UUID ownerId) { + super(ownerId, 242, "Shield of the Oversoul", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{G/W}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Aura"); + + this.color.setGreen(true); + this.color.setWhite(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is green, it gets +1/+1 and is indestructible. + SimpleStaticAbility greenAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "As long as enchanted creature is green, it gets +1/+1")); + greenAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(IndestructibleAbility.getInstance() ,AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.GREEN), "and is indestructible")); + this.addAbility(greenAbility); + // As long as enchanted creature is white, it gets +1/+1 and has flying. + SimpleStaticAbility whiteAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.WHITE), "As long as enchanted creature is white, it gets +1/+1")); + whiteAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.WHITE), "and has flying")); + this.addAbility(whiteAbility); + } + + public ShieldOfTheOversoul(final ShieldOfTheOversoul card) { + super(card); + } + + @Override + public ShieldOfTheOversoul copy() { + return new ShieldOfTheOversoul(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/SteelOfTheGodhead.java b/Mage.Sets/src/mage/sets/shadowmoor/SteelOfTheGodhead.java new file mode 100644 index 00000000000..13036e522bc --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/SteelOfTheGodhead.java @@ -0,0 +1,89 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedCreatureColorCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.UnblockableAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Plopman + */ +public class SteelOfTheGodhead extends CardImpl { + + public SteelOfTheGodhead(UUID ownerId) { + super(ownerId, 150, "Steel of the Godhead", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{W/U}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Aura"); + + this.color.setBlue(true); + this.color.setWhite(true); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As long as enchanted creature is white, it gets +1/+1 and has lifelink. + SimpleStaticAbility whiteAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.WHITE), "As long as enchanted creature is white, it gets +1/+1")); + whiteAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.WHITE), "and has lifelink")); + this.addAbility(whiteAbility); + // As long as enchanted creature is blue, it gets +1/+1 and is unblockable. + SimpleStaticAbility blueAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinousEffect(new BoostEnchantedEffect(1, 1), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "As long as enchanted creature is blue, it gets +1/+1")); + blueAbility.addEffect(new ConditionalContinousEffect(new GainAbilityAttachedEffect(new UnblockableAbility(), AttachmentType.AURA), new EnchantedCreatureColorCondition(ObjectColor.BLUE), "and is unblockable")); + this.addAbility(blueAbility); + } + + public SteelOfTheGodhead(final SteelOfTheGodhead card) { + super(card); + } + + @Override + public SteelOfTheGodhead copy() { + return new SteelOfTheGodhead(this); + } +} diff --git a/Mage.Sets/src/mage/sets/sixthedition/EarlyHarvest.java b/Mage.Sets/src/mage/sets/sixthedition/EarlyHarvest.java new file mode 100644 index 00000000000..a6da55f486e --- /dev/null +++ b/Mage.Sets/src/mage/sets/sixthedition/EarlyHarvest.java @@ -0,0 +1,52 @@ +/* + * 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.sixthedition; + +import java.util.UUID; + +/** + * + * @author Plopman + */ +public class EarlyHarvest extends mage.sets.ninthedition.EarlyHarvest { + + public EarlyHarvest(UUID ownerId) { + super(ownerId); + this.cardNumber = 222; + this.expansionSetCode = "6ED"; + } + + public EarlyHarvest(final EarlyHarvest card) { + super(card); + } + + @Override + public EarlyHarvest copy() { + return new EarlyHarvest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timeshifted/VerdelothTheAncient.java b/Mage.Sets/src/mage/sets/timeshifted/VerdelothTheAncient.java new file mode 100644 index 00000000000..60183eb6528 --- /dev/null +++ b/Mage.Sets/src/mage/sets/timeshifted/VerdelothTheAncient.java @@ -0,0 +1,54 @@ +/* + * 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.timeshifted; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class VerdelothTheAncient extends mage.sets.invasion.VerdelothTheAncient { + + public VerdelothTheAncient(UUID ownerId) { + super(ownerId); + this.cardNumber = 88; + this.expansionSetCode = "TSB"; + this.rarity = Rarity.SPECIAL; + } + + public VerdelothTheAncient(final VerdelothTheAncient card) { + super(card); + } + + @Override + public VerdelothTheAncient copy() { + return new VerdelothTheAncient(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timespiral/GreaterGargadon.java b/Mage.Sets/src/mage/sets/timespiral/GreaterGargadon.java index b02a8c7f3db..cdf65622ee6 100644 --- a/Mage.Sets/src/mage/sets/timespiral/GreaterGargadon.java +++ b/Mage.Sets/src/mage/sets/timespiral/GreaterGargadon.java @@ -114,6 +114,6 @@ class GreaterGargadonAbility extends ActivatedAbilityImpl { + + public FertileGround(UUID ownerId) { + super(ownerId, 252, "Fertile Ground", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); + this.expansionSetCode = "USG"; + this.subtype.add("Aura"); + + this.color.setGreen(true); + + // Enchant land + TargetPermanent auraTarget = new TargetLandPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Whenever enchanted land is tapped for mana, its controller adds one mana of any color to his or her mana pool. + this.addAbility(new FertileGroundTriggeredAbility()); + } + + public FertileGround(final FertileGround card) { + super(card); + } + + @Override + public FertileGround copy() { + return new FertileGround(this); + } +} + +class FertileGroundTriggeredAbility extends TriggeredManaAbility { + + + public FertileGroundTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect()); + this.addChoice(new ChoiceColor()); + } + + public FertileGroundTriggeredAbility(FertileGroundTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent enchantment = game.getPermanent(this.getSourceId()); + if(event.getType() == GameEvent.EventType.TAPPED_FOR_MANA){ + if (enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo())) { + return true; + } + } + return false; + } + + @Override + public FertileGroundTriggeredAbility copy() { + return new FertileGroundTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color to his or her mana pool"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/zendikar/MoldShambler.java b/Mage.Sets/src/mage/sets/zendikar/MoldShambler.java index 052ece5cedb..d623ff2dd9c 100644 --- a/Mage.Sets/src/mage/sets/zendikar/MoldShambler.java +++ b/Mage.Sets/src/mage/sets/zendikar/MoldShambler.java @@ -40,6 +40,7 @@ import mage.cards.CardImpl; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.Target; import mage.target.TargetPermanent; /** @@ -69,7 +70,9 @@ public class MoldShambler extends CardImpl { // When Mold Shambler enters the battlefield, if it was kicked, destroy target noncreature permanent. EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), false); - ability.addTarget(new TargetPermanent(filter)); + Target target = new TargetPermanent(filter); + target.setRequired(true); + ability.addTarget(target); this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.getInstance(), "When {this} enters the battlefield, if it was kicked, destroy target noncreature permanent.")); } diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index be15e14b18c..86d309d6376 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -53,6 +53,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; import mage.abilities.keyword.EntwineAbility; +import mage.constants.SpellAbilityType; /** @@ -162,11 +163,22 @@ public abstract class AbilityImpl> implements Ability { @Override public boolean activate(Game game, boolean noMana) { - // 20110204 - 700.2 + /* 20130201 - 601.2b + * If the spell is modal the player announces the mode choice (see rule 700.2). + */ if (!modes.choose(game, this)) { return false; } - //20100716 - 601.2b + + /* 20130201 - 601.2b + * If the player wishes to splice any cards onto the spell (see rule 702.45), he + * or she reveals those cards in his or her hand. + */ + if (this.abilityType.equals(AbilityType.SPELL)) { + game.getContinuousEffects().applySpliceEffects(this, game); + } + + Card card = game.getCard(sourceId); if (card != null) { card.adjustChoices(this, game); @@ -179,7 +191,7 @@ public abstract class AbilityImpl> implements Ability { } } - // 20121001 - 601.2b + // 20130201 - 601.2b // If the spell has alternative or additional costs that will be paid as it's being cast such // as buyback, kicker, or convoke costs (see rules 117.8 and 117.9), the player announces his // or her intentions to pay any or all of those costs (see rule 601.2e). @@ -192,12 +204,12 @@ public abstract class AbilityImpl> implements Ability { break; } } - if (ability instanceof OptionalAdditionalSourceCosts - && !(ability instanceof EntwineAbility)) { + if (ability instanceof OptionalAdditionalSourceCosts) { ((OptionalAdditionalSourceCosts)ability).addOptionalAdditionalCosts(this, game); } } } + // 20121001 - 601.2b // If the spell has a variable cost that will be paid as it's being cast (such as an {X} in // its mana cost; see rule 107.3), the player announces the value of that variable. diff --git a/Mage/src/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/mage/abilities/ActivatedAbilityImpl.java index fd270faf351..1f0ca1412e7 100644 --- a/Mage/src/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/mage/abilities/ActivatedAbilityImpl.java @@ -243,31 +243,53 @@ public abstract class ActivatedAbilityImpl> ex } else { sb.append("unknown"); } - if (object instanceof Spell && ((Spell) object).getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.SPLIT_FUSED)) { - Spell spell = (Spell) object; - int i = 0; - for (SpellAbility spellAbility : spell.getSpellAbilities()) { - i++; - String half; - if (i == 1) { - half = " left"; - } else { - half = " right"; + if (object instanceof Spell && ((Spell) object).getSpellAbilities().size() > 1) { + if (((Spell) object).getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.SPLIT_FUSED)) { + Spell spell = (Spell) object; + int i = 0; + for (SpellAbility spellAbility : spell.getSpellAbilities()) { + i++; + String half; + if (i == 1) { + half = " left"; + } else { + half = " right"; + } + if (spellAbility.getTargets().size() > 0) { + sb.append(half).append(" half targeting "); + for (Target target: spellAbility.getTargets()) { + sb.append(target.getTargetedName(game)); + } + } } - if (spellAbility.getTargets().size() > 0) { - sb.append(half).append(" half targeting "); - for (Target target: spellAbility.getTargets()) { - sb.append(target.getTargetedName(game)); + } else { + Spell spell = (Spell) object; + int i = 0; + for (SpellAbility spellAbility : spell.getSpellAbilities()) { + i++; + if ( i > 1) { + sb.append(" splicing "); + if (spellAbility.name.length() > 5 && spellAbility.name.startsWith("Cast ")) { + sb.append(spellAbility.name.substring(5)); + } else { + sb.append(spellAbility.name); + } + } + if (spellAbility.getTargets().size() > 0) { + for (Target target: spellAbility.getTargets()) { + sb.append(" targeting "); + sb.append(target.getTargetedName(game)); + } } } } } else if (object instanceof Spell && ((Spell) object).getSpellAbility().getModes().size() > 1) { - Modes modes = ((Spell) object).getSpellAbility().getModes(); + Modes spellModes = ((Spell) object).getSpellAbility().getModes(); int item = 0; - for (Mode mode : modes.values()) { + for (Mode mode : spellModes.values()) { item++; - if (modes.getSelectedModes().contains(mode.getId())) { - modes.setMode(mode); + if (spellModes.getSelectedModes().contains(mode.getId())) { + spellModes.setMode(mode); sb.append(" (mode ").append(item).append(")"); if (getTargets().size() > 0) { sb.append(" targeting "); diff --git a/Mage/src/mage/abilities/common/BlocksAttachedTriggeredAbility.java b/Mage/src/mage/abilities/common/BlocksAttachedTriggeredAbility.java index 8b9b87db34b..ba7e08a2965 100644 --- a/Mage/src/mage/abilities/common/BlocksAttachedTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/BlocksAttachedTriggeredAbility.java @@ -19,6 +19,7 @@ import mage.target.targetpointer.FixedTarget; public class BlocksAttachedTriggeredAbility extends TriggeredAbilityImpl{ private boolean setFixedTargetPointer; private String attachedDescription; + private boolean setFixedTargetPointerToBlocked; public BlocksAttachedTriggeredAbility(Effect effect, String attachedDescription, boolean optional) { this(effect, attachedDescription, optional, false); @@ -29,6 +30,13 @@ public class BlocksAttachedTriggeredAbility extends TriggeredAbilityImpl { public ExileFromGraveCost(TargetCardInYourGraveyard target) { this.addTarget(target); if (target.getMaxNumberOfTargets() > 1) { - this.text = "Exile " + target.getMaxNumberOfTargets() + " " + target.getTargetName(); + this.text = "Exile " + CardUtil.numberToText(target.getMaxNumberOfTargets()) + " " + target.getTargetName(); } else { this.text = "Exile " + target.getTargetName(); diff --git a/Mage/src/mage/abilities/dynamicvalue/common/MultikickerCount.java b/Mage/src/mage/abilities/dynamicvalue/common/MultikickerCount.java index 5f70fe6f98d..05276d85c3f 100644 --- a/Mage/src/mage/abilities/dynamicvalue/common/MultikickerCount.java +++ b/Mage/src/mage/abilities/dynamicvalue/common/MultikickerCount.java @@ -57,7 +57,7 @@ public class MultikickerCount implements DynamicValue { } @Override - public DynamicValue copy() { + public MultikickerCount copy() { return new MultikickerCount(); } diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index b08a3fa92a0..0cc5102bfcd 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -36,11 +36,22 @@ import mage.constants.Layer; import mage.constants.SubLayer; import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; +import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.Outcome; +import mage.constants.SpellAbilityType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardIdPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.common.TargetCardInHand; /** * @@ -58,6 +69,7 @@ public class ContinuousEffects implements Serializable { private ContinuousEffectsList restrictionEffects = new ContinuousEffectsList(); private ContinuousEffectsList asThoughEffects = new ContinuousEffectsList(); private ContinuousEffectsList costModificationEffects = new ContinuousEffectsList(); + private ContinuousEffectsList spliceCardEffects = new ContinuousEffectsList(); private List> allEffectsLists = new ArrayList>(); @@ -88,6 +100,7 @@ public class ContinuousEffects implements Serializable { restrictionEffects = effect.restrictionEffects.copy(); asThoughEffects = effect.asThoughEffects.copy(); costModificationEffects = effect.costModificationEffects.copy(); + spliceCardEffects = effect.spliceCardEffects.copy(); for (Map.Entry entry : effect.sources.entrySet()) { sources.put(entry.getKey(), entry.getValue()); } @@ -103,6 +116,7 @@ public class ContinuousEffects implements Serializable { allEffectsLists.add(restrictionEffects); allEffectsLists.add(asThoughEffects); allEffectsLists.add(costModificationEffects); + allEffectsLists.add(spliceCardEffects); } public ContinuousEffects copy() { @@ -125,6 +139,7 @@ public class ContinuousEffects implements Serializable { restrictionEffects.removeEndOfCombatEffects(); asThoughEffects.removeEndOfCombatEffects(); costModificationEffects.removeEndOfCombatEffects(); + spliceCardEffects.removeEndOfCombatEffects(); } public void removeEndOfTurnEffects() { @@ -135,6 +150,7 @@ public class ContinuousEffects implements Serializable { restrictionEffects.removeEndOfTurnEffects(); asThoughEffects.removeEndOfTurnEffects(); costModificationEffects.removeEndOfTurnEffects(); + spliceCardEffects.removeEndOfTurnEffects(); } public void removeInactiveEffects(Game game) { @@ -145,6 +161,7 @@ public class ContinuousEffects implements Serializable { restrictionEffects.removeInactiveEffects(game); asThoughEffects.removeInactiveEffects(game); costModificationEffects.removeInactiveEffects(game); + spliceCardEffects.removeInactiveEffects(game); } public List getLayeredEffects(Game game) { @@ -328,6 +345,29 @@ public class ContinuousEffects implements Serializable { return costEffects; } + /** + * Filters out splice effects that are not active. + * + * @param game + * @return + */ + private List getApplicableSpliceCardEffects(Game game) { + List spliceEffects = new ArrayList(); + + for (SpliceCardEffect effect: spliceCardEffects) { + HashSet abilities = spliceCardEffects.getAbility(effect.getId()); + for (Ability ability : abilities) { + if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, false)) { + if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) { + spliceEffects.add(effect); + break; + } + } + } + } + + return spliceEffects; + } public boolean asThough(UUID objectId, AsThoughEffectType type, Game game) { List asThoughEffectsList = getApplicableAsThoughEffects(game); @@ -390,6 +430,68 @@ public class ContinuousEffects implements Serializable { } } + /** + * Checks all available splice effects to be applied. + * + * @param abilityToModify + * @param game + * @return + */ + public void applySpliceEffects ( Ability abilityToModify, Game game ) { + if ( ((SpellAbility) abilityToModify).getSpellAbilityType().equals(SpellAbilityType.SPLICE)) { + // on a spliced ability of a spell can't be spliced again + return; + } + List spliceEffects = getApplicableSpliceCardEffects(game); + // get the applyable splice abilities + List spliceAbilities = new ArrayList(); + for (SpliceCardEffect effect : spliceEffects) { + HashSet abilities = spliceCardEffects.getAbility(effect.getId()); + for (Ability ability : abilities) { + if (effect.applies(abilityToModify, ability, game) ) { + spliceAbilities.add((SpliceOntoArcaneAbility) ability); + } + } + } + // check if player wants to use splice + + if (spliceAbilities.size() > 0) { + Player controller = game.getPlayer(abilityToModify.getControllerId()); + if (controller.chooseUse(Outcome.Benefit, "Splice a card?", game)) { + Cards cardsToReveal = new CardsImpl(); + do { + FilterCard filter = new FilterCard("a card to splice"); + ArrayList> idPredicates = new ArrayList>(); + for (SpliceOntoArcaneAbility ability : spliceAbilities) { + idPredicates.add(new CardIdPredicate((ability.getSourceId()))); + } + filter.add(Predicates.or(idPredicates)); + TargetCardInHand target = new TargetCardInHand(filter); + target.setRequired(true); + controller.chooseTarget(Outcome.Benefit, target, abilityToModify, game); + UUID cardId = target.getFirstTarget(); + if (cardId != null) { + SpliceOntoArcaneAbility selectedAbility = null; + for(SpliceOntoArcaneAbility ability :spliceAbilities) { + if (ability.getSourceId().equals(cardId)) { + selectedAbility = ability; + break; + } + } + if (selectedAbility != null) { + SpliceCardEffect spliceEffect = (SpliceCardEffect) selectedAbility.getEffects().get(0); + spliceEffect.apply(game, selectedAbility, abilityToModify); + cardsToReveal.add(game.getCard(cardId)); + spliceAbilities.remove(selectedAbility); + } + } + } while (!spliceAbilities.isEmpty() && controller.chooseUse(Outcome.Benefit, "Splice another card?", game)); + controller.revealCards("Spliced cards", cardsToReveal, game); + } + } + } + + public boolean replaceEvent(GameEvent event, Game game) { boolean caught = false; HashMap> consumed = new HashMap>(); @@ -617,6 +719,10 @@ public class ContinuousEffects implements Serializable { CostModificationEffect newCostModificationEffect = (CostModificationEffect)effect; costModificationEffects.addEffect(newCostModificationEffect, source); break; + case SPLICE: + SpliceCardEffect newSpliceCardEffect = (SpliceCardEffect)effect; + spliceCardEffects.addEffect(newSpliceCardEffect, source); + break; default: ContinuousEffect newEffect = (ContinuousEffect)effect; layeredEffects.addEffect(newEffect, source); diff --git a/Mage/src/mage/abilities/effects/SpliceCardEffect.java b/Mage/src/mage/abilities/effects/SpliceCardEffect.java new file mode 100644 index 00000000000..094b3a98916 --- /dev/null +++ b/Mage/src/mage/abilities/effects/SpliceCardEffect.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.abilities.effects; + +import mage.abilities.Ability; +import mage.game.Game; + +/** + * Represents a {@link ContinuousEffect} that will modify the cost and abilities of a spell + * on the stack (splice a card). {@link mage.abilities.Ability Abilities} with this type of effect will be + * called once and only once from the {@link mage.abilities.AbilityImpl#activate(mage.game.Game, + * boolean) Ability.activate} method before alternative or additional costs are paid. + * + * @param + * @author levelX2 + */ + +public interface SpliceCardEffect> extends ContinuousEffect { + /** + * Called by the {@link ContinuousEffects#costModification(Ability abilityToModify, Game game) ContinuousEffects.costModification} + * method. + * + * @param game The game for which this effect should be applied. + * @param source The source ability of this effect. + * @param abilityToModify The {@link mage.abilities.SpellAbility} or {@link Ability} which should be modified. + * @return + */ + boolean apply ( Game game, Ability source, Ability abilityToModify ); + + /** + * Called by the {@link ContinuousEffects#costModification(mage.abilities.Ability, mage.game.Game) ContinuousEffects.costModification} + * method. + * + * @param abilityToModify The ability to possibly modify. + * @param source The source ability of this effect. + * @param game The game for which this effect shoul dbe applied. + * @return + */ + boolean applies(Ability abilityToModify, Ability source, Game game); +} diff --git a/Mage/src/mage/abilities/effects/SpliceCardEffectImpl.java b/Mage/src/mage/abilities/effects/SpliceCardEffectImpl.java new file mode 100644 index 00000000000..4a4aa90cd2f --- /dev/null +++ b/Mage/src/mage/abilities/effects/SpliceCardEffectImpl.java @@ -0,0 +1,67 @@ +/* + * 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; + +import mage.abilities.Ability; +import mage.constants.Duration; +import mage.constants.EffectType; +import mage.constants.Outcome; +import mage.game.Game; + + +/** + * Simple implementation of a {@link SpliceCardEffect} offering simplified + * construction to setup the object for use by the mage framework. + + * @author LevelX2 + */ +public abstract class SpliceCardEffectImpl> extends ContinuousEffectImpl implements SpliceCardEffect { + + public SpliceCardEffectImpl ( Duration duration, Outcome outcome ) { + super(duration, outcome); + this.effectType = EffectType.SPLICE; + } + + public SpliceCardEffectImpl(final SpliceCardEffectImpl effect) { + super(effect); + this.effectType = effect.effectType; + } + + /** + * Overridden and 'no-op' implementation put in place. + * + * @see #apply(mage.game.Game, mage.abilities.Ability, mage.abilities.Ability) + * + * @param game + * @param source + * @return + */ + @Override + public final boolean apply ( Game game, Ability source ) { return false; } +} diff --git a/Mage/src/mage/abilities/effects/common/CounterTargetEffect.java b/Mage/src/mage/abilities/effects/common/CounterTargetEffect.java index a756b4b819d..b0d764e2c9e 100644 --- a/Mage/src/mage/abilities/effects/common/CounterTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/CounterTargetEffect.java @@ -1,33 +1,33 @@ /* -* 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. -*/ - + * 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 java.util.UUID; import mage.constants.Outcome; import mage.abilities.Ability; import mage.abilities.Mode; @@ -55,12 +55,20 @@ public class CounterTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - return game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game); + boolean countered = false; + for (UUID targetId : source.getTargets().get(0).getTargets()) { + if (game.getStack().counter(targetId, source.getSourceId(), game)) { + countered = true; + } + } + return countered; } @Override public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } return "Counter target " + mode.getTargets().get(0).getTargetName(); } - } diff --git a/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java b/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java index b420aa7bf1d..b331aa9af68 100644 --- a/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java @@ -40,6 +40,7 @@ import mage.game.permanent.Permanent; import mage.target.Target; import java.util.UUID; +import mage.cards.Card; /** * @@ -48,23 +49,29 @@ import java.util.UUID; public class GainAbilityTargetEffect extends ContinuousEffectImpl { protected Ability ability; + // shall a card gain the ability (otherwise permanent) + private boolean onCard; public GainAbilityTargetEffect(Ability ability, Duration duration) { - super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, - ability.getEffects().size() > 0 ? ability.getEffects().get(0).getOutcome() : Outcome.AddAbility); - this.ability = ability; + this(ability, duration, null); } public GainAbilityTargetEffect(Ability ability, Duration duration, String rule) { + this(ability, duration, rule, false); + } + + public GainAbilityTargetEffect(Ability ability, Duration duration, String rule, boolean onCard) { super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, ability.getEffects().size() > 0 ? ability.getEffects().get(0).getOutcome() : Outcome.AddAbility); this.ability = ability; staticText = rule; + this.onCard = onCard; } public GainAbilityTargetEffect(final GainAbilityTargetEffect effect) { super(effect); this.ability = effect.ability.copy(); + this.onCard = effect.onCard; } @Override @@ -81,11 +88,24 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl 0; diff --git a/Mage/src/mage/abilities/keyword/KickerAbility.java b/Mage/src/mage/abilities/keyword/KickerAbility.java index 12e08e9e6f3..0724b88a056 100644 --- a/Mage/src/mage/abilities/keyword/KickerAbility.java +++ b/Mage/src/mage/abilities/keyword/KickerAbility.java @@ -31,8 +31,6 @@ package mage.abilities.keyword; import java.util.Iterator; import java.util.LinkedList; import java.util.List; - -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; @@ -41,8 +39,11 @@ import mage.abilities.costs.Costs; import mage.abilities.costs.OptionalAdditionalCost; import mage.abilities.costs.OptionalAdditionalCostImpl; import mage.abilities.costs.OptionalAdditionalSourceCosts; +import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.costs.mana.VariableManaCost; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -88,6 +89,7 @@ public class KickerAbility extends StaticAbility implements Optio protected String keywordText; protected String reminderText; protected List kickerCosts = new LinkedList(); + private int xManaValue = 0; public KickerAbility(String manaString) { this(KICKER_KEYWORD, KICKER_REMINDER_MANA); @@ -112,6 +114,8 @@ public class KickerAbility extends StaticAbility implements Optio this.kickerCosts = ability.kickerCosts; this.keywordText = ability.keywordText; this.reminderText = ability.reminderText; + this.xManaValue = ability.xManaValue; + } @Override @@ -137,6 +141,10 @@ public class KickerAbility extends StaticAbility implements Optio } } + public int getXManaValue() { + return xManaValue; + } + public int getKickedCounter() { int counter = 0; for (OptionalAdditionalCost cost: kickerCosts) { @@ -178,7 +186,16 @@ public class KickerAbility extends StaticAbility implements Optio for (Iterator it = ((Costs) kickerCost).iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); if (cost instanceof ManaCostsImpl) { - ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy()); + List varCosts = ((ManaCostsImpl)cost).getVariableCosts(); + if (!varCosts.isEmpty()) { + // use only first variable cost + xManaValue = game.getPlayer(this.controllerId).announceXMana(varCosts.get(0).getMinX(), Integer.MAX_VALUE, "Announce kicker value for " + varCosts.get(0).getText(), game, this); + // kicker variable X costs handled internally as multikicker with {1} cost (no multikicker on card) + game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announced a value of ").append(xManaValue).append(" for ").append(" kicker X ").toString()); + ability.getManaCostsToPay().add(new GenericManaCost(xManaValue)); + } else { + ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy()); + } } else { ability.getCosts().add(cost.copy()); } diff --git a/Mage/src/mage/abilities/keyword/ProwlAbility.java b/Mage/src/mage/abilities/keyword/ProwlAbility.java new file mode 100644 index 00000000000..4ca59aa9f30 --- /dev/null +++ b/Mage/src/mage/abilities/keyword/ProwlAbility.java @@ -0,0 +1,199 @@ +/* +* 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.keyword; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.StaticAbility; +import mage.abilities.costs.AlternativeCost2; +import mage.abilities.costs.AlternativeCost2Impl; +import mage.abilities.costs.AlternativeSourceCosts; +import mage.abilities.costs.Cost; +import mage.abilities.costs.Costs; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.watchers.common.ProwlWatcher; + +/** + * 702.74. Prowl # + * + * 702.74a Prowl is a static ability that functions on the stack. "Prowl [cost]" means + * "You may pay [cost] rather than pay this spell's mana cost if a player was dealt combat + * damage this turn by a source that, at the time it dealt that damage, was under your + * control and had any of this spell's creature types." Paying a spell's prowl cost follows + * the rules for paying alternative costs in rules 601.2b and 601.2e-g + * + * @author LevelX2 + */ + +public class ProwlAbility extends StaticAbility implements AlternativeSourceCosts { + + private static final String PROWL_KEYWORD = "Prowl"; + private List prowlCosts = new LinkedList(); + private String reminderText; + + public ProwlAbility(Card card, String manaString) { + super(Zone.STACK, null); + setRuleAtTheTop(true); + name = PROWL_KEYWORD; + setReminderText(card); + this.addProwlCost(manaString); + card.addWatcher(new ProwlWatcher()); + + } + + public ProwlAbility(final ProwlAbility ability) { + super(ability); + this.prowlCosts.addAll(ability.prowlCosts); + this.reminderText = ability.reminderText; + } + + @Override + public ProwlAbility copy() { + return new ProwlAbility(this); + } + + public final AlternativeCost2 addProwlCost(String manaString) { + AlternativeCost2 prowlCost = new AlternativeCost2Impl(PROWL_KEYWORD, reminderText, new ManaCostsImpl(manaString)); + prowlCosts.add(prowlCost); + return prowlCost; + } + + public void resetProwl() { + for (AlternativeCost2 cost: prowlCosts) { + cost.reset(); + } + } + @Override + public boolean isActivated() { + for (AlternativeCost2 cost: prowlCosts) { + if(cost.isActivated()) { + return true; + } + } + return false; + } + + @Override + public boolean askToActivateAlternativeCosts(Ability ability, Game game) { + if (ability instanceof SpellAbility) { + Player player = game.getPlayer(controllerId); + ProwlWatcher prowlWatcher = (ProwlWatcher) game.getState().getWatchers().get("Prowl"); + Card card = game.getCard(ability.getSourceId()); + if (player == null || prowlWatcher == null || card == null) { + throw new IllegalArgumentException("Params can't be null"); + } + boolean canProwl = false; + if (prowlWatcher.getDamagingSubtypes(ability.getControllerId()) != null) { + for (String subtype : prowlWatcher.getDamagingSubtypes(ability.getControllerId())) { + if (card.getSubtype().contains(subtype)) { + canProwl = true; + break; + } + } + } + if (canProwl) { + this.resetProwl(); + for (AlternativeCost2 prowlCost: prowlCosts) { + if (prowlCost.canPay(sourceId, controllerId, game) && + player.chooseUse(Outcome.Benefit, new StringBuilder("Cast for ").append(PROWL_KEYWORD).append(" cost ").append(prowlCost.getText(true)).append(" ?").toString(), game)) { + prowlCost.activate(); + ability.getManaCostsToPay().clear(); + ability.getCosts().clear(); + for (Iterator it = ((Costs) prowlCost).iterator(); it.hasNext();) { + Cost cost = (Cost) it.next(); + if (cost instanceof ManaCostsImpl) { + ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy()); + } else { + ability.getCosts().add(cost.copy()); + } + } + } + } + } + } + return isActivated(); + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder(); + int numberCosts = 0; + String remarkText = ""; + for (AlternativeCost2 prowlCost: prowlCosts) { + if (numberCosts == 0) { + sb.append(prowlCost.getText(false)); + remarkText = prowlCost.getReminderText(); + } else { + sb.append(" and/or ").append(prowlCost.getText(true)); + } + ++numberCosts; + } + if (numberCosts == 1) { + sb.append(" ").append(remarkText); + } + + return sb.toString(); + } + + @Override + public String getCastMessageSuffix() { + StringBuilder sb = new StringBuilder(); + int position = 0; + for (AlternativeCost2 cost : prowlCosts) { + if (cost.isActivated()) { + sb.append(cost.getCastSuffixMessage(position)); + ++position; + } + } + return sb.toString(); + } + + private void setReminderText(Card card) { + StringBuilder sb = new StringBuilder("(You may cast this for its prowl cost if you dealt combat damage to a player this turn with a "); + int i = 0; + for (String subtype: card.getSubtype()) { + i++; + sb.append(subtype); + if (card.getSupertype().size() > 1 && i < card.getSupertype().size()) { + sb.append(" or "); + } + } + //private static final String REMINDER_TEXT = "{subtypes}.)"; + + reminderText = sb.toString(); + } +} diff --git a/Mage/src/mage/abilities/keyword/SpliceOntoArcaneAbility.java b/Mage/src/mage/abilities/keyword/SpliceOntoArcaneAbility.java new file mode 100644 index 00000000000..299aaf3cc7f --- /dev/null +++ b/Mage/src/mage/abilities/keyword/SpliceOntoArcaneAbility.java @@ -0,0 +1,208 @@ +/* + * 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.keyword; + +import java.util.Iterator; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.Costs; +import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.SpliceCardEffectImpl; +import mage.cards.Card; +import mage.cards.CardsImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SpellAbilityType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; + + +/** + * 702.45. Splice + * + * 702.45a Splice is a static ability that functions while a card is in your hand. + * "Splice onto [subtype] [cost]" means "You may reveal this card from your hand + * as you cast a [subtype] spell. If you do, copy this card's text box onto that + * spell and pay [cost] as an additional cost to cast that spell." Paying a card's + * splice cost follows the rules for paying additional costs in rules 601.2b and + * 601.2e-g. + * + * Example: Since the card with splice remains in the player's hand, it can later + * be cast normally or spliced onto another spell. It can even be discarded to pay + * a "discard a card" cost of the spell it's spliced onto. + * + * 702.45b You can't choose to use a splice ability if you can't make the required + * choices (targets, etc.) for that card's instructions. You can't splice any one + * card onto the same spell more than once. If you're splicing more than one card + * onto a spell, reveal them all at once and choose the order in which their + * instructions will be followed. The instructions on the main spell have to be + * followed first. + * + * 702.45c The spell has the characteristics of the main spell, plus the text boxes + * of each of the spliced cards. The spell doesn't gain any other characteristics + * (name, mana cost, color, supertypes, card types, subtypes, etc.) of the spliced + * cards. Text copied onto the spell that refers to a card by name refers to the spell + * on the stack, not the card from which the text was copied. + * + * Example: Glacial Ray is a red card with splice onto Arcane that reads, "Glacial + * Ray deals 2 damage to target creature or player." Suppose Glacial Ray is spliced + * onto Reach Through Mists, a blue spell. The spell is still blue, and Reach Through + * Mists deals the damage. This means that the ability can target a creature with + * protection from red and deal 2 damage to that creature. + * + * 702.45d Choose targets for the added text normally (see rule 601.2c). Note that a + * spell with one or more targets will be countered if all of its targets are illegal + * on resolution. + * + * 702.45e The spell loses any splice changes once it leaves the stack (for example, + * when it's countered, it's exiled, or it resolves). + * + * Rulings + * + * You must reveal all of the cards you intend to splice at the same time. Each individual card can only be spliced once onto a spell. + * If you have more than one card with the same name in your hand, you may splice both of them onto the spell. + * A card with a splice ability can't be spliced onto itself because the spell is on the stack (and not in your hand) when you reveal the cards you want to splice onto it. + * The target for a card that's spliced onto a spell may be the same as the target chosen for the original spell or for another spliced-on card. (A recent change to the targeting rules allows this, but most other cards are unaffected by the change.) + * If you splice a targeted card onto an untargeted spell, the entire spell will be countered if the target isn't legal when the spell resolves. + * If you splice an untargeted card onto a targeted spell, the entire spell will be countered if the target isn't legal when the spell resolves. + * A spell is countered on resolution only if *all* of its targets are illegal (or the spell is countered by an effect). + * + * @author LevelX2 + */ + + +public class SpliceOntoArcaneAbility extends SimpleStaticAbility { + + private static final String KEYWORD_TEXT = "Splice onto Arcane"; + private Costs spliceCosts = new CostsImpl(); + private boolean nonManaCosts = false; + + public SpliceOntoArcaneAbility(String manaString) { + super(Zone.HAND, new SpliceOntoArcaneEffect()); + spliceCosts.add(new ManaCostsImpl(manaString)); + } + + public SpliceOntoArcaneAbility(Cost cost) { + super(Zone.HAND, new SpliceOntoArcaneEffect()); + spliceCosts.add(cost); + nonManaCosts = true; + } + + public SpliceOntoArcaneAbility(final SpliceOntoArcaneAbility ability) { + super(ability); + this.spliceCosts = ability.spliceCosts.copy(); + this.nonManaCosts = ability.nonManaCosts; + } + + @Override + public SimpleStaticAbility copy() { + return new SpliceOntoArcaneAbility(this); + } + + public Costs getSpliceCosts() { + return spliceCosts; + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder(); + sb.append(KEYWORD_TEXT).append(nonManaCosts?"-":" "); + sb.append(spliceCosts.getText()).append(nonManaCosts?". ":" "); + sb.append("(As you cast an Arcane spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)"); + return sb.toString(); + } +} + + +class SpliceOntoArcaneEffect extends SpliceCardEffectImpl { + + public SpliceOntoArcaneEffect() { + super(Duration.WhileOnBattlefield, Outcome.Copy); + staticText = "Splice onto Arcane"; + } + + public SpliceOntoArcaneEffect(final SpliceOntoArcaneEffect effect) { + super(effect); + } + + + + @Override + public SpliceOntoArcaneEffect copy() { + return new SpliceOntoArcaneEffect(this); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + Player controller = game.getPlayer(source.getControllerId()); + Card spliceCard = game.getCard(source.getSourceId()); + if (spliceCard != null && controller != null) { + Spell spell = game.getStack().getSpell(abilityToModify.getId()); + if (spell != null) { + SpellAbility splicedAbility = spliceCard.getSpellAbility().copy(); + splicedAbility.setSpellAbilityType(SpellAbilityType.SPLICE); + splicedAbility.setSourceId(abilityToModify.getSourceId()); + spell.addSpellAbility(splicedAbility); + for (Iterator it = ((SpliceOntoArcaneAbility) source).getSpliceCosts().iterator(); it.hasNext();) { + Cost cost = (Cost) it.next(); + if (cost instanceof ManaCostsImpl) { + spell.getSpellAbility().getManaCostsToPay().add((ManaCostsImpl) cost.copy()); + } else { + spell.getSpellAbility().getCosts().add(cost.copy()); + } + } + } + return true; + } + return false; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + MageObject object = game.getObject(abilityToModify.getSourceId()); + if (object != null && object.getSubtype().contains("Arcane")) { + return spliceSpellCanBeActivated(source, game); + } + return false; + } + + private boolean spliceSpellCanBeActivated(Ability source, Game game) { + // check if spell can be activated (protection problem not solved because effect will be used from the base spell?) + Card card = game.getCard(source.getSourceId()); + if (card != null) { + return card.getSpellAbility().canActivate(source.getControllerId(), game); + } + return false; + } +} diff --git a/Mage/src/mage/abilities/keyword/SuspendAbility.java b/Mage/src/mage/abilities/keyword/SuspendAbility.java index 1242a128d7f..567b84df65e 100644 --- a/Mage/src/mage/abilities/keyword/SuspendAbility.java +++ b/Mage/src/mage/abilities/keyword/SuspendAbility.java @@ -28,6 +28,8 @@ package mage.abilities.keyword; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import mage.constants.AsThoughEffectType; import mage.constants.CardType; @@ -176,13 +178,7 @@ public class SuspendAbility extends ActivatedAbilityImpl { if (card.getManaCost().isEmpty()) { setRuleAtTheTop(true); } - // add triggered ability to remove the counter from the card - Ability ability = new ConditionalTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), TargetController.YOU, false), - SuspendedCondition.getInstance(), - "At the beginning of your upkeep, if this card is suspended, remove a time counter from it."); - ability.setRuleVisible(false); - card.addAbility(ability); + card.addAbility(new SuspendBeginningOfUpkeepTriggeredAbility()); card.addAbility(new SuspendPlayCardAbility(card.getCardType().contains(CardType.CREATURE))); } @@ -326,16 +322,26 @@ class SuspendPlayCardEffect extends OneShotEffect { Card card = game.getCard(source.getSourceId()); if (player != null && card != null) { // remove temporary suspend ability (used e.g. for Epochrasite) - Ability abilityToRemove = null; + List abilitiesToRemove = new ArrayList(); for (Ability ability : card.getAbilities()) { if (ability instanceof SuspendAbility) { if (((SuspendAbility)ability).isGainedTemporary()) { - abilityToRemove = ability; + abilitiesToRemove.add(ability); } } } - if (abilityToRemove != null) { - card.getAbilities().remove(abilityToRemove); + if (!abilitiesToRemove.isEmpty()) { + for (Ability ability : card.getAbilities()) { + if (ability instanceof SuspendBeginningOfUpkeepTriggeredAbility || ability instanceof SuspendPlayCardAbility ) { + abilitiesToRemove.add(ability); + } + } + // remove the triggered abilities from the game + game.getState().resetTriggersForSourceId(card.getId()); + // remove the continious effects from the game + game.getState().getContinuousEffects().removeGainedEffectsForSource(card.getId()); + // remove the abilities from the card + card.getAbilities().removeAll(abilitiesToRemove); } // cast the card for free player.cast(card.getSpellAbility(), game, true); @@ -381,3 +387,23 @@ class GainHasteEffect extends ContinuousEffectImpl { } } + +class SuspendBeginningOfUpkeepTriggeredAbility extends ConditionalTriggeredAbility { + + public SuspendBeginningOfUpkeepTriggeredAbility() { + super(new BeginningOfUpkeepTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), TargetController.YOU, false), + SuspendedCondition.getInstance(), + "At the beginning of your upkeep, if this card is suspended, remove a time counter from it."); + this.setRuleVisible(false); + + } + + public SuspendBeginningOfUpkeepTriggeredAbility(final SuspendBeginningOfUpkeepTriggeredAbility effect) { + super(effect); + } + + @Override + public SuspendBeginningOfUpkeepTriggeredAbility copy() { + return new SuspendBeginningOfUpkeepTriggeredAbility(this); + } +} \ No newline at end of file diff --git a/Mage/src/mage/cards/decks/importer/DeckImporter.java b/Mage/src/mage/cards/decks/importer/DeckImporter.java index 6af78ca0cf2..0f50787b9a5 100644 --- a/Mage/src/mage/cards/decks/importer/DeckImporter.java +++ b/Mage/src/mage/cards/decks/importer/DeckImporter.java @@ -46,6 +46,10 @@ public abstract class DeckImporter { public DeckCardLists importDeck(String file) { File f = new File(file); DeckCardLists deckList = new DeckCardLists(); + if (!f.exists()) { + logger.warn("Deckfile " + file + " not found."); + return deckList; + } lineCount = 0; sbMessage.setLength(0); try { diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java index feb74c07090..3d979c90ef1 100644 --- a/Mage/src/mage/cards/repository/CardRepository.java +++ b/Mage/src/mage/cards/repository/CardRepository.java @@ -54,7 +54,7 @@ public enum CardRepository { instance; private static final String JDBC_URL = "jdbc:sqlite:db/cards.db"; - private static final long DB_VERSION = 7; + private static final long DB_VERSION = 8; private Random random = new Random(); private Dao cardDao; diff --git a/Mage/src/mage/constants/EffectType.java b/Mage/src/mage/constants/EffectType.java index b83b5f3891c..aa483ea23c4 100644 --- a/Mage/src/mage/constants/EffectType.java +++ b/Mage/src/mage/constants/EffectType.java @@ -14,7 +14,8 @@ public enum EffectType { ASTHOUGH("As Though Effect"), RESTRICTION("Restriction Effect"), REQUIREMENT("Requirement Effect"), - COSTMODIFICATION("Cost Modification Effect"); + COSTMODIFICATION("Cost Modification Effect"), + SPLICE("Splice Card Effect"); private String text; diff --git a/Mage/src/mage/filter/common/FilterControlledCreaturePermanent.java b/Mage/src/mage/filter/common/FilterControlledCreaturePermanent.java index 4d69b6393db..5831922c2f3 100644 --- a/Mage/src/mage/filter/common/FilterControlledCreaturePermanent.java +++ b/Mage/src/mage/filter/common/FilterControlledCreaturePermanent.java @@ -30,6 +30,7 @@ package mage.filter.common; import mage.constants.CardType; import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; /** * @@ -44,6 +45,13 @@ public class FilterControlledCreaturePermanent extends FilterControlledPermanent public FilterControlledCreaturePermanent(String name) { super(name); this.add(new CardTypePredicate(CardType.CREATURE)); + } + + + public FilterControlledCreaturePermanent(String subtype, String name) { + super(name); + this.add(new CardTypePredicate(CardType.CREATURE)); + this.add(new SubtypePredicate(subtype)); } public FilterControlledCreaturePermanent(final FilterControlledCreaturePermanent filter) { diff --git a/Mage/src/mage/filter/common/FilterCreaturePermanent.java b/Mage/src/mage/filter/common/FilterCreaturePermanent.java index b23a54be977..290176f307d 100644 --- a/Mage/src/mage/filter/common/FilterCreaturePermanent.java +++ b/Mage/src/mage/filter/common/FilterCreaturePermanent.java @@ -31,6 +31,7 @@ package mage.filter.common; import mage.constants.CardType; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; /** * @@ -45,6 +46,12 @@ public class FilterCreaturePermanent extends FilterPermanent { public FilterCreaturePermanent(String name) { super(name); this.add(new CardTypePredicate(CardType.CREATURE)); + } + + public FilterCreaturePermanent(String subtype, String name) { + super(name); + this.add(new CardTypePredicate(CardType.CREATURE)); + this.add(new SubtypePredicate(subtype)); } public FilterCreaturePermanent(final FilterCreaturePermanent filter) { diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 2517430a297..e73cd74e881 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1065,7 +1065,9 @@ public abstract class GameImpl> implements Game, Serializa public void addTriggeredAbility(TriggeredAbility ability) { if (ability instanceof TriggeredManaAbility || ability instanceof DelayedTriggeredManaAbility) { // 20110715 - 605.4 - ability.resolve(this); + Ability manaAbiltiy = ability.copy(); + manaAbiltiy.activate(this, false); + manaAbiltiy.resolve(this); } else { TriggeredAbility newAbility = (TriggeredAbility) ability.copy(); diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 6e940915198..fab094b1409 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -118,9 +118,21 @@ public class Spell> implements StackObject, Card { public boolean activate(Game game, boolean noMana) { + if (!spellAbilities.get(0).activate(game, noMana)) { + return false; + } + // if there are more abilities (fused split spell) or first ability added new abilities (splice), activate the additional abilities + boolean ignoreAbility = true; + boolean payNoMana = noMana; for (SpellAbility spellAbility: spellAbilities) { - if (!spellAbility.activate(game, noMana)) { - return false; + // costs for spliced abilities were added to main spellAbility, so pay no man for spliced abilities + payNoMana |= spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE); + if (ignoreAbility) { + ignoreAbility = false; + } else { + if (!spellAbility.activate(game, payNoMana)) { + return false; + } } } return true; @@ -142,7 +154,9 @@ public class Spell> implements StackObject, Card { spellAbility.getModes().setMode(spellAbility.getModes().get(modeId)); if (spellAbility.getTargets().stillLegal(spellAbility, game)) { legalParts = true; - updateOptionalCosts(index); + if (!spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE)) { + updateOptionalCosts(index); + } result |= spellAbility.resolve(game); } } @@ -351,6 +365,10 @@ public class Spell> implements StackObject, Card { return card.getOwnerId(); } + public void addSpellAbility(SpellAbility spellAbility) { + spellAbilities.add(spellAbility); + } + @Override public void addAbility(Ability ability) {} diff --git a/Mage/src/mage/watchers/common/ProwlWatcher.java b/Mage/src/mage/watchers/common/ProwlWatcher.java new file mode 100644 index 00000000000..0f8fa533e23 --- /dev/null +++ b/Mage/src/mage/watchers/common/ProwlWatcher.java @@ -0,0 +1,97 @@ +/* + * 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.watchers.common; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.watchers.WatcherImpl; + +/** + * Watcher stores with which creature subtypes a player made combat damage to + * other players during a turn. + * + * @author LevelX + */ +public class ProwlWatcher extends WatcherImpl { + + private Map> damagingSubtypes = new HashMap>(); + + public ProwlWatcher() { + super("Prowl", WatcherScope.GAME); + } + + public ProwlWatcher(final ProwlWatcher watcher) { + super(watcher); + for (Entry> entry : watcher.damagingSubtypes.entrySet()) { + damagingSubtypes.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public ProwlWatcher copy() { + return new ProwlWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == EventType.DAMAGED_PLAYER) { + DamagedPlayerEvent dEvent = (DamagedPlayerEvent) event; + if (dEvent.isCombatDamage()) { + Permanent creature = game.getPermanent(dEvent.getSourceId()); + if (creature != null) { + Set subtypes = damagingSubtypes.get(creature.getControllerId()); + if (subtypes == null) { + subtypes = new LinkedHashSet(); + } + subtypes.addAll(creature.getSubtype()); + damagingSubtypes.put(creature.getControllerId(), subtypes); + } + } + } + } + + @Override + public void reset() { + super.reset(); + damagingSubtypes.clear(); + } + + public Set getDamagingSubtypes(UUID playerId) { + return damagingSubtypes.get(playerId); + } +} diff --git a/Utils/known-sets.txt b/Utils/known-sets.txt index 64660b8762f..dbd8ed79250 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -13,6 +13,7 @@ Magic 2010|magic2010| Magic 2011|magic2011| Magic 2012|magic2012| Magic 2013|magic2013| +Magic 2014|magic2014| Planechase|planechase| Planechase 2012 Edition|planechase2012| Duel Decks: Elspeth vs. Tezzeret|elspethvstezzeret| diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index 918e837264a..dabe32f3866 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -59,6 +59,7 @@ Magic 2010|M10| Magic 2011|M11| Magic 2012|M12| Magic 2013|M13| +Magic 2014|M14| Magic: The Gathering-Commander|CMD| Masters Edition II|ME2| Masters Edition III|ME3|