From 4232520a701ebcedfa2034f03bda0699b8e99828 Mon Sep 17 00:00:00 2001 From: myersn024 Date: Mon, 9 Mar 2015 09:07:29 -0500 Subject: [PATCH 01/12] Implemented ManaSeverance.java --- .../src/mage/sets/tempest/ManaSeverance.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/tempest/ManaSeverance.java diff --git a/Mage.Sets/src/mage/sets/tempest/ManaSeverance.java b/Mage.Sets/src/mage/sets/tempest/ManaSeverance.java new file mode 100644 index 00000000000..57bc71c2550 --- /dev/null +++ b/Mage.Sets/src/mage/sets/tempest/ManaSeverance.java @@ -0,0 +1,85 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.sets.tempest; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.SearchEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterLandCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; + +/** + * + * @author nick.myers + */ +public class ManaSeverance extends CardImpl { + + public ManaSeverance(UUID ownerId) { + super(ownerId, 73, "Mana Severance", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{1}{U}"); + this.expansionSetCode = "TMP"; + + // Search your library for any number of land cards and remove the from the game. + // Shuffle your library afterwards. + this.getSpellAbility().addEffect(new ManaSeveranceEffect()); + } + + public ManaSeverance(final ManaSeverance card) { + super(card); + } + + @Override + public ManaSeverance copy() { + return new ManaSeverance(this); + } + +} + +class ManaSeveranceEffect extends SearchEffect { + + public ManaSeveranceEffect() { + super(new TargetCardInLibrary(0, Integer.MAX_VALUE, new FilterLandCard()), Outcome.Exile); + this.staticText = "Search your library for any number of land cards and remove them from the game. Shuffle your library afterwards."; + } + + public ManaSeveranceEffect(final ManaSeveranceEffect effect) { + super(effect); + } + + @Override + public ManaSeveranceEffect copy() { + return new ManaSeveranceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player you = game.getPlayer(source.getControllerId()); + if (you != null) { + if (you.searchLibrary(target, game)) { + UUID exileZone = CardUtil.getCardExileZoneId(game, source); + if (target.getTargets().size() > 0) { + for (UUID cardId : target.getTargets()) { + Card card = you.getLibrary().getCard(cardId, game); + if (card != null) { + card.moveToExile(exileZone, "Mana Severance", source.getSourceId(), game); + } + } + } + } + you.shuffleLibrary(game); + return true; + + } + return false; + } +} From a6f0cd02af1fd469c064c8acf12a678d29e71c05 Mon Sep 17 00:00:00 2001 From: nickmyers Date: Mon, 9 Mar 2015 18:17:11 -0500 Subject: [PATCH 02/12] Made changes to ManaSeverance.java based on suggestions --- .../src/mage/sets/tempest/ManaSeverance.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Mage.Sets/src/mage/sets/tempest/ManaSeverance.java b/Mage.Sets/src/mage/sets/tempest/ManaSeverance.java index 57bc71c2550..8b48c5bf77c 100644 --- a/Mage.Sets/src/mage/sets/tempest/ManaSeverance.java +++ b/Mage.Sets/src/mage/sets/tempest/ManaSeverance.java @@ -13,11 +13,11 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterLandCard; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; -import mage.util.CardUtil; /** * @@ -29,7 +29,7 @@ public class ManaSeverance extends CardImpl { super(ownerId, 73, "Mana Severance", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{1}{U}"); this.expansionSetCode = "TMP"; - // Search your library for any number of land cards and remove the from the game. + // Search your library for any number of land cards and remove them from the game. // Shuffle your library afterwards. this.getSpellAbility().addEffect(new ManaSeveranceEffect()); } @@ -63,20 +63,19 @@ class ManaSeveranceEffect extends SearchEffect { @Override public boolean apply(Game game, Ability source) { - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - if (you.searchLibrary(target, game)) { - UUID exileZone = CardUtil.getCardExileZoneId(game, source); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { for (UUID cardId : target.getTargets()) { - Card card = you.getLibrary().getCard(cardId, game); + Card card = controller.getLibrary().getCard(cardId, game); if (card != null) { - card.moveToExile(exileZone, "Mana Severance", source.getSourceId(), game); + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY); } } } } - you.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } From 9b7db771d18ed9e892419792069345487e881457 Mon Sep 17 00:00:00 2001 From: fireshoes Date: Mon, 9 Mar 2015 22:13:24 -0500 Subject: [PATCH 03/12] [DTK] Updated mtg-cards-data.txt; added Harbinger of the Hunt, Shieldhide Dragon, Crater Elemental, Dragon Whisperer, Encase in Ice, Surge of Righteousness --- .../sets/dragonsoftarkir/CraterElemental.java | 89 +++++ .../sets/dragonsoftarkir/DragonWhisperer.java | 91 ++++++ .../sets/dragonsoftarkir/EncaseInIce.java | 93 ++++++ .../dragonsoftarkir/HarbingerOfTheHunt.java | 86 +++++ .../dragonsoftarkir/ShieldhideDragon.java | 87 +++++ .../dragonsoftarkir/SurgeOfRighteousness.java | 75 +++++ .../sets/modernmasters/WarrenWeirding.java | 309 +++++++++--------- Utils/mtg-cards-data.txt | 14 +- 8 files changed, 682 insertions(+), 162 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/CraterElemental.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/DragonWhisperer.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/EncaseInIce.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/HarbingerOfTheHunt.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/ShieldhideDragon.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/SurgeOfRighteousness.java diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/CraterElemental.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/CraterElemental.java new file mode 100644 index 00000000000..b24004f3261 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/CraterElemental.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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.FormidableCondition; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.SetPowerSourceEffect; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class CraterElemental extends CardImpl { + + public CraterElemental(UUID ownerId) { + super(ownerId, 132, "Crater Elemental", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Elemental"); + this.power = new MageInt(0); + this.toughness = new MageInt(6); + + // {R}, {T}, Sacrifice Crater Elemental: Crater Elemental deals 4 damage to target creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(4), new ManaCostsImpl("{R}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // Formidable - {2}{R}: Crater Elemental has base power 8 until end of turn. Activate this ability only if creatures you control have total power 8 or greater. + ability = new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, + new SetPowerSourceEffect(new StaticValue(8), Duration.EndOfTurn), + new ManaCostsImpl("{4}{R}{R}"), + FormidableCondition.getInstance()); + ability.setAbilityWord(AbilityWord.FORMIDABLE); + this.addAbility(ability); + } + + public CraterElemental(final CraterElemental card) { + super(card); + } + + @Override + public CraterElemental copy() { + return new CraterElemental(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonWhisperer.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonWhisperer.java new file mode 100644 index 00000000000..4cd37d83425 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonWhisperer.java @@ -0,0 +1,91 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.FormidableCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.permanent.token.DragonToken; + +/** + * + * @author fireshoes + */ +public class DragonWhisperer extends CardImpl { + + public DragonWhisperer(UUID ownerId) { + super(ownerId, 137, "Dragon Whisperer", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{R}{R}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {R}: Dragon Whisperer gains flying until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new GainAbilitySourceEffect(FlyingAbility.getInstance(), + Duration.EndOfTurn), new ManaCostsImpl("{R}"))); + + // {1}{R}: Dragon Whisperer get +1/+0 until end of turn + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new BoostSourceEffect(1, 0, Duration.EndOfTurn), + new ManaCostsImpl("{R}"))); + + // - {4}{R}{R}: Put a 4/4 red Dragon creature token with flying onto the battlefield. Activate this ability only if creatures you control have total power 8 or greater. + Ability ability = new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, + new CreateTokenEffect(new DragonToken()), + new ManaCostsImpl("{4}{R}{R}"), + FormidableCondition.getInstance()); + ability.setAbilityWord(AbilityWord.FORMIDABLE); + this.addAbility(ability); + } + + public DragonWhisperer(final DragonWhisperer card) { + super(card); + } + + @Override + public DragonWhisperer copy() { + return new DragonWhisperer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/EncaseInIce.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/EncaseInIce.java new file mode 100644 index 00000000000..3b6b664fcea --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/EncaseInIce.java @@ -0,0 +1,93 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; +import mage.abilities.effects.common.TapEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class EncaseInIce extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red or green creature"); + + static { + filter.add(Predicates.or( + new ColorPredicate(ObjectColor.RED), + new ColorPredicate(ObjectColor.GREEN))); + } + + public EncaseInIce(UUID ownerId) { + super(ownerId, 54, "Encase in Ice", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Aura"); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Enchant red or green creature + TargetPermanent auraTarget = new TargetCreaturePermanent(filter); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.addAbility(new EnchantAbility(auraTarget.getTargetName())); + + // When Encase in Ice enters the battlefield, tap enchanted creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect())); + + // Enchanted creature doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect())); + } + + public EncaseInIce(final EncaseInIce card) { + super(card); + } + + @Override + public EncaseInIce copy() { + return new EncaseInIce(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/HarbingerOfTheHunt.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/HarbingerOfTheHunt.java new file mode 100644 index 00000000000..467e44f3148 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/HarbingerOfTheHunt.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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author fireshoes + */ +public class HarbingerOfTheHunt extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature without flying"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("other creature with flying"); + + static { + filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + filter2.add(new AbilityPredicate(FlyingAbility.class)); + filter2.add(new AnotherPredicate()); + } + + public HarbingerOfTheHunt(UUID ownerId) { + super(ownerId, 223, "Harbinger of the Hunt", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {2}{R}: Harbinger of the Hunt deals 1 damage to each creature without flying. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageAllEffect(1, filter), new ManaCostsImpl("{2}{R}"))); + + // {2}{G}: Harbinger of the Hunt deals 1 damage to each other creature with flying. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageAllEffect(1, filter2), new ManaCostsImpl("{2}{G}"))); + } + + public HarbingerOfTheHunt(final HarbingerOfTheHunt card) { + super(card); + } + + @Override + public HarbingerOfTheHunt copy() { + return new HarbingerOfTheHunt(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ShieldhideDragon.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ShieldhideDragon.java new file mode 100644 index 00000000000..a9ecaa1c0e1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ShieldhideDragon.java @@ -0,0 +1,87 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author fireshoes + */ +public class ShieldhideDragon extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + static { + filter.add(new AnotherPredicate()); + filter.add(new SubtypePredicate("Dragon")); + } + + public ShieldhideDragon(UUID ownerId) { + super(ownerId, 37, "Shieldhide Dragon", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{5}{W}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // Megamorph {5}{W}{W} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{W}{W}"), true)); + + // When Shieldhide Dragon is turned face up, put a +1/+1 counter on each other Dragon you control. + this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); + } + + public ShieldhideDragon(final ShieldhideDragon card) { + super(card); + } + + @Override + public ShieldhideDragon copy() { + return new ShieldhideDragon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SurgeOfRighteousness.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SurgeOfRighteousness.java new file mode 100644 index 00000000000..bd1b8fea041 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SurgeOfRighteousness.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.dragonsoftarkir; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterAttackingOrBlockingCreature; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class SurgeOfRighteousness extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterAttackingOrBlockingCreature("black or red creature that's attacking or blocking"); + + static { + filter.add(Predicates.or( + new ColorPredicate(ObjectColor.BLACK), + new ColorPredicate(ObjectColor.RED))); + } + + public SurgeOfRighteousness(UUID ownerId) { + super(ownerId, 42, "Surge of Righteousness", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}"); + this.expansionSetCode = "DTK"; + + // Destroy target black or red creature that's attacking or blocking. You gain 2 life. + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addEffect(new GainLifeEffect(2)); + } + + public SurgeOfRighteousness(final SurgeOfRighteousness card) { + super(card); + } + + @Override + public SurgeOfRighteousness copy() { + return new SurgeOfRighteousness(this); + } +} diff --git a/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java b/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java index d880830e2a5..aadfcfda732 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java +++ b/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java @@ -1,156 +1,153 @@ -/* - * 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.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.HasteAbility; -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.filter.common.FilterControlledPermanent; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.game.permanent.token.Token; -import mage.players.Player; -import mage.target.TargetPlayer; -import mage.target.common.TargetControlledPermanent; -import mage.target.targetpointer.FixedTarget; - -/** - * - * @author LevelX2 - */ -public class WarrenWeirding extends CardImpl { - - public WarrenWeirding(UUID ownerId) { - super(ownerId, 104, "Warren Weirding", Rarity.COMMON, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{1}{B}"); - this.expansionSetCode = "MMA"; - this.subtype.add("Goblin"); - - this.color.setBlack(true); - - // Target player sacrifices a creature. If a Goblin is sacrificed this way, that player puts two 1/1 black Goblin Rogue creature tokens onto the battlefield, and those tokens gain haste until end of turn. - this.getSpellAbility().addEffect(new WarrenWeirdingEffect()); - this.getSpellAbility().addTarget(new TargetPlayer()); - } - - public WarrenWeirding(final WarrenWeirding card) { - super(card); - } - - @Override - public WarrenWeirding copy() { - return new WarrenWeirding(this); - } -} - -class WarrenWeirdingEffect extends OneShotEffect { - - private static final FilterCreaturePermanent filterGoblin = new FilterCreaturePermanent(); - static { - filterGoblin.add(new SubtypePredicate("Goblin")); - } - WarrenWeirdingEffect ( ) { - super(Outcome.Sacrifice); - staticText = "Target player sacrifices a creature. If a Goblin is sacrificed this way, that player puts two 1/1 black Goblin Rogue creature tokens onto the battlefield, and those tokens gain haste until end of turn"; - } - - WarrenWeirdingEffect ( WarrenWeirdingEffect effect ) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); - - FilterControlledPermanent filter = new FilterControlledPermanent("creature"); - filter.add(new CardTypePredicate(CardType.CREATURE)); - filter.add(new ControllerIdPredicate(player.getId())); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); - - //A spell or ability could have removed the only legal target this player - //had, if thats the case this ability should fizzle. - if (target.canChoose(player.getId(), game)) { - player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - if (filterGoblin.match(permanent, game)) { - for (int i = 0; i < 2; i++) { - Token token = new WarrenWeirdingBlackGoblinRogueToken(); - Effect effect = new CreateTokenTargetEffect(token); - effect.setTargetPointer(new FixedTarget(player.getId())); - if (effect.apply(game, source)) { - Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken()); - if (tokenPermanent != null) { - ContinuousEffect hasteEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); - hasteEffect.setTargetPointer(new FixedTarget(tokenPermanent.getId())); - game.addEffect(hasteEffect, source); - } - } - } - } - } - return true; - } - return false; - } - - @Override - public WarrenWeirdingEffect copy() { - return new WarrenWeirdingEffect(this); - } - -} - -class WarrenWeirdingBlackGoblinRogueToken extends Token { - WarrenWeirdingBlackGoblinRogueToken() { - super("Goblin Rogue", "1/1 black Goblin Rogue creature tokens, and those tokens gain haste until end of turn"); - cardType.add(CardType.CREATURE); - color.setBlack(true); - subtype.add("Goblin"); - subtype.add("Rogue"); - power.setValue(1); - toughness.setValue(1); - } -} +/* + * 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.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.Token; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetControlledPermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class WarrenWeirding extends CardImpl { + + public WarrenWeirding(UUID ownerId) { + super(ownerId, 104, "Warren Weirding", Rarity.COMMON, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{1}{B}"); + this.expansionSetCode = "MMA"; + this.subtype.add("Goblin"); + + this.color.setBlack(true); + + // Target player sacrifices a creature. If a Goblin is sacrificed this way, that player puts two 1/1 black Goblin Rogue creature tokens onto the battlefield, and those tokens gain haste until end of turn. + this.getSpellAbility().addEffect(new WarrenWeirdingEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public WarrenWeirding(final WarrenWeirding card) { + super(card); + } + + @Override + public WarrenWeirding copy() { + return new WarrenWeirding(this); + } +} + +class WarrenWeirdingEffect extends OneShotEffect { + + private static final FilterCreaturePermanent filterGoblin = new FilterCreaturePermanent(); + static { + filterGoblin.add(new SubtypePredicate("Goblin")); + } + WarrenWeirdingEffect ( ) { + super(Outcome.Sacrifice); + staticText = "Target player sacrifices a creature. If a Goblin is sacrificed this way, that player puts two 1/1 black Goblin Rogue creature tokens onto the battlefield, and those tokens gain haste until end of turn"; + } + + WarrenWeirdingEffect ( WarrenWeirdingEffect effect ) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + + FilterControlledPermanent filter = new FilterControlledPermanent("creature"); + filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(new ControllerIdPredicate(player.getId())); + TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); + + //A spell or ability could have removed the only legal target this player + //had, if thats the case this ability should fizzle. + if (target.canChoose(player.getId(), game)) { + player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.sacrifice(source.getSourceId(), game); + if (filterGoblin.match(permanent, game)) { + for (int i = 0; i < 2; i++) { + Token token = new WarrenWeirdingBlackGoblinRogueToken(); + Effect effect = new CreateTokenTargetEffect(token); + effect.setTargetPointer(new FixedTarget(player.getId())); + if (effect.apply(game, source)) { + Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken()); + if (tokenPermanent != null) { + ContinuousEffect hasteEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); + hasteEffect.setTargetPointer(new FixedTarget(tokenPermanent.getId())); + game.addEffect(hasteEffect, source); + } + } + } + } + } + return true; + } + return false; + } + + @Override + public WarrenWeirdingEffect copy() { + return new WarrenWeirdingEffect(this); + } + +} + +class WarrenWeirdingBlackGoblinRogueToken extends Token { + WarrenWeirdingBlackGoblinRogueToken() { + super("Goblin Rogue", "1/1 black Goblin Rogue creature tokens, and those tokens gain haste until end of turn"); + cardType.add(CardType.CREATURE); + color.setBlack(true); + subtype.add("Goblin"); + subtype.add("Rogue"); + power.setValue(1); + toughness.setValue(1); + } +} diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 9bbde31946d..c8ce7577d1f 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25675,11 +25675,12 @@ Ojutai Exemplars|Dragons of Tarkir|27|M|{2}{W}{W}|Creature - Human Monk|4|4|When Profound Journey|Dragons of Tarkir|30|R|{5}{W}{W}|Sorcery|||Return target permanent card from your graveyard to the battlefield.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| Radiant Purge|Dragons of Tarkir|31|R|{1}{W}|Instant|||Exile target multicolored creature or multicolored enchantment.| Sandcrafter Mage|Dragons of Tarkir|33|C|{2}{W}|Creature - Human Wizard|2|2|When Sandcrafter Mage enters the battlefield, bolster 1 (Choose a creature with the least toughness among the creatures you control and put a +1/+1 counter on it.)| +Shieldhide Dragon|Dragons of Tarkir|37|U|{5}{W}|Creature - Dragon|3|3|Flying, lifelink$Megamorph {5}{W}{W} You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Shieldhide Dragon is turned face up, put a +1/+1 counter on each other Dragon you control.| Sunscorch Regent|Dragons of Tarkir|41|R|{3}{W}{W}|Creature - Dragon|4|3|Flying$Whenever an opponent casts a spell, put a +1/+1 counter on Sunscorch Regent and you gain 1 life.| -Surge of Righteousness|Dragons of Tarkir|42|U|Instant|||Destroy target black or red creature that's attacking or blocking. You gain 2 life.| +Surge of Righteousness|Dragons of Tarkir|42|U|{1}{W}|Instant|||Destroy target black or red creature that's attacking or blocking. You gain 2 life.| Anticipate|Dragons of Tarkir|45|C|{1}{U}|Instant|||Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| Dragonlord's Prerogative|Dragons of Tarkir|52|R|{4}{U}{U}|Instant||As an additional cost to cast Dragonlord's Prerogative, you may reveal a Dragon card from your hand.$If you reveal a Dragon card or controlled a Dragon as you cast Dragonlord's Prerogative, Dragonlord's Prerogative can't be countered.$Draw four cards.| -Encase in Ice|Dragons of Tarkir|54|{1}{U}|Enchantment - Aura|||Flash$Enchant red or green creature$When Encase in Ice enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during its controller's untap step.| +Encase in Ice|Dragons of Tarkir|54|U|{1}{U}|Enchantment - Aura|||Flash$Enchant red or green creature$When Encase in Ice enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during its controller's untap step.| Gudul Lurker|Dragons of Tarkir|56|U|{U}|Creature - Salamander|1|1|Gudul Lurker can't be blocked.$Megamorph {U} (You may cast this card face down as a 2/2 creature for {3}. Turn it up anytime for its megamorph cost and put a +1/+1 counter on it.)| Mirror Mockery|Dragons of Tarkir|62|R|{1}{U}|Enchantment - Aura|||Enchant creature$Whenever enchanted creature attacks, you may put a token onto the battlefield that's a copy of that creature. Exile that token at the end of combat.| Ojutai's Summons|Dragons of Tarkir|68|C|{3}{U}{U}|Sorcery|||Put a 2/2 blue Djinn Monk creature token with flying onto the battlefield.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| @@ -25689,14 +25690,15 @@ Stratus Dancer|Dragons of Tarkir|80|R|{1}{U}|Creature - Djinn Monk|2|1|Flying$Me Acid-Spewer Dragon|Dragons of Tarkir|86|U|{5}{B}|Creature - Dragon|3|3|Flying, deathtouch$Megamorph {5}{B}{B} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Acid-Spewer Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.| Blood-Chin Fanatic|Dragons of Tarkir|88|R|{1}{B}{B}|Creature - Orc Warrior|3|3|{1}{B}, Sacrifice another Warrior creature: Target player loses X life and you gain X life, where X is the sacrificed creature's power.| Deathbringer Regent|Dragons of Tarkir|96|R|{5}{B}{B}|Creature - Dragon|5|6|Flying$When Deathbringer Regent enters the battlefield, if you cast it from your hand and there are five or more other creatures on the battlefield, destroy all other creatures.| +Hedonist's Trove|Dragons of Tarkir|106|R|{5}{B}{B}|Enchantment|||When Hdeonist's Trove enters the battlefield, exile all cards in target opponent's graveyard.$You may play land cards exiled by Hedonist's Trove.$once per turn, you may cast a nonland card exiled by Hedonist's Trove.| Marang River Skeleton|Dragons of Tarkir|108|U|{1}{B}|Creature - Skeleton|1|1|{B}: Regenerate Marang River Skeleton.$Megamorph {3}{B} You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)| Risen Executioner|Dragons of Tarkir|116|M|{2}{B}{B}|Creature - Zombie Warrior|4|3|Risen Executioner can't block.$Other Zombie creatures you control get +1/+1.$You may cast Risen Executioner from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard.| -Self-Inflicted Wound|Dragons of Tarkir|117|{1}{B}|Sorcery|||Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life.| +Self-Inflicted Wound|Dragons of Tarkir|117|U|{1}{B}|Sorcery|||Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life.| Sidisi, Undead Vizier|Dragons of Tarkir|120|R|{3}{B}{B}|Legendary Creature - Zombie Naga|4|6|Deathtouch$Exploit (When this creature enters the battlefield, you may sacrifice a creature.)$When Sidisi, Undead Vizier exploits a creature, you may search your library for a card, put it into your hand, then shuffle your library.| Silumgar Assassin|Dragons of Tarkir|121|R|{1}{B}|Creature - Human Assassin|2|1|Creatures with power greater than Silumgar Assassin's power can't block it.$Megamorph {2}{B} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)$When Silumgar Assassin is turned face up, destroy target creature with power 3 or less an opponent controls.| Silumgar Butcher|Dragons of Tarkir|122|C|{4}{B}|Creature - Zombie Djinn|3|3|Exploit (When this creature enters the battlefield, you may sacrifice a creature.)$When Silumgar Butcher exploits a creature, target creature gets -3/-3 until end of turn.| Ultimate Price|Dragons of Tarkir|124|U|{1}{B}|Instant|||Destroy target monocolored creature.| -Crater Elemental|Dragons of Tarkir|132|R|{{2}{R}|Creature - Elemental|0|6|{R}, {T}, Sacrifice Crater Elemental: Crater Elemental deals 4 damage to target creature.$Formidable - {2}{R}: Crater Elemental has base power 8 until end of turn. Activate this ability only if creatures you control have total power 8 or greater.| +Crater Elemental|Dragons of Tarkir|132|R|{2}{R}|Creature - Elemental|0|6|{R}, {T}, Sacrifice Crater Elemental: Crater Elemental deals 4 damage to target creature.$Formidable - {2}{R}: Crater Elemental has base power 8 until end of turn. Activate this ability only if creatures you control have total power 8 or greater.| Descent of the Dragons|Dragons of Tarkir|133|M|{4}{R}{R}|Sorcery||Destroy any number of target creatures. For each creature destroyed this way, its controller puts a 4/4 red Dragon creature token with flying onto the battlefield.| Draconic Roar|Dragons of Tarkir|154|U|{1}{R}|Instant - As an additional cost to cast Draconic Roar, you may reveal a Dragon card from your hand.$Draconic Roar deals 3 damage to target creature. If you revealed a Dragon card or controlled a Dragon as you cast Draconic Roar, Draconic Roar deals 3 damage to that creature's controller.| Dragon Fodder|Dragons of Tarkir|135|C|{1}{R}|Sorcery|||Put two 1/1 red Goblin creature tokens onto the battlefield.| @@ -25714,7 +25716,7 @@ Aerie Bowmasters|Dragons of Tarkir|170|C|{2}|{G}{G}|Creature - Hound Archer|Reac Collected Company|Dragons of Tarkir|177|R|{3}{G}|Instant|||Look at the top six cards of your library. Put up to two creature cards with converted mana cost 3 or less from among them onto the battlefield. Put the rest on the bottom of your library in any order.| Deathmist Raptor|Dragons of Tarkir|180|M|{1}{G}{G}|Creature - Lizard Beast|3|3|Deathtouch$Whenever a permanent you control is turned face up, you may return Deathmist Raptor from your graveyard to the battlefield face up or face down.$Megamorph {4}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Den Protector|Dragons of Tarkir|181|R|{1}{G}|Creature - Human Warrior|2|1|Creatures with power less than Den Protector's power can't block it.$Megamorph {1}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| -Display of Dominance|Dragons of Tarkir|182|{1}{G}|Instant|||Choose one - Destroy target blue or black noncreature permanent; or Permanents you control can't be the targets of blue or black spells your opponents control this turn.| +Display of Dominance|Dragons of Tarkir|182|U|{1}{G}|Instant|||Choose one - Destroy target blue or black noncreature permanent; or Permanents you control can't be the targets of blue or black spells your opponents control this turn.| Epic Confrontation|Dragons of Tarkir|185|C|{1}{G}|Sorcery|||Target creature you control gets +1/+2 until end of turn. It fights target creature you don't control.| Foe-Razer Regent|Dragons of Tarkir|187|R|{5}{G}{G}|Creature - Dragon|4|5|Flying$When Foe-Razer Regent enters the battlefield, you may have it fight target creature you don't control.$Whenever a creature you control fights, put two +1/+1 counters on it at the beginning of the next end step.| Salt Road Ambushers|Dragons of Tarkir|198|U|{3}{G}|Creature - Hound Warrior|3|3|Whenever another permanent you control is turned face up, if it's a creature, put two +1/+1 counters on it.$Megamorph {3}{G}{G} You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| @@ -25732,7 +25734,7 @@ Dragonlord Kolaghan|Dragons of Tarkir|218|{4}{B}{R}|Legendary Creature - Elder D Dragonlord Ojutai|Dragons of Tarkir|219|M|{3}{W}{U}|Legendary Creature - Elder Dragon|5|4|Flying$Dragonlord Ojutai has hexproof as long as it's untapped.$Whenever Dragonlord Ojutai deals combat damage to a player, look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| Dragonlord Silumgar|Dragons of Tarkir|220|M|{4}{U}{B}|Legendary Creature - Elder Dragon|3|5|Flying$Deathtouch$When Dragonlord Silumgar enters the battlefield, gain control of target creature or planeswalker for as long as you control Dragonlord Silumgar.| Enduring Scalelord|Dragons of Tarkir|222|U|{4}{G}{W}|Creature - Dragon|4|4|Flying$Whenever one or more +1/+1 counters are place on another creature you control, you may put a +1/+1 counter on Enduring Scaleguard.| -Harbinger of the Hunt|Dragons of Tarkir|223|R|{3]{R}{G}|Creature - Dragon|5|3|Flying${2}{R}: Harbinger of the Hunt deals 1 damage to each creature without flying.${2}{G}: Harbinger of the Hunt deals 1 damage to each other creature with flying.| +Harbinger of the Hunt|Dragons of Tarkir|223|R|{3}{R}{G}|Creature - Dragon|5|3|Flying${2}{R}: Harbinger of the Hunt deals 1 damage to each creature without flying.${2}{G}: Harbinger of the Hunt deals 1 damage to each other creature with flying.| Kolaghan's Command|Dragons of Tarkir|224|R|{1}{B}{R}|Instant|||Choose two - Return target creature card from your graveyard to your hand; or Target player discards a card; or Destroy target artifact; or Kolaghan's Command deals 2 damage to target creature or player.| Narset Transcendent|Dragons of Tarkir|225|M|{2}{W}{U}|Planeswalker - Narset|||+1: Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand.$-2: When you cast your next instant or sorcery spell from your hand this turn, it gains rebound.$-9:You get an emblem with "Your opponents can't cast noncreature spells."| Necromaster Dragon|Dragons of Tarkir|226|R|{3}{U}{B}|Creature - Dragon|4|4|Flying$Whenever Necromaster Dragon deals combat damage to a player, you may pay {2}. If you do, put a 2/2 black Zombie creature token onto the battlefield and each opponent puts the top two cards of his or her library into his or her graveyard.| From 803676268c43a8ef7b8404b9b32516d3335c09ea Mon Sep 17 00:00:00 2001 From: fireshoes Date: Tue, 10 Mar 2015 01:35:57 -0500 Subject: [PATCH 04/12] [DTK] Added Ojutai Exemplars; updated mtg-cards-data.txt for 3/9 spoilers. Added TargetCreatureOrPlaneswalkerAmount --- .../sets/dragonsoftarkir/OjutaiExemplars.java | 136 +++++++++++++ .../TargetCreatureOrPlaneswalkerAmount.java | 178 ++++++++++++++++++ Utils/mtg-cards-data.txt | 1 + 3 files changed, 315 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiExemplars.java create mode 100644 Mage/src/mage/target/common/TargetCreatureOrPlaneswalkerAmount.java diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiExemplars.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiExemplars.java new file mode 100644 index 00000000000..a6f534e7851 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiExemplars.java @@ -0,0 +1,136 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.Card; +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.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class OjutaiExemplars extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("creature spell"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + } + + public OjutaiExemplars(UUID ownerId) { + super(ownerId, 27, "Ojutai Exemplars", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Human"); + this.subtype.add("Monk"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Whenever you cast a noncreature spell, choose one - Tap target creature; + Ability ability = new SpellCastControllerTriggeredAbility(new TapTargetEffect(), filter, false); + ability.addTarget(new TargetCreaturePermanent()); + + // Ojutai Exemplars gain first strike and lifelink until end of turn; + Mode mode = new Mode(); + Effect effect = new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); + effect.setText("{this} gains first strike"); + mode.getEffects().add(effect); + Effect effect2 = new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn); + effect2.setText("and lifelink"); + mode.getEffects().add(effect2); + ability.addMode(mode); + + // or Exile Ojutai Exemplars, then return it to the battlefield tapped under its owner's control. + mode = new Mode(); + mode.getEffects().add(new OjutaiExemplarsEffect()); + ability.addMode(mode); + + this.addAbility(ability); + } + + public OjutaiExemplars(final OjutaiExemplars card) { + super(card); + } + + @Override + public OjutaiExemplars copy() { + return new OjutaiExemplars(this); + } +} + +class OjutaiExemplarsEffect extends OneShotEffect { + + public OjutaiExemplarsEffect() { + super(Outcome.Neutral); + this.staticText = "Exile {this}, then return it to the battlefield tapped under its owner's control"; + } + + public OjutaiExemplarsEffect(final OjutaiExemplarsEffect effect) { + super(effect); + } + + @Override + public OjutaiExemplarsEffect copy() { + return new OjutaiExemplarsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent ojutaiExemplars = game.getPermanent(source.getSourceId()); + if (ojutaiExemplars != null) { + if (ojutaiExemplars.moveToExile(source.getSourceId(), "Ojutai Exemplars", source.getSourceId(), game)) { + Card card = game.getExile().getCard(source.getSourceId(), game); + if (card != null) { + return card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, true); + } + } + } + return false; + } +} \ No newline at end of file diff --git a/Mage/src/mage/target/common/TargetCreatureOrPlaneswalkerAmount.java b/Mage/src/mage/target/common/TargetCreatureOrPlaneswalkerAmount.java new file mode 100644 index 00000000000..e21c763d71c --- /dev/null +++ b/Mage/src/mage/target/common/TargetCreatureOrPlaneswalkerAmount.java @@ -0,0 +1,178 @@ + /* + * 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.target.common; + + import java.util.HashSet; + import java.util.Set; + import java.util.UUID; + import mage.constants.Zone; + import mage.MageObject; + import mage.abilities.Ability; + import mage.abilities.dynamicvalue.DynamicValue; + import mage.abilities.dynamicvalue.common.StaticValue; + import mage.filter.Filter; + import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; + import mage.filter.common.FilterCreaturePermanent; + import mage.game.Game; + import mage.game.permanent.Permanent; + import mage.target.TargetAmount; + + /** + * + * @author BetaSteward_at_googlemail.com + */ + public class TargetCreatureOrPlaneswalkerAmount extends TargetAmount { + + protected FilterCreatureOrPlaneswalkerPermanent filter; + + public TargetCreatureOrPlaneswalkerAmount(int amount) { + // 107.1c If a rule or ability instructs a player to choose “any number,” that player may choose + // any positive number or zero, unless something (such as damage or counters) is being divided + // or distributed among “any number” of players and/or objects. In that case, a nonzero number + // of players and/or objects must be chosen if possible. + this(new StaticValue(amount)); + this.minNumberOfTargets = 1; + } + + public TargetCreatureOrPlaneswalkerAmount(DynamicValue amount) { + super(amount); + this.zone = Zone.ALL; + this.filter = new FilterCreatureOrPlaneswalkerPermanent(); + this.targetName = filter.getMessage(); + } + + public TargetCreatureOrPlaneswalkerAmount(final TargetCreatureOrPlaneswalkerAmount target) { + super(target); + this.filter = target.filter.copy(); + } + + @Override + public Filter getFilter() { + return this.filter; + } + + @Override + public boolean canTarget(UUID id, Game game) { + Permanent permanent = game.getPermanent(id); + if (permanent != null) { + return filter.match(permanent, game); + } + return false; + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + Permanent permanent = game.getPermanent(id); + if (source != null) { + MageObject targetSource = game.getObject(source.getSourceId()); + if (permanent != null) { + return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game); + } + } + + if (permanent != null) { + return filter.match(permanent, game); + } + return false; + } + + @Override + public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) { + return canTarget(id, source, game); + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + int count = 0; + MageObject targetSource = game.getObject(sourceId); + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { + if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { + count++; + if (count >= this.minNumberOfTargets) { + return true; + } + } + } + return false; + } + + @Override + public boolean canChoose(UUID sourceControllerId, Game game) { + int count = 0; + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { + if (filter.match(permanent, null, sourceControllerId, game)) { + count++; + if (count >= this.minNumberOfTargets) { + return true; + } + } + } + return false; + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + MageObject targetSource = game.getObject(sourceId); + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { + if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { + possibleTargets.add(permanent.getId()); + } + } + return possibleTargets; + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { + if (filter.match(permanent, null, sourceControllerId, game)) { + possibleTargets.add(permanent.getId()); + } + } + return possibleTargets; + } + + @Override + public String getTargetedName(Game game) { + StringBuilder sb = new StringBuilder(); + for (UUID targetId : getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null) { + sb.append(permanent.getLogName()).append("(").append(getTargetAmount(targetId)).append(") "); + } + } + return sb.toString(); + } + + @Override + public TargetCreatureOrPlaneswalkerAmount copy() { + return new TargetCreatureOrPlaneswalkerAmount(this); + } + + } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index c8ce7577d1f..a2b40b1f334 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25746,6 +25746,7 @@ Savage Ventmaw|Dragons of Tarkir|231|U|{4}{R}{G}|Creature - Dragon|4|4|Flying$Wh Silumgar's Command|Dragons of Tarkir|232|R|{3}{U}{B}|Instant|||Choose two - Counter target noncreature spell; or Return target permanent to its owner's hand; or Target creature gets -3/-3 until end of turn; or Destroy target planeswalker.| Swift Warkite|Dragons of Tarkir|233|U|{4}{B}{R}|Creature - Dragon|4|4|Flying$When Swift Warkite enters the battlefield, you may put a creature card with converted mana cost 3 or less from your hand or graveyard onto the battlefield. That creature gains haste. Return it to your hand at the beginning of the next end step.| Evolving Wilds|Dragons of Tarkir|248|C||Land|||{T}, Sacrifice Evolving Wilds: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library.| +Haven of the Spirit Dragon|Dragons of Tarkir|249|R||Land|||{T}: Add {1} to your mana pool.${T}: add one mana of any color to your mana pool. Spend this mana only to cast a Dragon creature spell.${2}, {T}, Sacrifice Haven of the Spirit Dragon: Return target Dragon creature card or Ugin planeswalker card from your graveyard to your hand.| Emrakul, the Aeons Torn|Modern Masters 2015|3|M|{15}|Legendary Creature - Eldrazi|15|15|Emrakul, the Aeons Torn can't be countered.$When you cast Emrakul, take an extra turn after this one.$Flying, protection from colored spells, annihilator 6$When Emrakul is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.| Karn Liberated|Modern Masters 2015|4|M|{7}|Planeswalker - Karn|||+4: Target player exiles a card from his or her hand.$-3: Exile target permanent.$-14: Restart the game, leaving in exile all non-Aura permanent cards exiled with Karn Liberated. Then put those cards onto the battlefield under your control.| Tarmogoyf|Modern Masters 2015|165|M|{1}{G}|Creature - Lhurgoyf|*|1+*|Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (Artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal are card types.)| From 9dfd951edd9af4713d973c5af40080aacc0016a2 Mon Sep 17 00:00:00 2001 From: fireshoes Date: Tue, 10 Mar 2015 08:08:55 -0500 Subject: [PATCH 05/12] [DTK] Updated mtg-cards-data.txt for 3/10. --- Utils/mtg-cards-data.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index a2b40b1f334..7cfeb63e9c8 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25669,6 +25669,7 @@ Siege Dragon|Prerelease Events|86|Special|{5}{R}{R}|Creature - Dragon|5|5|Flying Phytotitan|Prerelease Events|87|Special|{4}{G}{G}|Creature - Plant Elemental|7|2|When Phytotitan dies, return it to the battlefield tapped under its owner's control at the beginning of his or her next upkeep.| Anafenza, Kin-Tree Spirit|Dragons of Tarkir|2|R|{W}{W}|Legendary Creature - Spirit Soldier|2|2|Whenever another nontoken creature enters the battlefield under your control, bolster 1. (Choose a creature with the least toughness among creatures you control and put a +1/+1 counter on it.)| Arashin Foremost|Dragons of Tarkir|3|R|{1}{W}{W}|Creature - Human Warrior|2|2|Double strike$Whenever Arashin Foremost enters the battlefield or attacks, another target Warrior creature you control gains double strike until end of turn.| +Artful Maneuver|Dragons of Tarkir|4|C|{1}{W}|Instant|||Target creature gets +2/+2 until end of turn.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| Aven Sunstriker|Dragons of Tarkir|5|U|{1}{W}{W}|Creature - Bird Warrior|1|1|Flying$Double strike (This creature deals both first-strike and regular combat damage.)$Megamorph {4}{W} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Hidden Dragonslayer|Dragons of Tarkir|23|R|{1}{W}|Creature - Human Warrior|2|1|Lifelink$Megamorph {2}{W} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Hidden Dragonslayer is turned face up, destroy target creature with power 4 or greater an opponent controls.| Ojutai Exemplars|Dragons of Tarkir|27|M|{2}{W}{W}|Creature - Human Monk|4|4|Whenever you cast a noncreature spell, choose one - Tap target creature; Ojutai Exemplars gain first strike and lifelink until end of turn; or Exile Ojutai Exemplars, then return it to the battlefield tapped under its owner's control.| @@ -25684,6 +25685,7 @@ Encase in Ice|Dragons of Tarkir|54|U|{1}{U}|Enchantment - Aura|||Flash$Enchant r Gudul Lurker|Dragons of Tarkir|56|U|{U}|Creature - Salamander|1|1|Gudul Lurker can't be blocked.$Megamorph {U} (You may cast this card face down as a 2/2 creature for {3}. Turn it up anytime for its megamorph cost and put a +1/+1 counter on it.)| Mirror Mockery|Dragons of Tarkir|62|R|{1}{U}|Enchantment - Aura|||Enchant creature$Whenever enchanted creature attacks, you may put a token onto the battlefield that's a copy of that creature. Exile that token at the end of combat.| Ojutai's Summons|Dragons of Tarkir|68|C|{3}{U}{U}|Sorcery|||Put a 2/2 blue Djinn Monk creature token with flying onto the battlefield.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| +Qarsi Deceiver|Dragons of Tarkir|71|U|{1}{U}|Creature - Naga Wizard|0|4|{T}: Add {1} to your mana pool. Spend this mana only to cast a face-down creature spell, pay a mana cost to turn a manifested creature face up, or pay a morph cost. | Shorecrasher Elemental|Dragons of Tarkir|73|M|{U}{U}{U}|Creature - Elemental|3|3|{U}: Exile Shorecrasher Elemental, then return it to the battlefield face down under its owner's control.${1}: Shorecrasher Elemental gets +1/-1 or -1/+1 until end of turn.$Megamorph {4}{U} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Silumgar's Scorn|Dragtons of Tarkir|78|U|{U}{U}|Instant|||As an additional cost to cast Silumgar's Scorn, you may reveal a Dragon card from your hand.$Counter target spell unless its controller pays {1}. If you revealed a Dragon card or controlled a Dragon as you cast Silumgar's Scorn, counter that spell instead.| Stratus Dancer|Dragons of Tarkir|80|R|{1}{U}|Creature - Djinn Monk|2|1|Flying$Megamorph {1}{U} You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time from its megamorph cost and put a +1/+1 counter on it.)| @@ -25692,6 +25694,7 @@ Blood-Chin Fanatic|Dragons of Tarkir|88|R|{1}{B}{B}|Creature - Orc Warrior|3|3|{ Deathbringer Regent|Dragons of Tarkir|96|R|{5}{B}{B}|Creature - Dragon|5|6|Flying$When Deathbringer Regent enters the battlefield, if you cast it from your hand and there are five or more other creatures on the battlefield, destroy all other creatures.| Hedonist's Trove|Dragons of Tarkir|106|R|{5}{B}{B}|Enchantment|||When Hdeonist's Trove enters the battlefield, exile all cards in target opponent's graveyard.$You may play land cards exiled by Hedonist's Trove.$once per turn, you may cast a nonland card exiled by Hedonist's Trove.| Marang River Skeleton|Dragons of Tarkir|108|U|{1}{B}|Creature - Skeleton|1|1|{B}: Regenerate Marang River Skeleton.$Megamorph {3}{B} You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)| +Pitiless Horde|Dragons of Tarkir|R|112|{2}{B}|Creature - Orc Berserker|5|3|At the beginning of your upkeep, lose 2 life.$Dash {2}{B}{B} (You may cast tjos spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| Risen Executioner|Dragons of Tarkir|116|M|{2}{B}{B}|Creature - Zombie Warrior|4|3|Risen Executioner can't block.$Other Zombie creatures you control get +1/+1.$You may cast Risen Executioner from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard.| Self-Inflicted Wound|Dragons of Tarkir|117|U|{1}{B}|Sorcery|||Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life.| Sidisi, Undead Vizier|Dragons of Tarkir|120|R|{3}{B}{B}|Legendary Creature - Zombie Naga|4|6|Deathtouch$Exploit (When this creature enters the battlefield, you may sacrifice a creature.)$When Sidisi, Undead Vizier exploits a creature, you may search your library for a card, put it into your hand, then shuffle your library.| @@ -25700,6 +25703,7 @@ Silumgar Butcher|Dragons of Tarkir|122|C|{4}{B}|Creature - Zombie Djinn|3|3|Expl Ultimate Price|Dragons of Tarkir|124|U|{1}{B}|Instant|||Destroy target monocolored creature.| Crater Elemental|Dragons of Tarkir|132|R|{2}{R}|Creature - Elemental|0|6|{R}, {T}, Sacrifice Crater Elemental: Crater Elemental deals 4 damage to target creature.$Formidable - {2}{R}: Crater Elemental has base power 8 until end of turn. Activate this ability only if creatures you control have total power 8 or greater.| Descent of the Dragons|Dragons of Tarkir|133|M|{4}{R}{R}|Sorcery||Destroy any number of target creatures. For each creature destroyed this way, its controller puts a 4/4 red Dragon creature token with flying onto the battlefield.| +Ire Shaman|Dragons of Tarkir|141|R|{1}{R}|Creature - Orc Shaman|2|1|Ire Shaman can't be blocked except by two or more creatures.$Megamorph {R} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Ire Shaman is turned face up, exile the top card of your library. Until end of turn, you may play that card.| Draconic Roar|Dragons of Tarkir|154|U|{1}{R}|Instant - As an additional cost to cast Draconic Roar, you may reveal a Dragon card from your hand.$Draconic Roar deals 3 damage to target creature. If you revealed a Dragon card or controlled a Dragon as you cast Draconic Roar, Draconic Roar deals 3 damage to that creature's controller.| Dragon Fodder|Dragons of Tarkir|135|C|{1}{R}|Sorcery|||Put two 1/1 red Goblin creature tokens onto the battlefield.| Dragon Tempest|Dragons of Tarkir|136|R|{1}{R}|Enchantment|||Whenever a creature with flying enters the battlefield under your control, it gains haste until the end of turn.$Whenever a Dragon enters the battlefield under your control, it deals X damage to target creature or player, where X is the number of Dragons you control.| @@ -25711,6 +25715,7 @@ Sprinting Warbrute|Dragons of Tarkir|157|C|{4}{R}|Creature - Ogre Berserker|5|4| Stormcrag Elemental|Dragons of Tarkir|158|U|{5}{R}|Creature - Elemental|5|5|Trample$Megamorph {4}{R}{R} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Stormwing Dragon|Dragons of Tarkir|159|U|{5}{R}|Creature - Dragon|3|3|Flying, first strike$Megamorph {5}{R}{R} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Stormwing Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.| Thunderbreak Regent|Dragons of Tarkir|162|R|{2}{R}{R}|Creature - Dragon|4|4|Flying$Whenever a Dragon you control becomes the target of a spell or ability your opponent controls, Thunderbreak Regent deals 3 damage to that player.| +Warbringer|Dragons of Tarkir|168|U|{3}{R}|Creature - Orc Berserker|3|3|Dash costs you pay cost {2} less (as long as this creature is on the battlefield).$Dash {2}{R} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| Zurgo Bellstriker|Dragons of Tarkir|169|R|{R}|Legendary Creature - Orc Warrior|2|2|Zurgo Bellstriker can't block creatures with power 2 or greater.$Dash {1}{R} You may cast this creature for its dash cost. If you do, it gains haste, and it's returned to its owner's hand at the beginning of the next end step.)| Aerie Bowmasters|Dragons of Tarkir|170|C|{2}|{G}{G}|Creature - Hound Archer|Reach (This creature can block creatures with flying.)$Megamorph {5}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)| Collected Company|Dragons of Tarkir|177|R|{3}{G}|Instant|||Look at the top six cards of your library. Put up to two creature cards with converted mana cost 3 or less from among them onto the battlefield. Put the rest on the bottom of your library in any order.| From 5a31e35837d994276638eef2b8164f1dceab6198 Mon Sep 17 00:00:00 2001 From: fireshoes Date: Tue, 10 Mar 2015 09:11:04 -0500 Subject: [PATCH 06/12] [DTK] Added Artful Maneuver, Ire Shaman, and Pitiless Horde. Updated mtg-cards-data.txt for 3/10. --- .../sets/dragonsoftarkir/ArtfulManeuver.java | 65 ++++++++ .../mage/sets/dragonsoftarkir/IreShaman.java | 151 ++++++++++++++++++ .../sets/dragonsoftarkir/PitilessHorde.java | 69 ++++++++ Utils/mtg-cards-data.txt | 2 +- 4 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/ArtfulManeuver.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/IreShaman.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/PitilessHorde.java diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ArtfulManeuver.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ArtfulManeuver.java new file mode 100644 index 00000000000..2c16f2419b8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ArtfulManeuver.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.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.ReboundAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class ArtfulManeuver extends CardImpl { + + public ArtfulManeuver(UUID ownerId) { + super(ownerId, 4, "Artful Maneuver", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{W}"); + this.expansionSetCode = "DTK"; + + // Target creature gets +2/+2 until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(2,2,Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Rebound + this.addAbility(new ReboundAbility()); + } + + public ArtfulManeuver(final ArtfulManeuver card) { + super(card); + } + + @Override + public ArtfulManeuver copy() { + return new ArtfulManeuver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/IreShaman.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/IreShaman.java new file mode 100644 index 00000000000..c78e54933ae --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/IreShaman.java @@ -0,0 +1,151 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByOneEffect; +import mage.abilities.keyword.MorphAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.AsThoughEffectType; +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.permanent.Permanent; +import mage.players.Library; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author fireshoes + */ +public class IreShaman extends CardImpl { + + public IreShaman(UUID ownerId) { + super(ownerId, 141, "Ire Shaman", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Orc"); + this.subtype.add("Shaman"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Ire Shaman can't be blocked except by two or more creatures. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByOneEffect(2))); + + // Megamorph {R} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{R}"), true)); + + // When Ire Shaman is turned face up, exile the top card of your library. Until end of turn, you may play that card. + this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new IreShamanExileEffect(), false)); + } + + public IreShaman(final IreShaman card) { + super(card); + } + + @Override + public IreShaman copy() { + return new IreShaman(this); + } +} + +class IreShamanExileEffect extends OneShotEffect { + + public IreShamanExileEffect() { + super(Outcome.Detriment); + this.staticText = "Exile the top card of your library. Until end of turn, you may play that card"; + } + + public IreShamanExileEffect(final IreShamanExileEffect effect) { + super(effect); + } + + @Override + public IreShamanExileEffect copy() { + return new IreShamanExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourcePermanent != null && controller != null && controller.getLibrary().size() > 0) { + Library library = controller.getLibrary(); + Card card = library.removeFromTop(game); + if (card != null) { + String exileName = new StringBuilder(sourcePermanent.getName()).append(" ").toString(); + controller.moveCardToExileWithInfo(card, source.getSourceId(), exileName, source.getSourceId(), game, Zone.LIBRARY); + ContinuousEffect effect = new IreShamanCastFromExileEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } + return true; + } + return false; + } +} + +class IreShamanCastFromExileEffect extends AsThoughEffectImpl { + + public IreShamanCastFromExileEffect() { + super(AsThoughEffectType.PLAY_FROM_NON_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + staticText = "You may play the card from exile"; + } + + public IreShamanCastFromExileEffect(final IreShamanCastFromExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public IreShamanCastFromExileEffect copy() { + return new IreShamanCastFromExileEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + return source.getControllerId().equals(affectedControllerId) && + objectId.equals(getTargetPointer().getFirst(game, source)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/PitilessHorde.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/PitilessHorde.java new file mode 100644 index 00000000000..be191f0dae7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/PitilessHorde.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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.keyword.DashAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author fireshoes + */ +public class PitilessHorde extends CardImpl { + + public PitilessHorde(UUID ownerId) { + super(ownerId, 112, "Pitiless Horde", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Orc"); + this.subtype.add("Berserker"); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // At the beginning of your upkeep, lose 2 life. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new LoseLifeSourceControllerEffect(2), TargetController.YOU, false)); + + // Dash {2}{B}{B} + this.addAbility(new DashAbility(this, "{2}{B}{B}")); + } + + public PitilessHorde(final PitilessHorde card) { + super(card); + } + + @Override + public PitilessHorde copy() { + return new PitilessHorde(this); + } +} diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 7cfeb63e9c8..6e65804f1b9 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25694,7 +25694,7 @@ Blood-Chin Fanatic|Dragons of Tarkir|88|R|{1}{B}{B}|Creature - Orc Warrior|3|3|{ Deathbringer Regent|Dragons of Tarkir|96|R|{5}{B}{B}|Creature - Dragon|5|6|Flying$When Deathbringer Regent enters the battlefield, if you cast it from your hand and there are five or more other creatures on the battlefield, destroy all other creatures.| Hedonist's Trove|Dragons of Tarkir|106|R|{5}{B}{B}|Enchantment|||When Hdeonist's Trove enters the battlefield, exile all cards in target opponent's graveyard.$You may play land cards exiled by Hedonist's Trove.$once per turn, you may cast a nonland card exiled by Hedonist's Trove.| Marang River Skeleton|Dragons of Tarkir|108|U|{1}{B}|Creature - Skeleton|1|1|{B}: Regenerate Marang River Skeleton.$Megamorph {3}{B} You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)| -Pitiless Horde|Dragons of Tarkir|R|112|{2}{B}|Creature - Orc Berserker|5|3|At the beginning of your upkeep, lose 2 life.$Dash {2}{B}{B} (You may cast tjos spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| +Pitiless Horde|Dragons of Tarkir|112|R|{2}{B}|Creature - Orc Berserker|5|3|At the beginning of your upkeep, lose 2 life.$Dash {2}{B}{B} (You may cast tjos spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| Risen Executioner|Dragons of Tarkir|116|M|{2}{B}{B}|Creature - Zombie Warrior|4|3|Risen Executioner can't block.$Other Zombie creatures you control get +1/+1.$You may cast Risen Executioner from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard.| Self-Inflicted Wound|Dragons of Tarkir|117|U|{1}{B}|Sorcery|||Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life.| Sidisi, Undead Vizier|Dragons of Tarkir|120|R|{3}{B}{B}|Legendary Creature - Zombie Naga|4|6|Deathtouch$Exploit (When this creature enters the battlefield, you may sacrifice a creature.)$When Sidisi, Undead Vizier exploits a creature, you may search your library for a card, put it into your hand, then shuffle your library.| From cca99b22aae66df36cbafb927df90fd9c591febd Mon Sep 17 00:00:00 2001 From: fireshoes Date: Tue, 10 Mar 2015 10:16:29 -0500 Subject: [PATCH 07/12] [DTK] Updated mtg-cards-data.txt for 3/10. --- Utils/mtg-cards-data.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 6e65804f1b9..7745d3d56d3 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25718,6 +25718,8 @@ Thunderbreak Regent|Dragons of Tarkir|162|R|{2}{R}{R}|Creature - Dragon|4|4|Flyi Warbringer|Dragons of Tarkir|168|U|{3}{R}|Creature - Orc Berserker|3|3|Dash costs you pay cost {2} less (as long as this creature is on the battlefield).$Dash {2}{R} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| Zurgo Bellstriker|Dragons of Tarkir|169|R|{R}|Legendary Creature - Orc Warrior|2|2|Zurgo Bellstriker can't block creatures with power 2 or greater.$Dash {1}{R} You may cast this creature for its dash cost. If you do, it gains haste, and it's returned to its owner's hand at the beginning of the next end step.)| Aerie Bowmasters|Dragons of Tarkir|170|C|{2}|{G}{G}|Creature - Hound Archer|Reach (This creature can block creatures with flying.)$Megamorph {5}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)| +Assault Formation|Dragons of Tarkir|173|R|{1}{G}|Enchantment|||Each creature you control assigns combat damage equal to its toughness rather than its power.${G}: Target creature with defender can attack this turn as though it didn't have defender.${2}{G}: Creatures you control get +0/+1 until end of turn.| +Avatar of the Resolute|Dragons of Tarkir|175|R|{G}{G}|Creature - Avatar|3|2|Reach, trample$Avatar of the Resolute enters the battlefield with a +1/+1 counter on it for each other creature you control with a +1/+1 counter on it.| Collected Company|Dragons of Tarkir|177|R|{3}{G}|Instant|||Look at the top six cards of your library. Put up to two creature cards with converted mana cost 3 or less from among them onto the battlefield. Put the rest on the bottom of your library in any order.| Deathmist Raptor|Dragons of Tarkir|180|M|{1}{G}{G}|Creature - Lizard Beast|3|3|Deathtouch$Whenever a permanent you control is turned face up, you may return Deathmist Raptor from your graveyard to the battlefield face up or face down.$Megamorph {4}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Den Protector|Dragons of Tarkir|181|R|{1}{G}|Creature - Human Warrior|2|1|Creatures with power less than Den Protector's power can't block it.$Megamorph {1}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| @@ -25729,8 +25731,7 @@ Scaleguard Sentinels|Dragons of Tarkir|201|U|{G}{G}|Creature - Human Soldier|2|3 Shaman of Forgotten Ways|Dragons of Tarkir|204|M|{2}G}|Creature - Human Shaman| 2|3|{T}:Add two mana in any combination of colors to your mana pool. Spend this mana only to cast creature spells.$Formidable - {9}{G}{G},{T}:Each player's life total becomes the number of creatures he or she controls. Acitave the ability only if creatures you control have total power 8 or greater.| Stampeding Elk Herd|Dragons of Tarkir|208|C|{3}{G}{G}|Creature - Elk|5|5|Formidable - Whenever Stampeding Elk Herd attacks, if creatures you control have total power 8 or greater, creatures you control gain trample until end of turn.| Sunbringer's Touch|Dragons of Tarkir|209|R|{2}{G}{G}|Sorcery|||Bolster X, where X is the number of cards in your hand. Each creature you control with a +1/+1 counter on it gains trample until end of turn. (To bolster X, choose a creature with the least toughness among creature you control and put X +1/+1 counters on it.)| -Arashin Sovereign|Dragons of Tarkir|212|R|{5}{G}{W}|Creature - Dragon|6|6|Flying$When Arashin Sovereign dies, you may put it on the top or bottom of its owner's library.| -Atarka's Command|Dragons of Tarkir|213|R|{R}{G}|Instant|||Choose two - Your opponents can't gain life this turn; or Atarka's Command deals 3 damage to each opponent; or You may put a land card from your hand onto the battlefield; or Creatures you control get +1/+1 and gain reach until the end of turn.| +Arashin Sovereign|Dragons of Tarkir|212|R|{5}{G}{W}|Creature - Dragon|6|6|Flying$When Arashin Sovereign dies, you may put it on the top or bottom of its owner's library.|Atarka's Command|Dragons of Tarkir|213|R|{R}{G}|Instant|||Choose two - Your opponents can't gain life this turn; or Atarka's Command deals 3 damage to each opponent; or You may put a land card from your hand onto the battlefield; or Creatures you control get +1/+1 and gain reach until the end of turn.| Boltwing Marauder|Dragons of Tarkir|214|R|{3}{B}{R}|Creature - Dragon|5|4|Flying$Whenever another creature enters the battlefield under your control, target creature gets +2/+0 until end of turn.| Cunning Breezedancer|Dragons of Tarkir|215|U|{4}{W}{U}|Creature - Dragon|4|4|Flying$Whenever you cast a noncreature spell, Cunning Breezedancer gets +2/+2 until end of turn.| Dragonlord Atarka|Dragons of Tarkir|216|M|{5}{R}{G}|Legendary Creature - Elder Dragon|8|8|Flying, trample$When Dragonlord Atarka enters the battlefield, it deals 5 damage divided as you choose among any number of target creatures and/or planeswalkers your opponents control.| From 8b7cc5ae45d87e094805ce33ca60433d8f1792d9 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 10 Mar 2015 11:47:45 -0500 Subject: [PATCH 08/12] - Added some DTK cards. Dragonlord Silumgar and Deathbringer Regent. --- .../dragonsoftarkir/DeathbringerRegent.java | 107 ++++++++++++++++++ .../dragonsoftarkir/DragonlordSilumgar.java | 83 ++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/DeathbringerRegent.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordSilumgar.java diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathbringerRegent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathbringerRegent.java new file mode 100644 index 00000000000..e7da53ee3e6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathbringerRegent.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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; +import mage.watchers.common.CastFromHandWatcher; + +/** + * + * @author jeffwadsworth + */ +public class DeathbringerRegent extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other creatures"); + + static { + filter.add(new AnotherPredicate()); + } + + public DeathbringerRegent(UUID ownerId) { + super(ownerId, 96, "Deathbringer Regent", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Deathbringer Regent enters the battlefield, if you cast it from your hand and there are five or more other creatures on the battlefield, destroy all other creatures. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(new DestroyAllEffect(filter), new DeathbringerRegentCondition()), false), new CastFromHandWatcher()); + + } + + public DeathbringerRegent(final DeathbringerRegent card) { + super(card); + } + + @Override + public DeathbringerRegent copy() { + return new DeathbringerRegent(this); + } +} + +class DeathbringerRegentCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + boolean applies = false; + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId()); + if (watcher != null && watcher.conditionMet()) { + applies = true; + } + } + if (applies) { + applies = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), game).size() >= 6; + } + return applies; + } + + @Override + public String toString() { + return "you cast it from your hand and there are five or more other creatures on the battlefield"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordSilumgar.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordSilumgar.java new file mode 100644 index 00000000000..75905fc5777 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordSilumgar.java @@ -0,0 +1,83 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreatureOrPlaneswalker; + +/** + * + * @author jeffwadsworth + */ +public class DragonlordSilumgar extends CardImpl { + + public DragonlordSilumgar(UUID ownerId) { + super(ownerId, 220, "Dragonlord Silumgar", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{4}{U}{B}"); + this.expansionSetCode = "DTK"; + this.supertype.add("Legendary"); + this.subtype.add("Elder"); + this.subtype.add("Dragon"); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // When Dragonlord Silumgar enters the battlefield, gain control of target creature or planeswalker for as long as you control Dragonlord Silumgar. + ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new GainControlTargetEffect(Duration.Custom), new SourceOnBattlefieldControlUnchangedCondition(), null); + effect.setText("gain control of target creature or planeswalker for as long as you control {this}"); + Ability ability = new EntersBattlefieldTriggeredAbility(effect, false); + ability.addTarget(new TargetCreatureOrPlaneswalker()); + this.addAbility(ability); + + } + + public DragonlordSilumgar(final DragonlordSilumgar card) { + super(card); + } + + @Override + public DragonlordSilumgar copy() { + return new DragonlordSilumgar(this); + } +} From 3b64f37125d66f186c724b25cfddeb5df0cf7253 Mon Sep 17 00:00:00 2001 From: mnapoleon Date: Tue, 10 Mar 2015 14:12:51 -0400 Subject: [PATCH 09/12] implemented Cloud Spirit in Portal and Stronghold sets, as well as Sandstorm in Arabian Nights, 4th Edition and Mirage sets --- .../mage/sets/arabiannights/Sandstorm.java | 52 +++++++++++++++ .../mage/sets/fourthedition/Sandstorm.java | 59 +++++++++++++++++ Mage.Sets/src/mage/sets/mirage/Sandstorm.java | 52 +++++++++++++++ .../src/mage/sets/portal/CloudSpirit.java | 54 +++++++++++++++ .../src/mage/sets/stronghold/CloudSpirit.java | 65 +++++++++++++++++++ 5 files changed, 282 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/arabiannights/Sandstorm.java create mode 100644 Mage.Sets/src/mage/sets/fourthedition/Sandstorm.java create mode 100644 Mage.Sets/src/mage/sets/mirage/Sandstorm.java create mode 100644 Mage.Sets/src/mage/sets/portal/CloudSpirit.java create mode 100644 Mage.Sets/src/mage/sets/stronghold/CloudSpirit.java diff --git a/Mage.Sets/src/mage/sets/arabiannights/Sandstorm.java b/Mage.Sets/src/mage/sets/arabiannights/Sandstorm.java new file mode 100644 index 00000000000..42ec0985109 --- /dev/null +++ b/Mage.Sets/src/mage/sets/arabiannights/Sandstorm.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.arabiannights; + +import java.util.UUID; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class Sandstorm extends mage.sets.fourthedition.Sandstorm { + + public Sandstorm(UUID ownerId) { + super(ownerId); + this.cardNumber = 38; + this.expansionSetCode = "ARN"; + } + + public Sandstorm(final Sandstorm card) { + super(card); + } + + @Override + public Sandstorm copy() { + return new Sandstorm(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fourthedition/Sandstorm.java b/Mage.Sets/src/mage/sets/fourthedition/Sandstorm.java new file mode 100644 index 00000000000..c6aea781f72 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/Sandstorm.java @@ -0,0 +1,59 @@ +/* + * 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.fourthedition; + +import java.util.UUID; +import mage.abilities.effects.common.DamageAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterAttackingCreature; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class Sandstorm extends CardImpl { + + public Sandstorm(UUID ownerId) { + super(ownerId, 153, "Sandstorm", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}"); + this.expansionSetCode = "4ED"; + + // Sandstorm deals 1 damage to each attacking creature. + this.getSpellAbility().addEffect(new DamageAllEffect(1, new FilterAttackingCreature())); + } + + public Sandstorm(final Sandstorm card) { + super(card); + } + + @Override + public Sandstorm copy() { + return new Sandstorm(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirage/Sandstorm.java b/Mage.Sets/src/mage/sets/mirage/Sandstorm.java new file mode 100644 index 00000000000..ce570de42fe --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/Sandstorm.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 michael.napoleon@gmail.com + */ +public class Sandstorm extends mage.sets.fourthedition.Sandstorm { + + public Sandstorm(UUID ownerId) { + super(ownerId); + this.cardNumber = 137; + this.expansionSetCode = "MIR"; + } + + public Sandstorm(final Sandstorm card) { + super(card); + } + + @Override + public Sandstorm copy() { + return new Sandstorm(this); + } +} diff --git a/Mage.Sets/src/mage/sets/portal/CloudSpirit.java b/Mage.Sets/src/mage/sets/portal/CloudSpirit.java new file mode 100644 index 00000000000..4ffab029985 --- /dev/null +++ b/Mage.Sets/src/mage/sets/portal/CloudSpirit.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.portal; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class CloudSpirit extends mage.sets.stronghold.CloudSpirit { + + public CloudSpirit(UUID ownerId) { + super(ownerId); + this.cardNumber = 48; + this.expansionSetCode = "POR"; + this.rarity = Rarity.UNCOMMON; + } + + public CloudSpirit(final CloudSpirit card) { + super(card); + } + + @Override + public CloudSpirit copy() { + return new CloudSpirit(this); + } +} diff --git a/Mage.Sets/src/mage/sets/stronghold/CloudSpirit.java b/Mage.Sets/src/mage/sets/stronghold/CloudSpirit.java new file mode 100644 index 00000000000..90568f97f8b --- /dev/null +++ b/Mage.Sets/src/mage/sets/stronghold/CloudSpirit.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.stronghold; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.CanBlockOnlyFlyingAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class CloudSpirit extends CardImpl { + + public CloudSpirit(UUID ownerId) { + super(ownerId, 26, "Cloud Spirit", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{U}"); + this.expansionSetCode = "STH"; + this.subtype.add("Spirit"); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Cloud Spirit can block only creatures with flying. + this.addAbility(new CanBlockOnlyFlyingAbility()); + } + + public CloudSpirit(final CloudSpirit card) { + super(card); + } + + @Override + public CloudSpirit copy() { + return new CloudSpirit(this); + } +} From fe2cd395a68e2b0c9a698de322149bbe43b642bb Mon Sep 17 00:00:00 2001 From: betasteward Date: Tue, 10 Mar 2015 14:57:55 -0400 Subject: [PATCH 10/12] moved info from CardImpl to CardState and PermanentImpl + created InfoEffect for displaying rule info on Card --- Mage.Common/src/mage/view/CardView.java | 8 +- Mage.Common/src/mage/view/PermanentView.java | 2 +- .../sets/avacynrestored/CavernOfSouls.java | 2 +- .../sets/avacynrestored/RidersOfGavony.java | 2 +- .../bornofthegods/KioraTheCrashingWave.java | 4 +- .../sets/commander2013/TrueNameNemesis.java | 2 +- .../mage/sets/commander2014/BitterFeud.java | 2 +- .../mage/sets/dissension/UtopiaSprawl.java | 2 +- .../src/mage/sets/eventide/BatwingBrume.java | 3 +- .../mage/sets/eventide/CankerousThirst.java | 3 +- .../mage/sets/eventide/InvertTheSkies.java | 3 +- .../src/mage/sets/eventide/Moonhold.java | 3 +- .../mage/sets/eventide/UnnervingAssault.java | 3 +- .../src/mage/sets/fifthdawn/SummonersEgg.java | 2 +- .../src/mage/sets/innistrad/Nevermore.java | 2 +- .../sets/journeyintonyx/HallOfTriumph.java | 2 +- .../sets/magic2012/AdaptiveAutomaton.java | 2 +- .../mage/sets/magic2014/DoorOfDestinies.java | 2 +- .../mage/sets/magic2014/EliteArcanist.java | 2 +- .../sets/magic2014/ShadowbornApostle.java | 3 +- .../src/mage/sets/magic2015/ObeliskOfUrd.java | 2 +- .../src/mage/sets/mirrodin/Duplicant.java | 2 +- .../mage/sets/mirrodin/ExtraplanarLens.java | 2 +- .../mage/sets/mirrodin/IsochronScepter.java | 2 +- .../src/mage/sets/mirrodin/SoulFoundry.java | 2 +- .../mirrodinbesieged/PhyrexianRevoker.java | 2 +- .../src/mage/sets/newphyrexia/Xenograft.java | 2 +- .../sets/planarchaos/VoidstoneGargoyle.java | 2 +- .../riseoftheeldrazi/CurseOfWizardry.java | 2 +- .../sets/shadowmoor/DawnglowInfusion.java | 3 +- .../src/mage/sets/shadowmoor/Firespout.java | 3 +- .../sets/shadowmoor/LureboundScarecrow.java | 2 +- .../mage/sets/shadowmoor/PaintersServant.java | 2 +- .../mage/sets/shadowmoor/RepelIntruders.java | 3 +- .../src/mage/sets/shadowmoor/RiversGrasp.java | 3 +- .../sets/sorinvstibalt/TorrentOfSouls.java | 3 +- .../src/mage/sets/tenth/RelentlessRats.java | 3 +- .../sets/zendikar/IonaShieldOfEmeria.java | 2 +- .../cards/abilities/keywords/HauntTest.java | 130 ++++++++++++++++++ .../cards/rules/AlternativeCostRuleTest.java | 2 +- .../cards/single/roe/CastThroughTimeTest.java | 2 +- .../effects/common/ChooseColorEffect.java | 2 +- .../common/ChooseCreatureTypeEffect.java | 2 +- .../effects/common/ChooseModeEffect.java | 2 +- .../effects/common/DetainAllEffect.java | 4 +- .../effects/common/DetainTargetEffect.java | 4 +- .../abilities/effects/common/InfoEffect.java | 61 ++++++++ .../effects/common/NameACardEffect.java | 2 +- .../mage/abilities/keyword/HauntAbility.java | 4 +- Mage/src/mage/cards/Card.java | 6 +- Mage/src/mage/cards/CardImpl.java | 56 ++++---- .../predicate/other/CardTextPredicate.java | 2 +- .../mage/game/permanent/PermanentImpl.java | 35 ++++- Mage/src/mage/game/stack/Spell.java | 7 +- .../common/CommanderCombatDamageWatcher.java | 10 +- 55 files changed, 333 insertions(+), 94 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/HauntTest.java create mode 100644 Mage/src/mage/abilities/effects/common/InfoEffect.java diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index 1500a926324..fafd5af104f 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -190,15 +190,15 @@ public class CardView extends SimpleCardView { this.isSplitCard = true; leftSplitName = splitCard.getLeftHalfCard().getName(); leftSplitCosts = splitCard.getLeftHalfCard().getManaCost(); - leftSplitRules = splitCard.getLeftHalfCard().getRules(); + leftSplitRules = splitCard.getLeftHalfCard().getRules(game); rightSplitName = splitCard.getRightHalfCard().getName(); rightSplitCosts = splitCard.getRightHalfCard().getManaCost(); - rightSplitRules = splitCard.getRightHalfCard().getRules(); + rightSplitRules = splitCard.getRightHalfCard().getRules(game); } this.name = card.getImageName(); this.displayName = card.getName(); - this.rules = card.getRules(); + this.rules = card.getRules(game); this.manaCost = card.getManaCost().getSymbols(); this.convertedManaCost = card.getManaCost().convertedManaCost(); @@ -254,7 +254,7 @@ public class CardView extends SimpleCardView { } // // set code und card number for token copies to get the image - this.rules = ((PermanentToken) card).getRules(); + this.rules = ((PermanentToken) card).getRules(game); this.type = ((PermanentToken)card).getToken().getTokenType(); } else { this.rarity = card.getRarity(); diff --git a/Mage.Common/src/mage/view/PermanentView.java b/Mage.Common/src/mage/view/PermanentView.java index dfc3c49b89f..376e63e69a6 100644 --- a/Mage.Common/src/mage/view/PermanentView.java +++ b/Mage.Common/src/mage/view/PermanentView.java @@ -64,7 +64,7 @@ public class PermanentView extends CardView { public PermanentView(Permanent permanent, Card card, UUID createdForPlayerId, Game game) { super(permanent, game, null, permanent.getControllerId().equals(createdForPlayerId)); this.controlled = permanent.getControllerId().equals(createdForPlayerId); - this.rules = permanent.getRules(); + this.rules = permanent.getRules(game); this.tapped = permanent.isTapped(); this.flipped = permanent.isFlipped(); this.phasedIn = permanent.isPhasedIn(); diff --git a/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java b/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java index 5c2702bcd3d..5e0b1e5f2b6 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java @@ -120,7 +120,7 @@ class CavernOfSoulsEffect extends OneShotEffect { } game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + typeChoice.getChoice()); game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice())); + permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); } return false; } diff --git a/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java b/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java index 00234ae24ae..fb1ffba09b6 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java @@ -110,7 +110,7 @@ class RidersOfGavonyEffect extends OneShotEffect { if (typeChoice.getChoice() != null) { game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + typeChoice.getChoice()); game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + ""); + permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + "", game); } } return false; diff --git a/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java b/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java index 4057da0b812..79e1b6c7615 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java @@ -131,7 +131,7 @@ class KioraPreventionEffect extends PreventionEffectImpl { for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),CardUtil.addToolTipMarkTags("All damage that would be dealt to and dealt by this permanent is prevented.")); + permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),CardUtil.addToolTipMarkTags("All damage that would be dealt to and dealt by this permanent is prevented."), game); } } } @@ -154,7 +154,7 @@ class KioraPreventionEffect extends PreventionEffectImpl { for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),""); + permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),"", game); } } return true; diff --git a/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java b/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java index fdd6816cb4d..c7a8c341940 100644 --- a/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java +++ b/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java @@ -113,7 +113,7 @@ class TrueNameNemesisChoosePlayerEffect extends OneShotEffect { if (chosenPlayer != null) { game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + chosenPlayer.getName()); game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - permanent.addInfo("chosen player", "Chosen player: " + chosenPlayer.getName() + ""); + permanent.addInfo("chosen player", "Chosen player: " + chosenPlayer.getName() + "", game); return true; } } diff --git a/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java b/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java index 249638ba05c..7e9579dbc64 100644 --- a/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java +++ b/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java @@ -103,7 +103,7 @@ class BitterFeudEntersBattlefieldEffect extends OneShotEffect { game.getState().setValue(source.getSourceId() + "_player1", player1); game.getState().setValue(source.getSourceId() + "_player2", player2); game.informPlayers(permanent.getName() + ": " + controller.getName() + " has chosen " + player1.getName() + " and " + player2.getName()); - permanent.addInfo("chosen players", "Chosen players: " + player1.getName() +", " + player2.getName() + ""); + permanent.addInfo("chosen players", "Chosen players: " + player1.getName() +", " + player2.getName() + "", game); return true; } } diff --git a/Mage.Sets/src/mage/sets/dissension/UtopiaSprawl.java b/Mage.Sets/src/mage/sets/dissension/UtopiaSprawl.java index 5137108041d..ea255023794 100644 --- a/Mage.Sets/src/mage/sets/dissension/UtopiaSprawl.java +++ b/Mage.Sets/src/mage/sets/dissension/UtopiaSprawl.java @@ -115,7 +115,7 @@ class ChooseColorEffect extends OneShotEffect { if (player.choose(Outcome.Neutral, colorChoice, game)) { game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + colorChoice.getChoice()); game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor()); - permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + ""); + permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + "", game); } } return false; diff --git a/Mage.Sets/src/mage/sets/eventide/BatwingBrume.java b/Mage.Sets/src/mage/sets/eventide/BatwingBrume.java index ef6380c78f6..b94e083198b 100644 --- a/Mage.Sets/src/mage/sets/eventide/BatwingBrume.java +++ b/Mage.Sets/src/mage/sets/eventide/BatwingBrume.java @@ -35,6 +35,7 @@ import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalReplacementEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.PreventAllDamageByAllEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -69,7 +70,7 @@ public class BatwingBrume extends CardImpl { this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new BatwingBrumeEffect(), new ManaWasSpentCondition(ColoredManaSymbol.B), "Each player loses 1 life for each attacking creature he or she controls if {B} was spent to cast {this}")); - this.addInfo("Info1", "(Do both if {W}{B} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {W}{B} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/eventide/CankerousThirst.java b/Mage.Sets/src/mage/sets/eventide/CankerousThirst.java index f63cb1393b3..cd138504119 100644 --- a/Mage.Sets/src/mage/sets/eventide/CankerousThirst.java +++ b/Mage.Sets/src/mage/sets/eventide/CankerousThirst.java @@ -31,6 +31,7 @@ import java.util.UUID; import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -65,7 +66,7 @@ public class CankerousThirst extends CardImpl { new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.G)), "If {G} was spent to cast {this}, you may have target creature get +3/+3 until end of turn")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.addInfo("Info1", "(Do both if {B}{G} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {B}{G} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/eventide/InvertTheSkies.java b/Mage.Sets/src/mage/sets/eventide/InvertTheSkies.java index 20c23c87160..42da5ffbb7b 100644 --- a/Mage.Sets/src/mage/sets/eventide/InvertTheSkies.java +++ b/Mage.Sets/src/mage/sets/eventide/InvertTheSkies.java @@ -34,6 +34,7 @@ import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -72,7 +73,7 @@ public class InvertTheSkies extends CardImpl { new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.U)), "and creatures you control gain flying until end of turn if {U} was spent to cast it")); - this.addInfo("Info1", "(Do both if {G}{U} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {G}{U} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/eventide/Moonhold.java b/Mage.Sets/src/mage/sets/eventide/Moonhold.java index b0ff6baac49..513917758c4 100644 --- a/Mage.Sets/src/mage/sets/eventide/Moonhold.java +++ b/Mage.Sets/src/mage/sets/eventide/Moonhold.java @@ -35,6 +35,7 @@ import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; import mage.abilities.effects.ContinuousRuleModifyingEffect; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.InfoEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; @@ -72,7 +73,7 @@ public class Moonhold extends CardImpl { effect2, new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.W)))); this.getSpellAbility().addTarget(new TargetPlayer()); - this.addInfo("Info1", "(Do both if {R}{W} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {R}{W} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/eventide/UnnervingAssault.java b/Mage.Sets/src/mage/sets/eventide/UnnervingAssault.java index d7d7dea31d7..df6aeb823e8 100644 --- a/Mage.Sets/src/mage/sets/eventide/UnnervingAssault.java +++ b/Mage.Sets/src/mage/sets/eventide/UnnervingAssault.java @@ -30,6 +30,7 @@ package mage.sets.eventide; import java.util.UUID; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -71,7 +72,7 @@ public class UnnervingAssault extends CardImpl { this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new BoostAllEffect(1, 0, Duration.EndOfTurn, filter2, false), new ManaWasSpentCondition(ColoredManaSymbol.R), " and creatures you control get +1/0 until end of turn if {R} was spent to cast it")); - this.addInfo("Info1", "(Do both if {U}{R} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {U}{R} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java b/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java index 764fff6aca1..ecb14fc5433 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java @@ -102,7 +102,7 @@ class SummonersEggImprintEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { permanent.imprint(card.getId(), game); - permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card]")); + permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card]"), game); } } } diff --git a/Mage.Sets/src/mage/sets/innistrad/Nevermore.java b/Mage.Sets/src/mage/sets/innistrad/Nevermore.java index f8138cf1442..7cd1f805f58 100644 --- a/Mage.Sets/src/mage/sets/innistrad/Nevermore.java +++ b/Mage.Sets/src/mage/sets/innistrad/Nevermore.java @@ -107,7 +107,7 @@ class NevermoreEffect1 extends OneShotEffect { String cardName = cardChoice.getChoice(); game.informPlayers(permanent.getLogName() + ", named card: [" + cardName + "]"); game.getState().setValue(source.getSourceId().toString(), cardName); - permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]")); + permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]"), game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java b/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java index 63d1d9726d3..1e0088195f7 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java @@ -102,7 +102,7 @@ class HallOfTriumphEffect extends OneShotEffect { if (colorChoice.getChoice() != null) { game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + colorChoice.getChoice()); game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor()); - permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + ""); + permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + "", game); } } return false; diff --git a/Mage.Sets/src/mage/sets/magic2012/AdaptiveAutomaton.java b/Mage.Sets/src/mage/sets/magic2012/AdaptiveAutomaton.java index 328d877f804..dbe6f8d852b 100644 --- a/Mage.Sets/src/mage/sets/magic2012/AdaptiveAutomaton.java +++ b/Mage.Sets/src/mage/sets/magic2012/AdaptiveAutomaton.java @@ -102,7 +102,7 @@ class AdaptiveAutomatonEffect extends OneShotEffect { } game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + typeChoice.getChoice()); game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + ""); + permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + "", game); } return false; } diff --git a/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java b/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java index 4f2e6f0a574..83b84120e58 100644 --- a/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java +++ b/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java @@ -114,7 +114,7 @@ class ChooseCreatureTypeEffect extends OneShotEffect { } game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + typeChoice.getChoice()); game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + ""); + permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + "", game); } return false; } diff --git a/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java b/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java index aa103d157c4..cf29b600682 100644 --- a/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java +++ b/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java @@ -130,7 +130,7 @@ class EliteArcanistImprintEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { permanent.imprint(card.getId(), game); - permanent.addInfo("imprint", new StringBuilder("[Exiled card - ").append(card.getName()).append("]").toString()); + permanent.addInfo("imprint", new StringBuilder("[Exiled card - ").append(card.getName()).append("]").toString(), game); } return true; } diff --git a/Mage.Sets/src/mage/sets/magic2014/ShadowbornApostle.java b/Mage.Sets/src/mage/sets/magic2014/ShadowbornApostle.java index d2832c7cbb7..06c26882ec9 100644 --- a/Mage.Sets/src/mage/sets/magic2014/ShadowbornApostle.java +++ b/Mage.Sets/src/mage/sets/magic2014/ShadowbornApostle.java @@ -34,6 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -70,7 +71,7 @@ public class ShadowbornApostle extends CardImpl { this.toughness = new MageInt(1); // A deck can have any number of cards named Shadowborn Apostle. - this.addInfo("rule", "A deck can have any number of cards named Shadowborn Apostle."); + this.getSpellAbility().addEffect(new InfoEffect("A deck can have any number of cards named Shadowborn Apostle.")); // {B}, Sacrifice six creatures named Shadowborn Apostle: Search your library for a Demon creature and put it onto the battlefield. Then shuffle your library. Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), false, true); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{B}")); diff --git a/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java b/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java index 9e2f984ac02..4c55ee768aa 100644 --- a/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java +++ b/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java @@ -111,7 +111,7 @@ class ObeliskOfUrdEnterBattlefieldEffect extends OneShotEffect { } game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + typeChoice.getChoice()); game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice() + ""); + permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice() + "", game); } return false; } diff --git a/Mage.Sets/src/mage/sets/mirrodin/Duplicant.java b/Mage.Sets/src/mage/sets/mirrodin/Duplicant.java index 012ff4a1d9c..097ad9b5bbb 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/Duplicant.java +++ b/Mage.Sets/src/mage/sets/mirrodin/Duplicant.java @@ -109,7 +109,7 @@ class ExileTargetEffect extends OneShotEffect { if (permanent != null) { if(sourcePermananent != null){ sourcePermananent.imprint(permanent.getId(), game); - sourcePermananent.addInfo("imprint", new StringBuilder("[Imprinted card - ").append(permanent.getName()).append("]").toString()); + sourcePermananent.addInfo("imprint", new StringBuilder("[Imprinted card - ").append(permanent.getName()).append("]").toString(), game); } return permanent.moveToExile(null, null, source.getSourceId(), game); } diff --git a/Mage.Sets/src/mage/sets/mirrodin/ExtraplanarLens.java b/Mage.Sets/src/mage/sets/mirrodin/ExtraplanarLens.java index 26fabac7db1..dad4a998ab9 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/ExtraplanarLens.java +++ b/Mage.Sets/src/mage/sets/mirrodin/ExtraplanarLens.java @@ -109,7 +109,7 @@ class ExtraplanarLensImprintEffect extends OneShotEffect { if (targetLand != null) { targetLand.moveToExile(null, extraplanarLens.getLogName() + " (Imprint)", source.getSourceId(), game); extraplanarLens.imprint(targetLand.getId(), game); - extraplanarLens.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + targetLand.getLogName() + "]")); + extraplanarLens.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + targetLand.getLogName() + "]"), game); } } return true; diff --git a/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java b/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java index 502958450b0..f8a1af20458 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java +++ b/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java @@ -113,7 +113,7 @@ class IsochronScepterImprintEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { permanent.imprint(card.getId(), game); - permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + card.getLogName() + "]")); + permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + card.getLogName() + "]"), game); } } } diff --git a/Mage.Sets/src/mage/sets/mirrodin/SoulFoundry.java b/Mage.Sets/src/mage/sets/mirrodin/SoulFoundry.java index 21843f6da21..f0ff3462b7a 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/SoulFoundry.java +++ b/Mage.Sets/src/mage/sets/mirrodin/SoulFoundry.java @@ -134,7 +134,7 @@ class SoulFoundryImprintEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { permanent.imprint(card.getId(), game); - permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + card.getLogName() + "]")); + permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + card.getLogName() + "]"), game); } } } diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java index b8938d1849d..fd0a2c97d80 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java @@ -110,7 +110,7 @@ class PhyrexianRevokerEffect1 extends OneShotEffect { String cardName = cardChoice.getChoice(); game.informPlayers(permanent.getLogName() + ", named card: [" + cardName + "]"); game.getState().setValue(source.getSourceId().toString(), cardName); - permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]")); + permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]"), game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java b/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java index 9af106fa1fc..7ab55a16d2e 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java @@ -104,7 +104,7 @@ class XenograftEffect extends OneShotEffect { } game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + typeChoice.getChoice()); game.getState().setValue(source.getSourceId() + "_XenograftType", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + ""); + permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + "", game); } return false; } diff --git a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java index a954dadde11..c55118b3909 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java +++ b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java @@ -111,7 +111,7 @@ class VoidstoneGargoyleChooseCardEffect extends OneShotEffect { String cardName = cardChoice.getChoice(); game.informPlayers(permanent.getLogName() + ", named card: [" + cardName + "]"); game.getState().setValue(source.getSourceId().toString(), cardName); - permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]")); + permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]"), game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java index 558c38cd378..4f6b1818eeb 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java @@ -97,7 +97,7 @@ class CurseOfWizardryChooseColorEffect extends OneShotEffect { if (player.choose(Outcome.Detriment, colorChoice, game)) { game.informPlayers(curseOfWizardry.getName() + ": " + player.getName() + " has chosen " + colorChoice.getChoice()); game.getState().setValue(curseOfWizardry.getId() + "_color", colorChoice.getColor()); - curseOfWizardry.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + ""); + curseOfWizardry.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + "", game); } } return false; diff --git a/Mage.Sets/src/mage/sets/shadowmoor/DawnglowInfusion.java b/Mage.Sets/src/mage/sets/shadowmoor/DawnglowInfusion.java index 27723c73509..dd985af2a65 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/DawnglowInfusion.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/DawnglowInfusion.java @@ -36,6 +36,7 @@ import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.constants.ColoredManaSymbol; import mage.constants.ManaType; @@ -62,7 +63,7 @@ public class DawnglowInfusion extends CardImpl { this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new GainLifeEffect(xValue), new ManaWasSpentCondition(ColoredManaSymbol.W), " And X life if {W} was spent to cast it")); - this.addInfo("Info1", "(Do both if {G}{W} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {G}{W} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/Firespout.java b/Mage.Sets/src/mage/sets/shadowmoor/Firespout.java index 61d128aeb59..df34048116f 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/Firespout.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/Firespout.java @@ -31,6 +31,7 @@ import java.util.UUID; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -68,7 +69,7 @@ public class Firespout extends CardImpl { this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new DamageAllEffect(3, filter2), new ManaWasSpentCondition(ColoredManaSymbol.G), " And 3 damage to each creature with flying if {G} was spent to cast it")); - this.addInfo("Info1", "(Do both if {R}{G} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {R}{G} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java b/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java index 0fb2545d21f..288e5cb8cf9 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java @@ -100,7 +100,7 @@ class LureboundScarecrowChooseColorEffect extends OneShotEffect { if (player.choose(Outcome.BoostCreature, colorChoice, game)) { game.informPlayers(sourceStackObject.getName() + ": " + player.getName() + " has chosen " + colorChoice.getChoice()); game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor()); - permanent.addInfo("chosen color", new StringBuilder("Chosen color: ").append(colorChoice.getColor().getDescription()).append("").toString()); + permanent.addInfo("chosen color", new StringBuilder("Chosen color: ").append(colorChoice.getColor().getDescription()).append("").toString(), game); } } return false; diff --git a/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java b/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java index 081984f48ad..db41305754c 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java @@ -104,7 +104,7 @@ class ChooseColorEffect extends OneShotEffect { if (player.choose(Outcome.Neutral, colorChoice, game)) { game.informPlayers(new StringBuilder(permanent.getName()).append(": ").append(player.getName()).append(" has chosen ").append(colorChoice.getChoice()).toString()); game.getState().setValue(source.getSourceId() + "_color", colorChoice.getColor()); - permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + ""); + permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + "", game); } return true; } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/RepelIntruders.java b/Mage.Sets/src/mage/sets/shadowmoor/RepelIntruders.java index 3eaec05a997..f06ae825a65 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/RepelIntruders.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/RepelIntruders.java @@ -32,6 +32,7 @@ import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.ColoredManaSymbol; @@ -64,7 +65,7 @@ public class RepelIntruders extends CardImpl { new CounterTargetEffect(), new ManaWasSpentCondition(ColoredManaSymbol.U), " Counter up to one target creature spell if {U} was spent to cast {this}")); this.getSpellAbility().addTarget(target); - this.addInfo("Info1", "(Do both if {W}{U} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {W}{U} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java b/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java index 408316bce89..5d6cc24269c 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -74,7 +75,7 @@ public class RiversGrasp extends CardImpl { this.getSpellAbility().addTarget(targetCreature); this.getSpellAbility().addTarget(targetPlayer); - this.addInfo("Info1", "(Do both if {U}{B} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {U}{B} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/sorinvstibalt/TorrentOfSouls.java b/Mage.Sets/src/mage/sets/sorinvstibalt/TorrentOfSouls.java index 2ed6e74fd63..344e27d803b 100644 --- a/Mage.Sets/src/mage/sets/sorinvstibalt/TorrentOfSouls.java +++ b/Mage.Sets/src/mage/sets/sorinvstibalt/TorrentOfSouls.java @@ -33,6 +33,7 @@ import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; @@ -76,7 +77,7 @@ public class TorrentOfSouls extends CardImpl { this.getSpellAbility().addTarget(targetCreature); this.getSpellAbility().addTarget(targetPlayer); - this.addInfo("Info1", "(Do both if {B}{R} was spent.)"); + this.getSpellAbility().addEffect(new InfoEffect("(Do both if {B}{R} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/sets/tenth/RelentlessRats.java b/Mage.Sets/src/mage/sets/tenth/RelentlessRats.java index a4f830854d3..c9943bf0cef 100644 --- a/Mage.Sets/src/mage/sets/tenth/RelentlessRats.java +++ b/Mage.Sets/src/mage/sets/tenth/RelentlessRats.java @@ -40,6 +40,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.NamePredicate; @@ -70,7 +71,7 @@ public class RelentlessRats extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RelentlessRatsEffect())); // A deck can have any number of cards named Relentless Rats. - this.addInfo("rule", "A deck can have any number of cards named Relentless Rats."); + this.getSpellAbility().addEffect(new InfoEffect("A deck can have any number of cards named Relentless Rats.")); } public RelentlessRats(final RelentlessRats card) { diff --git a/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java b/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java index da3319687eb..90cc8037047 100644 --- a/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java +++ b/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java @@ -107,7 +107,7 @@ class IonaShieldOfEmeriaChooseColorEffect extends OneShotEffect { if (player.choose(Outcome.Detriment, colorChoice, game)) { game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + colorChoice.getChoice()); game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor()); - permanent.addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + colorChoice.getColor().getDescription())); + permanent.addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + colorChoice.getColor().getDescription()), game); } return true; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/HauntTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/HauntTest.java new file mode 100644 index 00000000000..dc75c058882 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/HauntTest.java @@ -0,0 +1,130 @@ +/* + * 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 org.mage.test.cards.abilities.keywords; + +import mage.cards.Card; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author BetaSteward + */ +public class HauntTest extends CardTestPlayerBase { + + /** + * Blind Hunter - 2WB + * Creature — Bat + * 2/2 + * Flying + * Haunt (When this creature dies, exile it haunting target creature.) + * When Blind Hunter enters the battlefield or the creature it haunts dies, target player loses 2 life and you gain 2 life. + * + */ + + // test that Haunting and Haunted by rules are added to cards + @Test + public void testAddHaunt() { + + addCard(Zone.BATTLEFIELD, playerA, "Blind Hunter", 1); + addCard(Zone.BATTLEFIELD, playerA, "Goblin Roughrider"); + addCard(Zone.HAND, playerA, "Lightning Bolt", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Blind Hunter"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, "Lightning Bolt", 1); + assertExileCount("Blind Hunter", 1); + + boolean found = false; + for (Card card : currentGame.getExile().getAllCards(currentGame)) { + if (card.getName().equals("Blind Hunter")) { + for (String rule : card.getRules(currentGame)) { + if (rule.startsWith("Haunting Goblin Roughrider")) { + found = true; + } + } + } + } + Assert.assertTrue("Couldn't find Haunting rule text displayed for the card", found); + + found = false; + for (Card card : currentGame.getBattlefield().getAllActivePermanents()) { + if (card.getName().equals("Goblin Roughrider")) { + for (String rule : card.getRules(currentGame)) { + if (rule.startsWith("Haunted by Blind Hunter")) { + found = true; + } + } + } + } + Assert.assertTrue("Couldn't find Haunted by rule text displayed for the card", found); + + } + + // test that Haunted by rule is removed from cards (it is only added to permanent) + @Test + public void testRemoveHaunt() { + + addCard(Zone.BATTLEFIELD, playerA, "Blind Hunter", 1); + addCard(Zone.BATTLEFIELD, playerA, "Goblin Roughrider"); + addCard(Zone.HAND, playerA, "Lightning Bolt", 2); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Blind Hunter"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Goblin Roughrider"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, "Lightning Bolt", 2); + assertExileCount("Blind Hunter", 1); + assertGraveyardCount(playerA, "Goblin Roughrider", 1); + + + boolean found = false; + for (Card card : currentGame.getPlayer(playerA.getId()).getGraveyard().getCards(currentGame)) { + if (card.getName().equals("Goblin Roughrider")) { + for (String rule : card.getRules(currentGame)) { + if (rule.startsWith("Haunted by Blind Hunter")) { + found = true; + } + } + } + } + Assert.assertFalse("Found Haunted by rule text displayed for the card", found); + + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/rules/AlternativeCostRuleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/rules/AlternativeCostRuleTest.java index f5f3d2d7d60..2efc8e23a0e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/rules/AlternativeCostRuleTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/rules/AlternativeCostRuleTest.java @@ -22,7 +22,7 @@ public class AlternativeCostRuleTest extends CardTestPlayerBase { Card firewildBorderpost = playerA.getGraveyard().getCards(currentGame).iterator().next(); boolean found = false; - for (String rule : firewildBorderpost.getRules()) { + for (String rule : firewildBorderpost.getRules(currentGame)) { if (rule.startsWith("You may pay")) { found = true; break; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/roe/CastThroughTimeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/roe/CastThroughTimeTest.java index eaf025e30ca..5ded9e333a0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/roe/CastThroughTimeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/roe/CastThroughTimeTest.java @@ -66,7 +66,7 @@ public class CastThroughTimeTest extends CardTestPlayerBase { boolean found = false; for (Card card : currentGame.getPlayer(playerA.getId()).getHand().getCards(currentGame)) { if (card.getName().equals("Lightning Bolt")) { - for (String rule : card.getRules()) { + for (String rule : card.getRules(currentGame)) { if (rule.startsWith("Rebound")) { found = true; } diff --git a/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java b/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java index cf8c00e1f01..e1bd51539fa 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java @@ -65,7 +65,7 @@ public class ChooseColorEffect extends OneShotEffect { } game.informPlayers(new StringBuilder(permanent.getLogName()).append(": ").append(controller.getName()).append(" has chosen ").append(choice.getChoice()).toString()); game.getState().setValue(source.getSourceId() + "_color", choice.getColor()); - permanent.addInfo("chosen color", "Chosen color: " + choice.getColor().getDescription() + ""); + permanent.addInfo("chosen color", "Chosen color: " + choice.getColor().getDescription() + "", game); return true; } return false; diff --git a/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java index db9a3f80798..553e3269e4f 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java @@ -69,7 +69,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect { } game.informPlayers(permanent.getName() + ": " + controller.getName() + " has chosen " + typeChoice.getChoice()); game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice())); + permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); } return false; } diff --git a/Mage/src/mage/abilities/effects/common/ChooseModeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseModeEffect.java index 6b8fb7f930d..4cc8792fbc4 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseModeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseModeEffect.java @@ -82,7 +82,7 @@ public class ChooseModeEffect extends OneShotEffect { if (choice.isChosen()) { game.informPlayers(new StringBuilder(sourcePermanent.getLogName()).append(": ").append(controller.getName()).append(" has chosen ").append(choice.getChoice()).toString()); game.getState().setValue(source.getSourceId() + "_modeChoice", choice.getChoice()); - sourcePermanent.addInfo("_modeChoice", "Chosen mode: " + choice.getChoice() + ""); + sourcePermanent.addInfo("_modeChoice", "Chosen mode: " + choice.getChoice() + "", game); } return true; } diff --git a/Mage/src/mage/abilities/effects/common/DetainAllEffect.java b/Mage/src/mage/abilities/effects/common/DetainAllEffect.java index e820cb2375d..5aa0e28c309 100644 --- a/Mage/src/mage/abilities/effects/common/DetainAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/DetainAllEffect.java @@ -105,7 +105,7 @@ class DetainAllRestrictionEffect extends RestrictionEffect { for(FixedTarget fixedTarget :this.detainedObjects) { Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source)); if (permanent != null) { - permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),"[Detained]"); + permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),"[Detained]", game); } } } @@ -118,7 +118,7 @@ class DetainAllRestrictionEffect extends RestrictionEffect { for(FixedTarget fixedTarget :this.detainedObjects) { Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source)); if (permanent != null) { - permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),""); + permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),"", game); } } return true; diff --git a/Mage/src/mage/abilities/effects/common/DetainTargetEffect.java b/Mage/src/mage/abilities/effects/common/DetainTargetEffect.java index 36aba4cb269..0a55e8dd652 100644 --- a/Mage/src/mage/abilities/effects/common/DetainTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/DetainTargetEffect.java @@ -141,7 +141,7 @@ class DetainRestrictionEffect extends RestrictionEffect { for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),"[Detained]"); + permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),"[Detained]", game); } } } @@ -154,7 +154,7 @@ class DetainRestrictionEffect extends RestrictionEffect { for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),""); + permanent.addInfo(new StringBuilder("detain").append(getId()).toString(),"", game); } } return true; diff --git a/Mage/src/mage/abilities/effects/common/InfoEffect.java b/Mage/src/mage/abilities/effects/common/InfoEffect.java new file mode 100644 index 00000000000..381b33e9c47 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/InfoEffect.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.effects.common; + +import mage.constants.Outcome; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.game.Game; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class InfoEffect extends OneShotEffect { + + public InfoEffect(String text) { + super(Outcome.Neutral); + this.staticText = text; + } + + public InfoEffect(final InfoEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public InfoEffect copy() { + return new InfoEffect(this); + } + +} diff --git a/Mage/src/mage/abilities/effects/common/NameACardEffect.java b/Mage/src/mage/abilities/effects/common/NameACardEffect.java index 77dc429d123..4650bfcbbf1 100644 --- a/Mage/src/mage/abilities/effects/common/NameACardEffect.java +++ b/Mage/src/mage/abilities/effects/common/NameACardEffect.java @@ -96,7 +96,7 @@ public class NameACardEffect extends OneShotEffect { game.informPlayers(sourceObject.getLogName() + ", named card: [" + cardName + "]"); game.getState().setValue(source.getSourceId().toString() + INFO_KEY, cardName); if (sourceObject instanceof Permanent) { - ((Permanent)sourceObject).addInfo(INFO_KEY, CardUtil.addToolTipMarkTags("Named card: " + cardName)); + ((Permanent)sourceObject).addInfo(INFO_KEY, CardUtil.addToolTipMarkTags("Named card: " + cardName), game); } return true; } diff --git a/Mage/src/mage/abilities/keyword/HauntAbility.java b/Mage/src/mage/abilities/keyword/HauntAbility.java index 7f4bd40612c..694d80af8d3 100644 --- a/Mage/src/mage/abilities/keyword/HauntAbility.java +++ b/Mage/src/mage/abilities/keyword/HauntAbility.java @@ -180,8 +180,8 @@ class HauntEffect extends OneShotEffect { // remember the haunted creature String key = new StringBuilder("Haunting_").append(source.getSourceId().toString()).append("_").append(card.getZoneChangeCounter()).toString(); game.getState().setValue(key, new FixedTarget(targetPointer.getFirst(game, source))); - card.addInfo("hauntinfo", new StringBuilder("Haunting ").append(hauntedCreature.getLogName()).toString()); - hauntedCreature.addInfo("hauntinfo", new StringBuilder("Haunted by ").append(card.getLogName()).toString()); + card.addInfo("hauntinfo", new StringBuilder("Haunting ").append(hauntedCreature.getLogName()).toString(), game); + hauntedCreature.addInfo("hauntinfo", new StringBuilder("Haunted by ").append(card.getLogName()).toString(), game); game.informPlayers(new StringBuilder(card.getName()).append(" haunting ").append(hauntedCreature.getLogName()).toString()); } return true; diff --git a/Mage/src/mage/cards/Card.java b/Mage/src/mage/cards/Card.java index aa53894b2e2..50cc60e67c0 100644 --- a/Mage/src/mage/cards/Card.java +++ b/Mage/src/mage/cards/Card.java @@ -40,7 +40,6 @@ import mage.constants.Zone; import mage.counters.Counter; import mage.counters.Counters; import mage.game.Game; -import mage.watchers.Watcher; public interface Card extends MageObject { @@ -51,7 +50,8 @@ public interface Card extends MageObject { void addAbility(Ability ability); void setSpellAbility(SpellAbility ability); SpellAbility getSpellAbility(); - List getRules(); + List getRules(); // gets base card rules + List getRules(Game game); // gets card rules + in game modifications String getExpansionSetCode(); String getTokenSetCode(); void setFaceDown(boolean value); @@ -71,7 +71,7 @@ public interface Card extends MageObject { int getZoneChangeCounter(); void updateZoneChangeCounter(); - void addInfo(String key, String value); + void addInfo(String key, String value, Game game); /** * Moves the card to the specified zone diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 505ffe95035..ca42ecaaf89 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -31,9 +31,7 @@ package mage.cards; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.UUID; import mage.MageObject; import mage.MageObjectImpl; @@ -59,6 +57,7 @@ import static mage.constants.Zone.PICK; import static mage.constants.Zone.STACK; import mage.counters.Counter; import mage.counters.Counters; +import mage.game.CardState; import mage.game.Game; import mage.game.command.Commander; import mage.game.events.GameEvent; @@ -87,7 +86,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { protected boolean flipCard; protected String flipCardName; protected int zoneChangeCounter = 1; - protected Map info; protected boolean usesVariousArt = false; protected boolean splitCard; protected boolean morphCard; @@ -153,10 +151,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { nightCard = card.nightCard; } zoneChangeCounter = card.zoneChangeCounter; - if (card.info != null) { - info = new HashMap<>(); - info.putAll(card.info); - } flipCard = card.flipCard; flipCardName = card.flipCardName; splitCard = card.splitCard; @@ -207,23 +201,39 @@ public abstract class CardImpl extends MageObjectImpl implements Card { return rarity; } + @Override + public void addInfo(String key, String value, Game game) { + game.getState().getCardState(objectId).addInfo(key, value); + } + + protected static final ArrayList rulesError = new ArrayList() {{add("Exception occured in rules generation");}}; + @Override public List getRules() { try { - List rules = abilities.getRules(this.getLogName()); - if (info != null) { - for (String data : info.values()) { - rules.add(data); - } + return abilities.getRules(this.getLogName()); + } catch (Exception e) { + logger.info("Exception in rules generation for card: " + this.getName(), e); + } + return rulesError; + } + + @Override + public List getRules(Game game) { + try { + List rules = getRules(); + CardState state = game.getState().getCardState(objectId); + for (String data : state.getInfo().values()) { + rules.add(data); } +// for (Ability ability: state.getAbilities()) { +// rules.add(ability.getRule()); +// } return rules; } catch (Exception e) { - System.out.println("Exception in rules generation for card: " + this.getName()); - e.printStackTrace(); + logger.error("Exception in rules generation for card: " + this.getName(), e); } - ArrayList rules = new ArrayList<>(); - rules.add("Exception occured in rules generation"); - return rules; + return rulesError; } @Override @@ -621,18 +631,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { // logger.info(name + " set= " + zoneChangeCounter + " " + ((this instanceof Permanent) ? " Permanent":"Card")); } - @Override - public void addInfo(String key, String value) { - if (info == null) { - info = new HashMap<>(); - } - if (value == null || value.isEmpty()) { - info.remove(key); - } else { - info.put(key, value); - } - } - @Override public void build() {} diff --git a/Mage/src/mage/filter/predicate/other/CardTextPredicate.java b/Mage/src/mage/filter/predicate/other/CardTextPredicate.java index f36cfacac90..8f340aacbaa 100644 --- a/Mage/src/mage/filter/predicate/other/CardTextPredicate.java +++ b/Mage/src/mage/filter/predicate/other/CardTextPredicate.java @@ -59,7 +59,7 @@ public class CardTextPredicate implements Predicate { boolean found = false; if (!token.isEmpty()) { // then try to find in rules - for (String rule : input.getRules()) { + for (String rule : input.getRules(game)) { if (rule.toLowerCase().contains(token)) { found = true; break; diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 5ad9148bc78..e8f3f50d36f 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -63,6 +63,7 @@ import mage.constants.Zone; import mage.counters.Counter; import mage.counters.CounterType; import mage.counters.Counters; +import mage.game.CardState; import mage.game.Game; import mage.game.events.DamageCreatureEvent; import mage.game.events.DamagePlaneswalkerEvent; @@ -110,7 +111,8 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { protected Counters counters; protected List markedDamage; protected int timesLoyaltyUsed = 0; - + protected Map info; + private static final List emptyList = Collections.unmodifiableList(new ArrayList()); public PermanentImpl(UUID ownerId, UUID controllerId, String name) { @@ -154,6 +156,10 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { markedDamage.add(counter.copy()); } } + if (permanent.info != null) { + info = new HashMap<>(); + info.putAll(permanent.info); + } this.counters = permanent.counters.copy(); this.attachedTo = permanent.attachedTo; this.minBlockedBy = permanent.minBlockedBy; @@ -209,6 +215,33 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { return sb.toString(); } + @Override + public void addInfo(String key, String value, Game game) { + if (info == null) { + info = new HashMap<>(); + } + if (value == null || value.isEmpty()) { + info.remove(key); + } else { + info.put(key, value); + } + } + + @Override + public List getRules(Game game) { + try { + List rules = getRules(); + if (info != null) { + for (String data : info.values()) { + rules.add(data); + } + } + return rules; + } catch (Exception e) { + return rulesError; + } + } + @Override @Deprecated public void addAbility(Ability ability) { diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 472f84daa03..23ed93bdae9 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -701,6 +701,11 @@ public class Spell implements StackObject, Card { return card.getRules(); } + @Override + public List getRules(Game game) { + return card.getRules(game); + } + @Override public String getExpansionSetCode() { return card.getExpansionSetCode(); @@ -900,7 +905,7 @@ public class Spell implements StackObject, Card { } @Override - public void addInfo(String key, String value) { + public void addInfo(String key, String value, Game game) { // do nothing } diff --git a/Mage/src/mage/watchers/common/CommanderCombatDamageWatcher.java b/Mage/src/mage/watchers/common/CommanderCombatDamageWatcher.java index 44515342a02..f0a0f5c9aee 100644 --- a/Mage/src/mage/watchers/common/CommanderCombatDamageWatcher.java +++ b/Mage/src/mage/watchers/common/CommanderCombatDamageWatcher.java @@ -108,21 +108,21 @@ public class CommanderCombatDamageWatcher extends Watcher { if (castCount != null) { sb.append(" ").append(castCount).append(castCount.intValue() == 1 ? " time":" times").append(" casted from the command zone."); } - this.addInfo(object, "Commander",sb.toString()); + this.addInfo(object, "Commander",sb.toString(), game); for (Map.Entry entry : damageToPlayer.entrySet()) { Player damagedPlayer = game.getPlayer(entry.getKey()); sb.setLength(0); sb.append("Commander did ").append(entry.getValue()).append(" combat damage to player ").append(damagedPlayer.getName()).append("."); - this.addInfo(object, new StringBuilder("Commander").append(entry.getKey()).toString(),sb.toString()); + this.addInfo(object, new StringBuilder("Commander").append(entry.getKey()).toString(),sb.toString(), game); } } } - private void addInfo(MageObject object, String key, String value) { + private void addInfo(MageObject object, String key, String value, Game game) { if (object instanceof Card) { - ((Card) object).addInfo(key, value); + ((Card) object).addInfo(key, value, game); } else if (object instanceof Permanent) { - ((Permanent) object).addInfo(key, value); + ((Permanent) object).addInfo(key, value, game); } } From 3a8b7cc281bd49e28e932c740e39baee21f1d09a Mon Sep 17 00:00:00 2001 From: fireshoes Date: Tue, 10 Mar 2015 17:06:45 -0500 Subject: [PATCH 11/12] [DTK] Added Sarkhan's Triumph, Herdchaser Dragon, and Rending Volley. Updated mtg-cards-data.txt for 3/10. --- .../dragonsoftarkir/HerdchaserDragon.java | 87 +++++++++++++++++++ .../sets/dragonsoftarkir/RendingVolley.java | 84 ++++++++++++++++++ .../sets/dragonsoftarkir/SarkhansTriumph.java | 67 ++++++++++++++ Utils/mtg-cards-data.txt | 4 + 4 files changed, 242 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/HerdchaserDragon.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/RendingVolley.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhansTriumph.java diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/HerdchaserDragon.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/HerdchaserDragon.java new file mode 100644 index 00000000000..5fd2eebcf30 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/HerdchaserDragon.java @@ -0,0 +1,87 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.MorphAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author fireshoes + */ +public class HerdchaserDragon extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + static { + filter.add(new AnotherPredicate()); + filter.add(new SubtypePredicate("Dragon")); + } + + public HerdchaserDragon(UUID ownerId) { + super(ownerId, 190, "Herdchaser Dragon", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{5}{G}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Megamorph {5}{G}{G} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{G}{G}"), true)); + + // When Herdchaser Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. + this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); + } + + public HerdchaserDragon(final HerdchaserDragon card) { + super(card); + } + + @Override + public HerdchaserDragon copy() { + return new HerdchaserDragon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/RendingVolley.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/RendingVolley.java new file mode 100644 index 00000000000..c72b48506c1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/RendingVolley.java @@ -0,0 +1,84 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CantBeCounteredSourceEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class RendingVolley extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("white or blue creature"); + + static { + filter.add(Predicates.or( + new ColorPredicate(ObjectColor.WHITE), + new ColorPredicate(ObjectColor.BLUE))); + } + + public RendingVolley(UUID ownerId) { + super(ownerId, 150, "Rending Volley", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "DTK"; + + // Rending Volley can't be countered by spells or abilities. + Effect effect = new CantBeCounteredSourceEffect(); + effect.setText("{this} can't be countered by spells or abilities"); + Ability ability = new SimpleStaticAbility(Zone.STACK,effect); + ability.setRuleAtTheTop(true); + this.addAbility(ability); + + // Rending Volley deals 4 damage to target white or blue creature. + this.getSpellAbility().addEffect(new DamageTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public RendingVolley(final RendingVolley card) { + super(card); + } + + @Override + public RendingVolley copy() { + return new RendingVolley(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhansTriumph.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhansTriumph.java new file mode 100644 index 00000000000..80b0da4c242 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhansTriumph.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.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author fireshoes + */ +public class SarkhansTriumph extends CardImpl { + + private static final FilterCreatureCard filter = new FilterCreatureCard("Dragon creature card"); + + static { + filter.add(new SubtypePredicate("Dragon")); + } + + public SarkhansTriumph(UUID ownerId) { + super(ownerId, 154, "Sarkhan's Triumph", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{R}"); + this.expansionSetCode = "DTK"; + + // Search your library for a Dragon creature card, reveal it, put it into your hand, then shuffle your library. + this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true)); + } + + public SarkhansTriumph(final SarkhansTriumph card) { + super(card); + } + + @Override + public SarkhansTriumph copy() { + return new SarkhansTriumph(this); + } +} diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 7745d3d56d3..b62acf6b675 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25673,6 +25673,7 @@ Artful Maneuver|Dragons of Tarkir|4|C|{1}{W}|Instant|||Target creature gets +2/+ Aven Sunstriker|Dragons of Tarkir|5|U|{1}{W}{W}|Creature - Bird Warrior|1|1|Flying$Double strike (This creature deals both first-strike and regular combat damage.)$Megamorph {4}{W} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Hidden Dragonslayer|Dragons of Tarkir|23|R|{1}{W}|Creature - Human Warrior|2|1|Lifelink$Megamorph {2}{W} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Hidden Dragonslayer is turned face up, destroy target creature with power 4 or greater an opponent controls.| Ojutai Exemplars|Dragons of Tarkir|27|M|{2}{W}{W}|Creature - Human Monk|4|4|Whenever you cast a noncreature spell, choose one - Tap target creature; Ojutai Exemplars gain first strike and lifelink until end of turn; or Exile Ojutai Exemplars, then return it to the battlefield tapped under its owner's control.| +Orator of Ojutai|Dragons of Tarkir|29|U|{1}{W}|Creature - Bird Monk|0|4|Defneder, flying$As an additional cost to cast Orator of Ojutai, you may reveal a Dragon card from your hand.$When Orator of Ojutai enters the battlefield, if you revealed a Dragon card or controlled a Dragon as you cast Orator of Ojutai, draw a card.| Profound Journey|Dragons of Tarkir|30|R|{5}{W}{W}|Sorcery|||Return target permanent card from your graveyard to the battlefield.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| Radiant Purge|Dragons of Tarkir|31|R|{1}{W}|Instant|||Exile target multicolored creature or multicolored enchantment.| Sandcrafter Mage|Dragons of Tarkir|33|C|{2}{W}|Creature - Human Wizard|2|2|When Sandcrafter Mage enters the battlefield, bolster 1 (Choose a creature with the least toughness among the creatures you control and put a +1/+1 counter on it.)| @@ -25710,7 +25711,9 @@ Dragon Tempest|Dragons of Tarkir|136|R|{1}{R}|Enchantment|||Whenever a creature Dragon Whisperer|Dragons of Tarkir|137|M|{R}{R}|Creature - Human Shaman|2|2|{R}: Dragon Whisperer gains flying until end of turn.${1}{R}: Dragon Whisperer get +1/+0 until end of turn$ - {4}{R}{R}: Put a 4/4 red Dragon creature token with flying onto the battlefield. Activate this ability only if creatures you control have total power 8 or greater.| Dragonlord's Servant|Dragons of Tarkir|138|U|{1}{R}|Creature - Goblin Shaman|1|3|Dragon spells you cast cost {1} less to cast.| Lightning Berserker|Dragons of Tarkir|146|U|{R}|Creature - Human Berserker|1|1|{R}: Lightning Berserker gets +1/+0 until end of turn.$Dash {R} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| +Rending Volley|Dragons of Tarkir|150|U|{R}|Instant|||Rending Volley can't be countered by spells or abilities.$Rending Volley deals 4 damage to target white or blue creature.| Roast|Dragons of Tarkir|151|U|{1}{R}|Sorcery|||Roast deals 5 damage to target creature without flying.| +Sarkhan's Triumph|Dragons of Tarkir|154|U|{2}{R}|Instant|||Search your library for a Dragon creature card, reveal it, put it into your hand, then shuffle your library.| Sprinting Warbrute|Dragons of Tarkir|157|C|{4}{R}|Creature - Ogre Berserker|5|4|Sprinting Warbrute attacks each turn if able.$Dash {3}{R} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| Stormcrag Elemental|Dragons of Tarkir|158|U|{5}{R}|Creature - Elemental|5|5|Trample$Megamorph {4}{R}{R} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Stormwing Dragon|Dragons of Tarkir|159|U|{5}{R}|Creature - Dragon|3|3|Flying, first strike$Megamorph {5}{R}{R} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Stormwing Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.| @@ -25726,6 +25729,7 @@ Den Protector|Dragons of Tarkir|181|R|{1}{G}|Creature - Human Warrior|2|1|Creatu Display of Dominance|Dragons of Tarkir|182|U|{1}{G}|Instant|||Choose one - Destroy target blue or black noncreature permanent; or Permanents you control can't be the targets of blue or black spells your opponents control this turn.| Epic Confrontation|Dragons of Tarkir|185|C|{1}{G}|Sorcery|||Target creature you control gets +1/+2 until end of turn. It fights target creature you don't control.| Foe-Razer Regent|Dragons of Tarkir|187|R|{5}{G}{G}|Creature - Dragon|4|5|Flying$When Foe-Razer Regent enters the battlefield, you may have it fight target creature you don't control.$Whenever a creature you control fights, put two +1/+1 counters on it at the beginning of the next end step.| +Herdchaser Dragon|Dragons of Tarkir|190|U|{5}{G}|Creature - Dragon|3|3|Flying, trample$Megamorph {5}{G}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it)$When Herdchaser Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.| Salt Road Ambushers|Dragons of Tarkir|198|U|{3}{G}|Creature - Hound Warrior|3|3|Whenever another permanent you control is turned face up, if it's a creature, put two +1/+1 counters on it.$Megamorph {3}{G}{G} You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Scaleguard Sentinels|Dragons of Tarkir|201|U|{G}{G}|Creature - Human Soldier|2|3|As an additional cost to cast Scaleguard Sentinels, you may reveal a Dragon card from your hand.$Scaleguard Sentinels enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast Scaleguard Sentinels.| Shaman of Forgotten Ways|Dragons of Tarkir|204|M|{2}G}|Creature - Human Shaman| 2|3|{T}:Add two mana in any combination of colors to your mana pool. Spend this mana only to cast creature spells.$Formidable - {9}{G}{G},{T}:Each player's life total becomes the number of creatures he or she controls. Acitave the ability only if creatures you control have total power 8 or greater.| From 3ee6df9a3e87bbe90d311ae8b6aa63aa8a368c05 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 10 Mar 2015 23:53:57 +0100 Subject: [PATCH 12/12] * Cylian Elf - Fixed missing creature card type attribute. --- Mage.Sets/src/mage/sets/shardsofalara/CylianElf.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/shardsofalara/CylianElf.java b/Mage.Sets/src/mage/sets/shardsofalara/CylianElf.java index bfa734c74b7..131d59e91cc 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/CylianElf.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/CylianElf.java @@ -41,11 +41,11 @@ import mage.cards.CardImpl; public class CylianElf extends CardImpl { public CylianElf (UUID ownerId) { - super(ownerId, 127, "Cylian Elf", Rarity.COMMON, new CardType[]{}, "{1}{G}"); + super(ownerId, 127, "Cylian Elf", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.expansionSetCode = "ALA"; this.subtype.add("Elf"); this.subtype.add("Scout"); - this.color.setGreen(true); + this.power = new MageInt(2); this.toughness = new MageInt(2); }