From 9810d7f3cf8ce7c3688e541ecd168c358b91fb86 Mon Sep 17 00:00:00 2001 From: mnapoleon Date: Tue, 17 Mar 2015 14:03:35 -0400 Subject: [PATCH 01/13] Implemented Morningtide: Roar of the Crowd --- .../mage/sets/morningtide/RoarOfTheCrowd.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java diff --git a/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java b/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java new file mode 100644 index 00000000000..6f45c8f7503 --- /dev/null +++ b/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java @@ -0,0 +1,113 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.morningtide; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageAllControlledTargetEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.repository.CardRepository; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class RoarOfTheCrowd extends CardImpl { + + public RoarOfTheCrowd(UUID ownerId) { + super(ownerId, 100, "Roar of the Crowd", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{3}{R}"); + this.expansionSetCode = "MOR"; + + // Choose a creature type. Roar of the Crowd deals damage to target creature or player equal to the number of permanents you control of the chosen type. + + TargetCreatureOrPlayer target = new TargetCreatureOrPlayer(); + this.getSpellAbility().addTarget(target); + this.getSpellAbility().addEffect(new RoarOfTheCrowdEffect()); + } + + public RoarOfTheCrowd(final RoarOfTheCrowd card) { + super(card); + } + + @Override + public RoarOfTheCrowd copy() { + return new RoarOfTheCrowd(this); + } +} + +class RoarOfTheCrowdEffect extends OneShotEffect { + + RoarOfTheCrowdEffect() { + super(Outcome.LoseLife); + this.staticText = "Choose a creature type. Roar of the Crowd deals damage to target creature or player equal to the number of permanents you control of the chosen type."; + } + + RoarOfTheCrowdEffect(final RoarOfTheCrowdEffect effect) { + super(effect); + } + + @Override + public RoarOfTheCrowdEffect copy() { + return new RoarOfTheCrowdEffect(this); + } + + @Override public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + Choice typeChoice = new ChoiceImpl(true); + typeChoice.setMessage("Choose a creature type:"); + typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + while (!player.choose(Outcome.LoseLife, typeChoice, game)) { + if (!player.isInGame()) { + return false; + } + } + FilterControlledPermanent filter = new FilterControlledPermanent(); + filter.add(new SubtypePredicate(typeChoice.getChoice())); + PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter); + DamageTargetEffect effect = new DamageTargetEffect(count); + + return effect.apply(game, source); + } + return false; + } +} \ No newline at end of file From 30025db332f9b06cb4f33f2fb8414229d7b097ba Mon Sep 17 00:00:00 2001 From: mnapoleon Date: Tue, 17 Mar 2015 14:05:55 -0400 Subject: [PATCH 02/13] removed unused imports and refactored a bit --- Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java b/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java index 6f45c8f7503..7cb24d5c101 100644 --- a/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java +++ b/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java @@ -31,9 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DamageAllControlledTargetEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; import mage.cards.repository.CardRepository; import mage.choices.Choice; @@ -58,7 +56,6 @@ public class RoarOfTheCrowd extends CardImpl { this.expansionSetCode = "MOR"; // Choose a creature type. Roar of the Crowd deals damage to target creature or player equal to the number of permanents you control of the chosen type. - TargetCreatureOrPlayer target = new TargetCreatureOrPlayer(); this.getSpellAbility().addTarget(target); this.getSpellAbility().addEffect(new RoarOfTheCrowdEffect()); @@ -103,10 +100,7 @@ class RoarOfTheCrowdEffect extends OneShotEffect { } FilterControlledPermanent filter = new FilterControlledPermanent(); filter.add(new SubtypePredicate(typeChoice.getChoice())); - PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter); - DamageTargetEffect effect = new DamageTargetEffect(count); - - return effect.apply(game, source); + return new DamageTargetEffect(new PermanentsOnBattlefieldCount(filter)).apply(game, source); } return false; } From fccea4f8a3ce3eed94f77fba3a8db2fe08bdc985 Mon Sep 17 00:00:00 2001 From: Michael Napoleon Date: Tue, 17 Mar 2015 17:21:38 -0400 Subject: [PATCH 03/13] used {this} instead of card name --- Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java b/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java index 7cb24d5c101..fa9e9d70501 100644 --- a/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java +++ b/Mage.Sets/src/mage/sets/morningtide/RoarOfTheCrowd.java @@ -75,7 +75,7 @@ class RoarOfTheCrowdEffect extends OneShotEffect { RoarOfTheCrowdEffect() { super(Outcome.LoseLife); - this.staticText = "Choose a creature type. Roar of the Crowd deals damage to target creature or player equal to the number of permanents you control of the chosen type."; + this.staticText = "Choose a creature type. {this} deals damage to target creature or player equal to the number of permanents you control of the chosen type."; } RoarOfTheCrowdEffect(final RoarOfTheCrowdEffect effect) { From 016737c73a5e0f1b0a43576a6c74cfef6869f5bd Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 00:33:39 +0100 Subject: [PATCH 04/13] [DTK] Added 12 black cards. --- .../avacynrestored/HomicidalSeclusion.java | 6 - .../sets/dragonsoftarkir/AmbuscadeShaman.java | 118 +++++++++++++++++ .../sets/dragonsoftarkir/BloodChinRager.java | 73 +++++++++++ .../sets/dragonsoftarkir/ButchersGlee.java | 73 +++++++++++ .../sets/dragonsoftarkir/CoatWithVenom.java | 69 ++++++++++ .../mage/sets/dragonsoftarkir/Corpseweft.java | 121 +++++++++++++++++ .../dragonsoftarkir/DeadlyWanderings.java | 79 +++++++++++ .../src/mage/sets/dragonsoftarkir/Defeat.java | 69 ++++++++++ .../dragonsoftarkir/DutifulAttendant.java | 76 +++++++++++ .../mage/sets/dragonsoftarkir/Flatten.java | 61 +++++++++ .../sets/dragonsoftarkir/FoulRenewal.java | 106 +++++++++++++++ .../dragonsoftarkir/FoulTongueInvocation.java | 123 ++++++++++++++++++ .../dragonsoftarkir/FoulTongueShriek.java | 98 ++++++++++++++ .../costs/common/ExileFromGraveCost.java | 10 +- .../combat/CantBeBlockedByOneAllEffect.java | 2 +- 15 files changed, 1072 insertions(+), 12 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/AmbuscadeShaman.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/BloodChinRager.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/ButchersGlee.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/CoatWithVenom.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/Corpseweft.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/DeadlyWanderings.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/Defeat.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/DutifulAttendant.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/Flatten.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueInvocation.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueShriek.java diff --git a/Mage.Sets/src/mage/sets/avacynrestored/HomicidalSeclusion.java b/Mage.Sets/src/mage/sets/avacynrestored/HomicidalSeclusion.java index f0b0ffe44ea..e335e302a94 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/HomicidalSeclusion.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/HomicidalSeclusion.java @@ -54,8 +54,6 @@ public class HomicidalSeclusion extends CardImpl { super(ownerId, 108, "Homicidal Seclusion", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}"); this.expansionSetCode = "AVR"; - this.color.setBlack(true); - // As long as you control exactly one creature, that creature gets +3/+1 and has lifelink. ContinuousEffect boostEffect = new BoostControlledEffect(3, 1, Duration.WhileOnBattlefield); Effect effect = new ConditionalContinuousEffect(boostEffect, new OneControlledCreatureCondition(), rule); @@ -64,10 +62,6 @@ public class HomicidalSeclusion extends CardImpl { effect = new ConditionalContinuousEffect(lifelinkEffect, new OneControlledCreatureCondition(), "and has lifelink"); ability.addEffect(effect); this.addAbility(ability); - - - - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } public HomicidalSeclusion(final HomicidalSeclusion card) { diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/AmbuscadeShaman.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/AmbuscadeShaman.java new file mode 100644 index 00000000000..e372c5a391e --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/AmbuscadeShaman.java @@ -0,0 +1,118 @@ +/* + * 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.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.DashAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class AmbuscadeShaman extends CardImpl { + + public AmbuscadeShaman(UUID ownerId) { + super(ownerId, 87, "Ambuscade Shaman", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Orc"); + this.subtype.add("Shaman"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Ambuscade Shaman or another creature enters the battlefield under your control, that creature gets +2/+2 until end of turn. + Effect effect = new BoostTargetEffect(2,2, Duration.EndOfTurn); + effect.setText("that creature gets +2/+2 until end of turn"); + this.addAbility(new AmbuscadeShamanTriggeredAbility(effect)); + + // Dash {3}{B} (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.)); + this.addAbility(new DashAbility(this, "{3}{B}")); + + } + + public AmbuscadeShaman(final AmbuscadeShaman card) { + super(card); + } + + @Override + public AmbuscadeShaman copy() { + return new AmbuscadeShaman(this); + } +} + +class AmbuscadeShamanTriggeredAbility extends TriggeredAbilityImpl { + + AmbuscadeShamanTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + AmbuscadeShamanTriggeredAbility(final AmbuscadeShamanTriggeredAbility ability) { + super(ability); + } + + @Override + public AmbuscadeShamanTriggeredAbility copy() { + return new AmbuscadeShamanTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + UUID targetId = event.getTargetId(); + Permanent permanent = game.getPermanent(targetId); + if (permanent.getControllerId().equals(this.controllerId) + && permanent.getCardType().contains(CardType.CREATURE)) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever {this} or another creature enters the battlefield under your control, that creature gets +2/+2 until end of turn."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/BloodChinRager.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/BloodChinRager.java new file mode 100644 index 00000000000..50aa41cbf0c --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/BloodChinRager.java @@ -0,0 +1,73 @@ +/* + * 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.AttacksTriggeredAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByOneAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LevelX2 + */ +public class BloodChinRager extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Warrior","Warrior creature you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public BloodChinRager(UUID ownerId) { + super(ownerId, 89, "Blood-Chin Rager", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Human"); + this.subtype.add("Warrior"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Blood-Chin Rager attacks, each Warrior creature you control can't be blocked this turn except by two or more creatures. + this.addAbility(new AttacksTriggeredAbility(new CantBeBlockedByOneAllEffect(2, filter), false)); + } + + public BloodChinRager(final BloodChinRager card) { + super(card); + } + + @Override + public BloodChinRager copy() { + return new BloodChinRager(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ButchersGlee.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ButchersGlee.java new file mode 100644 index 00000000000..b32fa7fad6d --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ButchersGlee.java @@ -0,0 +1,73 @@ +/* + * 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.Effect; +import mage.abilities.effects.common.RegenerateTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class ButchersGlee extends CardImpl { + + public ButchersGlee(UUID ownerId) { + super(ownerId, 90, "Butcher's Glee", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{B}"); + this.expansionSetCode = "DTK"; + + // Target creature gets +3/+0 and gains lifelink until end of turn. Regenerate it. + Effect effect = new BoostTargetEffect(3, 0, Duration.EndOfTurn); + effect.setText("Target creature gets +3/+0"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains lifelink until end of turn"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + effect = new RegenerateTargetEffect(); + effect.setText("Regenerate it"); + this.getSpellAbility().addEffect(effect); + } + + public ButchersGlee(final ButchersGlee card) { + super(card); + } + + @Override + public ButchersGlee copy() { + return new ButchersGlee(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/CoatWithVenom.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/CoatWithVenom.java new file mode 100644 index 00000000000..982977d4579 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/CoatWithVenom.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.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +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.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class CoatWithVenom extends CardImpl { + + public CoatWithVenom(UUID ownerId) { + super(ownerId, 91, "Coat with Venom", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{B}"); + this.expansionSetCode = "DTK"; + + // Target creature gets +1/+2 and gains deathtouch until end of turn. + Effect effect = new BoostTargetEffect(1, 2, Duration.EndOfTurn); + effect.setText("Target creature gets +1/+2"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains deathtouch until end of turn"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public CoatWithVenom(final CoatWithVenom card) { + super(card); + } + + @Override + public CoatWithVenom copy() { + return new CoatWithVenom(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Corpseweft.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Corpseweft.java new file mode 100644 index 00000000000..70e28007825 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Corpseweft.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.game.permanent.token.Token; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LevelX2 + */ +public class Corpseweft extends CardImpl { + + public Corpseweft(UUID ownerId) { + super(ownerId, 92, "Corpseweft", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + this.expansionSetCode = "DTK"; + + // {1}{B}, Exile one or more creature cards from your graveyard: Put an X/X black Zombie Horror creature token onto the battlefield tapped, where X is twice the number of cards exiled this way. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CorpseweftEffect(), new ManaCostsImpl("{1}{B}")); + ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(1, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard")))); + this.addAbility(ability); + } + + public Corpseweft(final Corpseweft card) { + super(card); + } + + @Override + public Corpseweft copy() { + return new Corpseweft(this); + } +} + +class CorpseweftEffect extends OneShotEffect { + + public CorpseweftEffect() { + super(Outcome.Benefit); + this.staticText = "Put an X/X black Zombie Horror creature token onto the battlefield tapped, where X is twice the number of cards exiled this way"; + } + + public CorpseweftEffect(final CorpseweftEffect effect) { + super(effect); + } + + @Override + public CorpseweftEffect copy() { + return new CorpseweftEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + int amount = 0; + for (Cost cost: source.getCosts()) { + if (cost instanceof ExileFromGraveCost) { + amount = ((ExileFromGraveCost) cost).getExiledCards().size() *2; + new CreateTokenEffect(new CorpseweftZombieToken(amount, amount), 1, true, false).apply(game, source); + } + } + if (amount > 0) { + + } + } + return false; + } +} + +class CorpseweftZombieToken extends Token { + + public CorpseweftZombieToken(int power, int toughness) { + super("Zombie Horror", "an X/X black Zombie Horror creature token onto the battlefield tapped, where X is twice the number of cards exiled this way"); + cardType.add(CardType.CREATURE); + subtype.add("Zombie"); + subtype.add("Horror"); + this.power = new MageInt(power); + this.toughness = new MageInt(toughness); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DeadlyWanderings.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeadlyWanderings.java new file mode 100644 index 00000000000..dbedd9f34b6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeadlyWanderings.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.OneControlledCreatureCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class DeadlyWanderings extends CardImpl { + + public DeadlyWanderings(UUID ownerId) { + super(ownerId, 94, "Deadly Wanderings", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); + this.expansionSetCode = "DTK"; + + // As long as you control exactly one creature, that creature gets +2/+0 and has deathtouch and lifelink. + ContinuousEffect boostEffect = new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield); + Effect effect = new ConditionalContinuousEffect(boostEffect, new OneControlledCreatureCondition(), + "As long as you control exactly one creature, that creature gets +2/+0"); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); + ContinuousEffect deathtouchEffect = new GainAbilityControlledEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield); + effect = new ConditionalContinuousEffect(deathtouchEffect, new OneControlledCreatureCondition(), "and has deathtouch"); + ability.addEffect(effect); + ContinuousEffect lifelinkEffect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield); + effect = new ConditionalContinuousEffect(lifelinkEffect, new OneControlledCreatureCondition(), "and lifelink"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public DeadlyWanderings(final DeadlyWanderings card) { + super(card); + } + + @Override + public DeadlyWanderings copy() { + return new DeadlyWanderings(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Defeat.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Defeat.java new file mode 100644 index 00000000000..e744d377dd8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Defeat.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.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.Filter; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class Defeat extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power 2 or less"); + + static { + filter.add(new PowerPredicate(Filter.ComparisonType.LessThan, 3)); + } + + public Defeat(UUID ownerId) { + super(ownerId, 97, "Defeat", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{B}"); + this.expansionSetCode = "DTK"; + + // Destroy target creature with power 2 or less. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public Defeat(final Defeat card) { + super(card); + } + + @Override + public Defeat copy() { + return new Defeat(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DutifulAttendant.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DutifulAttendant.java new file mode 100644 index 00000000000..aefec1eb7f8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DutifulAttendant.java @@ -0,0 +1,76 @@ +/* + * 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.DiesTriggeredAbility; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.AnotherCardPredicate; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LevelX2 + */ +public class DutifulAttendant extends CardImpl { + + private static final FilterCreatureCard filter = new FilterCreatureCard("another creature card from your graveyard"); + + static { + filter.add(new AnotherCardPredicate()); + } + + public DutifulAttendant(UUID ownerId) { + super(ownerId, 99, "Dutiful Attendant", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Human"); + this.subtype.add("Warrior"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // When Dutiful Ateendant dies, return another target creature card from your graveyard to your hand. + Ability ability = new DiesTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(ability); + } + + public DutifulAttendant(final DutifulAttendant card) { + super(card); + } + + @Override + public DutifulAttendant copy() { + return new DutifulAttendant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Flatten.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Flatten.java new file mode 100644 index 00000000000..775a7f2a2c1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Flatten.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.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class Flatten extends CardImpl { + + public Flatten(UUID ownerId) { + super(ownerId, 100, "Flatten", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{B}"); + this.expansionSetCode = "DTK"; + + // Target creature gets -4/-4 until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(-4, -4, Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public Flatten(final Flatten card) { + super(card); + } + + @Override + public Flatten copy() { + return new Flatten(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java new file mode 100644 index 00000000000..6d702534afe --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulRenewal.java @@ -0,0 +1,106 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +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.common.FilterCreatureCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class FoulRenewal extends CardImpl { + + public FoulRenewal(UUID ownerId) { + super(ownerId, 101, "Foul Renewal", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{B}"); + this.expansionSetCode = "DTK"; + + // Return target creature card from your graveyard to your hand. Target creature gets -X/-X until end of turn, where X is the toughness of the card returned this way. + this.getSpellAbility().addEffect(new FoulRenewalEffect()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public FoulRenewal(final FoulRenewal card) { + super(card); + } + + @Override + public FoulRenewal copy() { + return new FoulRenewal(this); + } +} + +class FoulRenewalEffect extends OneShotEffect { + + public FoulRenewalEffect() { + super(Outcome.Benefit); + this.staticText = "Return target creature card from your graveyard to your hand. Target creature gets -X/-X until end of turn, where X is the toughness of the card returned this way"; + } + + public FoulRenewalEffect(final FoulRenewalEffect effect) { + super(effect); + } + + @Override + public FoulRenewalEffect copy() { + return new FoulRenewalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Card card = game.getCard(targetPointer.getFirst(game, source)); + if (card != null) { + controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + ContinuousEffect effect = new BoostTargetEffect(-4,-4, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(source.getTargets().get(1).getFirstTarget())); + game.addEffect(effect, source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueInvocation.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueInvocation.java new file mode 100644 index 00000000000..5820d2ba07d --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueInvocation.java @@ -0,0 +1,123 @@ +/* + * 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.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.RevealTargetFromHandCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher; + +/** + * + * @author LevelX2 + */ +public class FoulTongueInvocation extends CardImpl { + + private static final FilterCreatureCard filter = new FilterCreatureCard("a Dragon card from your hand (you don't have to)"); + + static { + filter.add(new SubtypePredicate("Dragon")); + } + + public FoulTongueInvocation(UUID ownerId) { + super(ownerId, 102, "Foul-Tongue Invocation", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{B}"); + this.expansionSetCode = "DTK"; + + // As an additional cost to cast Foul-Tongue Invocation, you may reveal a Dragon card from your hand. + this.getSpellAbility().addEffect(new InfoEffect("As an additional cost to cast {this}, you may reveal a Dragon card from your hand")); + + + // Target player sacrifices a creature. If you revealed a Dragon card or controlled a Dragon as you cast Foul-Tongue Invocation, you gain 4 life. + this.getSpellAbility().addTarget(new TargetPlayer()); + this.getSpellAbility().addEffect(new SacrificeEffect(new FilterCreaturePermanent(), 1, "target player")); + this.getSpellAbility().addEffect(new FoulTongueInvocationEffect()); + this.getSpellAbility().addWatcher(new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); + } + + public FoulTongueInvocation(final FoulTongueInvocation card) { + super(card); + } + + @Override + public FoulTongueInvocation copy() { + return new FoulTongueInvocation(this); + } +} + +class FoulTongueInvocationEffect extends OneShotEffect { + + public FoulTongueInvocationEffect() { + super(Outcome.Benefit); + this.staticText = "If you revealed a Dragon card or controlled a Dragon as you cast {this}, you gain 4 life"; + } + + public FoulTongueInvocationEffect(final FoulTongueInvocationEffect effect) { + super(effect); + } + + @Override + public FoulTongueInvocationEffect copy() { + return new FoulTongueInvocationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = (DragonOnTheBattlefieldWhileSpellWasCastWatcher) game.getState().getWatchers().get("DragonOnTheBattlefieldWhileSpellWasCastWatcher"); + boolean condition = watcher != null && watcher.castWithConditionTrue(source.getId()); + if (!condition) { + for (Cost cost: source.getCosts()) { + if (cost instanceof RevealTargetFromHandCost) { + condition = ((RevealTargetFromHandCost)cost).getNumberRevealedCards() > 0; + } + } + } + if (condition) { + controller.gainLife(4, game); + } + return true; + } + return false; + } +} + diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueShriek.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueShriek.java new file mode 100644 index 00000000000..a9d5c4b15c6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/FoulTongueShriek.java @@ -0,0 +1,98 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.AttackingCreatureCount; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class FoulTongueShriek extends CardImpl { + + public FoulTongueShriek(UUID ownerId) { + super(ownerId, 103, "Foul-Tongue Shriek", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{B}"); + this.expansionSetCode = "DTK"; + + // Target opponent loses 1 life for each attacking creature you control. You gain that much life. + this.getSpellAbility().addEffect(new FoulTongueShriekEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + + } + + public FoulTongueShriek(final FoulTongueShriek card) { + super(card); + } + + @Override + public FoulTongueShriek copy() { + return new FoulTongueShriek(this); + } +} + +class FoulTongueShriekEffect extends OneShotEffect { + + public FoulTongueShriekEffect() { + super(Outcome.Benefit); + this.staticText = "Target opponent loses 1 life for each attacking creature you control. You gain that much life"; + } + + public FoulTongueShriekEffect(final FoulTongueShriekEffect effect) { + super(effect); + } + + @Override + public FoulTongueShriekEffect copy() { + return new FoulTongueShriekEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (controller != null && targetOpponent != null) { + int amount = new AttackingCreatureCount().calculate(game, source, this); + if (amount > 0) { + targetOpponent.loseLife(amount, game); + controller.gainLife(amount, game); + } + return true; + } + return false; + } +} diff --git a/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java b/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java index 8d7ce093b86..3dbe7efd154 100644 --- a/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java +++ b/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java @@ -53,11 +53,11 @@ public class ExileFromGraveCost extends CostImpl { public ExileFromGraveCost(TargetCardInYourGraveyard target) { this.addTarget(target); if (target.getMaxNumberOfTargets() > 1) { - this.text = "Exile " + - (target.getNumberOfTargets() < target.getMaxNumberOfTargets() ? "up to ":"") + - CardUtil.numberToText(target.getMaxNumberOfTargets()) + - " " + - target.getTargetName(); + this.text = "Exile " + + (target.getNumberOfTargets() == 1 && target.getMaxNumberOfTargets() == Integer.MAX_VALUE ? "one or more" : + ((target.getNumberOfTargets() < target.getMaxNumberOfTargets() ? "up to ":"")) + + CardUtil.numberToText(target.getMaxNumberOfTargets())) + + " " + target.getTargetName(); } else { this.text = "Exile " + target.getTargetName(); diff --git a/Mage/src/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java index 6ace98f33f4..f26ba37acd4 100644 --- a/Mage/src/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java @@ -55,7 +55,7 @@ public class CantBeBlockedByOneAllEffect extends ContinuousEffectImpl { super(duration, Outcome.Benefit); this.amount = amount; this.filter = filter; - StringBuilder sb = new StringBuilder("Each ").append(filter.getMessage()).append(" can't be blocked "); + StringBuilder sb = new StringBuilder("each ").append(filter.getMessage()).append(" can't be blocked "); if (duration.equals(Duration.EndOfTurn)) { sb.append("this turn "); } From b78d6f69af6d2b565c95b3ac20f76dd7eeecb3f8 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 00:34:33 +0100 Subject: [PATCH 05/13] Some minor updates to mtg-cards-data.txt. --- Utils/mtg-cards-data.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index bfb13321331..5ec3d72317d 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25757,10 +25757,10 @@ Ambuscade Shaman|Dragons of Tarkir|87|U}{2}{B}|Creature - Orc Shaman|2|2|Wheneve 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.| Blood-Chin Rager|Dragons of Tarkir|89|U|{1}{B}|Creature - Human Warrior|2|2|Whenever Blood-Chin Rager attacks, each Warrior creature you control can't be blocked this turn except by two or more creatures.| Butcher's Glee|Dragons of Tarkir|90|C|{2}{B}|Instant|||Target creature gets +3/+0 and gains lifelink until end of turn. Regenerate it. (Damage dealt by a creature with lifelink also causes its controller to gain that much life.)| -Coat with Venom|Dragons of Tarkor|91|C|{B}|Instant|||Target creature gets +1/+2 and gains deathtouch until end of turn. (Any amount of damage it deals to a creature is enough to destroy it.)| -Cropseweft|Dragons of Tarkor|92|R|{2}{B}|Enchantment|||{1}{B}, Exile one or more creature cards from your graveyard: Put an X/X black Zombie Horror creature token onto the battlefield tapped, where X is twice the number of cards exiled this way.| +Coat with Venom|Dragons of Tarkir|91|C|{B}|Instant|||Target creature gets +1/+2 and gains deathtouch until end of turn. (Any amount of damage it deals to a creature is enough to destroy it.)| +Corpseweft|Dragons of Tarkir|92|R|{2}{B}|Enchantment|||{1}{B}, Exile one or more creature cards from your graveyard: Put an X/X black Zombie Horror creature token onto the battlefield tapped, where X is twice the number of cards exiled this way.| Damnable Pact|Dragons of Tarkir|93|R|{X}{B}{B}|Sorcery|||Target player draws X cards and loses X life.| -Deadly Wandering|Dragons of Tarkir|94|U|{3}{B}{B}|Enchantment|||As long as you control exactly one creature, that creature gets +2/+0 and has deathtouch and lifelink.| +Deadly Wanderings|Dragons of Tarkir|94|U|{3}{B}{B}|Enchantment|||As long as you control exactly one creature, that creature gets +2/+0 and has deathtouch and lifelink.| Death Wind|Dragons of Tarkrir|95|U|{X}{B}|Instant|||Target creature gets -X/-X until end of turn.| 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.| Defeat|Dragons of Tarkir|97|C|{1}{B}|Sorcery|||Destroy target creature with power 2 or less.| From 739b430a038e191d032aabd286822dcca3d75dc5 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 01:19:03 +0100 Subject: [PATCH 06/13] Some minor updates. --- Mage/src/mage/cards/repository/CardRepository.java | 2 +- Utils/release/getting_implemented_cards.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java index 6a0c0e1c95f..4e1fe1de3ed 100644 --- a/Mage/src/mage/cards/repository/CardRepository.java +++ b/Mage/src/mage/cards/repository/CardRepository.java @@ -60,7 +60,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 36; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 6; + private static final long CARD_CONTENT_VERSION = 7; private final Random random = new Random(); private Dao cardDao; diff --git a/Utils/release/getting_implemented_cards.txt b/Utils/release/getting_implemented_cards.txt index 3feba783d63..d94a06114d9 100644 --- a/Utils/release/getting_implemented_cards.txt +++ b/Utils/release/getting_implemented_cards.txt @@ -105,6 +105,8 @@ git log 6bd17716cd23e0f19142fb59c9c1bc44d87441e3..HEAD --diff-filter=A --name-st since 1.3.0-2015-03-14v1 git log ece4d69f367536ffb80cdf94d5a3dd771ba40f04..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt +since 1.3.0-2015-03-14v2 +git log b78d6f69af6d2b565c95b3ac20f76dd7eeecb3f8..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt 3. Copy added_cards.txt to trunk\Utils folder 4. Run script: From 6b7565b0977096ba8a9ddf4ac67e76b4bdb25449 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 01:26:07 +0100 Subject: [PATCH 07/13] * Grizzly Fate - Fixed that Beast instead of Bear tokens were created. --- Mage.Sets/src/mage/sets/judgment/GrizzlyFate.java | 2 +- Mage/src/mage/game/permanent/token/BearToken.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/judgment/GrizzlyFate.java b/Mage.Sets/src/mage/sets/judgment/GrizzlyFate.java index 5339f86b8ff..0a6f5633e24 100644 --- a/Mage.Sets/src/mage/sets/judgment/GrizzlyFate.java +++ b/Mage.Sets/src/mage/sets/judgment/GrizzlyFate.java @@ -39,7 +39,6 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.TimingRule; import mage.game.permanent.token.BearToken; -import mage.target.common.TargetCreatureOrPlayer; /** * @@ -60,6 +59,7 @@ public class GrizzlyFate extends CardImpl { new CardsInControllerGraveCondition(7), "Put two 2/2 green Bear creature tokens onto the battlefield.

Threshold - Put four 2/2 green Bear creature tokens onto the battlefield instead if seven or more cards are in your graveyard."); this.getSpellAbility().addEffect(effect); + // Flashback {5}{G}{G} this.addAbility(new FlashbackAbility(new ManaCostsImpl("{5}{G}{G}"), TimingRule.SORCERY)); } diff --git a/Mage/src/mage/game/permanent/token/BearToken.java b/Mage/src/mage/game/permanent/token/BearToken.java index 3d56d60dc94..be7d810d316 100644 --- a/Mage/src/mage/game/permanent/token/BearToken.java +++ b/Mage/src/mage/game/permanent/token/BearToken.java @@ -29,7 +29,6 @@ package mage.game.permanent.token; import mage.MageInt; -import mage.ObjectColor; import mage.constants.CardType; /** @@ -39,7 +38,7 @@ import mage.constants.CardType; public class BearToken extends Token { public BearToken() { - super("Beast", "2/2 green Bear creature token"); + super("Bear", "2/2 green Bear creature token"); cardType.add(CardType.CREATURE); color.setGreen(true); subtype.add("Bear"); From 2198a01781c4a9ed34680d0b3c7fc039da006d30 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 10:07:03 +0100 Subject: [PATCH 08/13] Changed font for feedback area from "times" to logical java font "Dialog". --- .../mage/client/components/MageTextArea.java | 22 +++++++++---------- .../main/java/org/mage/card/arcane/UI.java | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/components/MageTextArea.java b/Mage.Client/src/main/java/mage/client/components/MageTextArea.java index d9b4bdd7051..47c68ce1410 100644 --- a/Mage.Client/src/main/java/mage/client/components/MageTextArea.java +++ b/Mage.Client/src/main/java/mage/client/components/MageTextArea.java @@ -5,6 +5,7 @@ import org.mage.card.arcane.UI; import javax.swing.*; import java.awt.*; +import javax.swing.text.JTextComponent; /** * Component for displaying text in mage. @@ -12,6 +13,7 @@ import java.awt.*; * * @author nantuko */ + public class MageTextArea extends JEditorPane { public MageTextArea() { @@ -19,35 +21,31 @@ public class MageTextArea extends JEditorPane { setEditable(false); setBackground(new Color(0, 0, 0, 0)); // transparent background setFocusable(false); - //setBorder(BorderFactory.createLineBorder(Color.red)); - //setSelectionColor(new Color(0, 0, 0, 0)); + // setBorder(BorderFactory.createLineBorder(Color.red)); + // setSelectionColor(new Color(0, 0, 0, 0)); } + @Override public void setText(String text) { setText(text, 16); } public void setText(String text, int fontSize) { - if (text == null) return; - - String fontFamily = "times"; + if (text == null) { + return; + } final StringBuilder buffer = new StringBuilder(512); - buffer.append("
"); text = text.replaceAll("#([^#]+)#", "$1"); //text = text.replaceAll("\\s*//\\s*", "
"); text = text.replace("\r\n", "
"); - //text += "
"; if (text.length() > 0) { - //buffer.append("
"); - //text = text.replaceAll("\\{this\\}", card.getName()); - //text = text.replaceAll("\\{source\\}", card.getName()); buffer.append(ManaSymbols.replaceSymbolsWithHTML(text, ManaSymbols.Type.PAY)); } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/UI.java b/Mage.Client/src/main/java/org/mage/card/arcane/UI.java index a84f4415cea..3d1b83ec27a 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/UI.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/UI.java @@ -46,7 +46,7 @@ import javax.swing.text.html.ImageView; * UI utility functions. */ public class UI { - private static ConcurrentMap imageCache = new ConcurrentHashMap(); + private static final ConcurrentMap imageCache = new ConcurrentHashMap<>(); public static JToggleButton getToggleButton () { JToggleButton button = new JToggleButton(); From 8e169649f3969100425aa420992309ab247468b7 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 10:19:45 +0100 Subject: [PATCH 09/13] * Loyal Sentry - Fixed a bug that the blocked creature was not destroyed. --- Mage.Sets/src/mage/sets/tenth/LoyalSentry.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/tenth/LoyalSentry.java b/Mage.Sets/src/mage/sets/tenth/LoyalSentry.java index 3723e33e285..80bf5deb9c7 100644 --- a/Mage.Sets/src/mage/sets/tenth/LoyalSentry.java +++ b/Mage.Sets/src/mage/sets/tenth/LoyalSentry.java @@ -53,7 +53,6 @@ public class LoyalSentry extends CardImpl { this.subtype.add("Human"); this.subtype.add("Soldier"); - this.color.setWhite(true); this.power = new MageInt(1); this.toughness = new MageInt(1); @@ -83,7 +82,7 @@ class LoyalSentryEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent p = game.getPermanent(source.getFirstTarget()); + Permanent p = game.getPermanent(getTargetPointer().getFirst(game, source)); if (p != null) { p.destroy(source.getSourceId(), game, false); } From 32eba22309719bef3cf240ec49bccd13c78e80af Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 15:59:16 +0100 Subject: [PATCH 10/13] [DTK] Added 5 multicolor cards. --- .gitignore | 2 + .../sets/commander/BasandraBattleSeraph.java | 8 +- .../dragonsoftarkir/ArashinSovereign.java | 104 +++++++ .../sets/dragonsoftarkir/AtarkasCommand.java | 92 ++++++ .../dragonsoftarkir/DragonlordDromoka.java | 117 ++++++++ .../dragonsoftarkir/DragonlordKolaghan.java | 140 +++++++++ .../dragonsoftarkir/NarsetTranscendent.java | 265 ++++++++++++++++++ .../src/mage/sets/gatecrash/AureliasFury.java | 17 +- .../src/mage/sets/gatecrash/DomriRade.java | 11 +- .../mage/sets/newphyrexia/IsolationCell.java | 8 +- .../ContinuousRuleModifyingEffectImpl.java | 2 +- .../continuous/CantGainLifeAllEffect.java | 84 +++++- .../abilities/keyword/ReboundAbility.java | 26 +- Utils/mtg-cards-data.txt | 3 +- 14 files changed, 837 insertions(+), 42 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/AtarkasCommand.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordDromoka.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordKolaghan.java create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java diff --git a/.gitignore b/.gitignore index f92c34058d2..2d4ddf9ef24 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,8 @@ Mage.Server/mageserver.log Mage.Server/magediag.log Mage.Sets/target Mage.Stats/server.log +Mage.Stats/mageserver.log +Mage.Stats/magediag.log Mage.Tests/target Mage.Tests/cache Mage.Tests/db diff --git a/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java b/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java index 971b6414f25..1be9ccd5424 100644 --- a/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java +++ b/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java @@ -111,10 +111,14 @@ class BasandraBattleSeraphEffect extends ContinuousRuleModifyingEffectImpl { return true; } + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL; + } + @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == GameEvent.EventType.CAST_SPELL - && game.getPhase().getType() == TurnPhase.COMBAT) { + if (game.getPhase().getType() == TurnPhase.COMBAT) { return true; } return false; diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java new file mode 100644 index 00000000000..bf6814cea5c --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java @@ -0,0 +1,104 @@ +/* + * 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.DiesTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class ArashinSovereign extends CardImpl { + + public ArashinSovereign(UUID ownerId) { + super(ownerId, 212, "Arashin Sovereign", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{G}{W}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Arashin Sovereign dies, you may put it on the top or bottom of its owner's library. + this.addAbility(new DiesTriggeredAbility(new ArashinSovereignEffect())); + } + + public ArashinSovereign(final ArashinSovereign card) { + super(card); + } + + @Override + public ArashinSovereign copy() { + return new ArashinSovereign(this); + } +} + +class ArashinSovereignEffect extends OneShotEffect { + + public ArashinSovereignEffect() { + super(Outcome.Benefit); + this.staticText = "you may put it on the top or bottom of its owner's library"; + } + + public ArashinSovereignEffect(final ArashinSovereignEffect effect) { + super(effect); + } + + @Override + public ArashinSovereignEffect copy() { + return new ArashinSovereignEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Card sourceCard = game.getCard(source.getSourceId()); + if (controller != null && sourceCard != null) { + if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { + boolean onTop = controller.chooseUse(outcome, "Put " + sourceCard.getName() + " on top of it's owners library (otherwise on bottom)?", game); + controller.moveCardToLibraryWithInfo(sourceCard, source.getSourceId(), game, Zone.GRAVEYARD, onTop, true); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/AtarkasCommand.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/AtarkasCommand.java new file mode 100644 index 00000000000..d0e79f4b708 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/AtarkasCommand.java @@ -0,0 +1,92 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Mode; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.CantGainLifeAllEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author LevelX2 + */ +public class AtarkasCommand extends CardImpl { + + public AtarkasCommand(UUID ownerId) { + super(ownerId, 213, "Atarka's Command", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{R}{G}"); + this.expansionSetCode = "DTK"; + + // Choose two - + this.getSpellAbility().getModes().setMinModes(2); + this.getSpellAbility().getModes().setMaxModes(2); + + // Your opponents can't gain life this turn; + this.getSpellAbility().addEffect(new CantGainLifeAllEffect(Duration.EndOfTurn, TargetController.OPPONENT)); + + // or Atarka's Command deals 3 damage to each opponent; + Mode mode = new Mode(); + mode.getEffects().add(new DamagePlayersEffect(3, TargetController.OPPONENT)); + this.getSpellAbility().addMode(mode); + + // or You may put a land card from your hand onto the battlefield; + mode = new Mode(); + mode.getEffects().add(new PutLandFromHandOntoBattlefieldEffect()); + this.getSpellAbility().addMode(mode); + + // or Creatures you control get +1/+1 and gain reach until the end of turn. + mode = new Mode(); + Effect effect = new BoostControlledEffect(1,1, Duration.EndOfTurn); + effect.setText("Creatures you control get +1/+1"); + mode.getEffects().add(effect); + effect = new GainAbilityControlledEffect(ReachAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gain reach until the end of turn"); + mode.getEffects().add(effect); + this.getSpellAbility().addMode(mode); + + } + + public AtarkasCommand(final AtarkasCommand card) { + super(card); + } + + @Override + public AtarkasCommand copy() { + return new AtarkasCommand(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordDromoka.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordDromoka.java new file mode 100644 index 00000000000..3ec8fffdf35 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordDromoka.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.CantBeCounteredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author LevelX2 + */ +public class DragonlordDromoka extends CardImpl { + + public DragonlordDromoka(UUID ownerId) { + super(ownerId, 217, "Dragonlord Dromoka", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{4}{G}{W}"); + this.expansionSetCode = "DTK"; + this.supertype.add("Legendary"); + this.subtype.add("Elder"); + this.subtype.add("Dragon"); + this.power = new MageInt(5); + this.toughness = new MageInt(7); + + // Dragonlord Dromoka can't be countered + this.addAbility(new CantBeCounteredAbility()); + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + // Your opponents can't cast spells during your turn. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DragonlordDromokaEffect())); + + } + + public DragonlordDromoka(final DragonlordDromoka card) { + super(card); + } + + @Override + public DragonlordDromoka copy() { + return new DragonlordDromoka(this); + } +} + +class DragonlordDromokaEffect extends ContinuousRuleModifyingEffectImpl { + + public DragonlordDromokaEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "Your opponents can't cast spells during your turn"; + } + + public DragonlordDromokaEffect(final DragonlordDromokaEffect effect) { + super(effect); + } + + @Override + public DragonlordDromokaEffect copy() { + return new DragonlordDromokaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (game.getActivePlayerId().equals(source.getSourceId()) && + game.getPlayer(source.getControllerId()).hasOpponent(event.getPlayerId(), game)) { + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordKolaghan.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordKolaghan.java new file mode 100644 index 00000000000..e6fce2ff0d8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordKolaghan.java @@ -0,0 +1,140 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class DragonlordKolaghan extends CardImpl { + + public DragonlordKolaghan(UUID ownerId) { + super(ownerId, 218, "Dragonlord Kolaghan", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{4}{B}{R}"); + this.expansionSetCode = "DTK"; + this.supertype.add("Legendary"); + this.subtype.add("Elder"); + this.subtype.add("Dragon"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Other creatures you control have haste. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, new FilterControlledCreaturePermanent(), true))); + + // Whenever an opponent casts a creature or planeswalker spell with the same name as a card in their graveyard, that player loses 10 life. + Effect effect = new LoseLifeTargetEffect(10); + effect.setText("that player loses 10 life"); + this.addAbility(new DragonlordKolaghanTriggeredAbility(effect)); + + } + + public DragonlordKolaghan(final DragonlordKolaghan card) { + super(card); + } + + @Override + public DragonlordKolaghan copy() { + return new DragonlordKolaghan(this); + } +} + +class DragonlordKolaghanTriggeredAbility extends TriggeredAbilityImpl { + + public DragonlordKolaghanTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + public DragonlordKolaghanTriggeredAbility(final DragonlordKolaghanTriggeredAbility ability) { + super(ability); + } + + @Override + public DragonlordKolaghanTriggeredAbility copy() { + return new DragonlordKolaghanTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Player controller = game.getPlayer(getControllerId()); + if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) { + Card card = game.getCard(event.getSourceId()); + if (card != null && (card.getCardType().contains(CardType.CREATURE) || card.getCardType().contains(CardType.PLANESWALKER))) { + Player opponent = game.getPlayer(event.getPlayerId()); + boolean sameName = false; + for (Card graveCard :opponent.getGraveyard().getCards(game)) { + if (graveCard.getName().equals(card.getName())) { + sameName = true; + break; + } + } + if (sameName) { + this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId())); + return true; + } + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever an opponent casts a creature or planeswalker spell with the same name as a card in their graveyard, " + super.getRule(); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java new file mode 100644 index 00000000000..acfe95ba890 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java @@ -0,0 +1,265 @@ +/* + * 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.MageObject; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.ReboundAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.command.Emblem; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + + +/** + * + * @author LevelX2 + */ +public class NarsetTranscendent extends CardImpl { + + public NarsetTranscendent(UUID ownerId) { + super(ownerId, 225, "Narset Transcendent", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Narset"); + + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); + + // +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. + this.addAbility(new LoyaltyAbility(new NarsetTranscendentEffect1(), 1)); + + // -2: When you cast your next instant or sorcery spell from your hand this turn, it gains rebound. + this.addAbility(new LoyaltyAbility(new CreateDelayedTriggeredAbilityEffect(new NarsetTranscendentTriggeredAbility()), -2)); + + + + // -9:You get an emblem with "Your opponents can't cast noncreature spells." + this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new NarsetTranscendentEmblem()), -9)); + } + + public NarsetTranscendent(final NarsetTranscendent card) { + super(card); + } + + @Override + public NarsetTranscendent copy() { + return new NarsetTranscendent(this); + } +} + +class NarsetTranscendentEffect1 extends OneShotEffect { + + public NarsetTranscendentEffect1() { + super(Outcome.DrawCard); + this.staticText = "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"; + } + + public NarsetTranscendentEffect1(final NarsetTranscendentEffect1 effect) { + super(effect); + } + + @Override + public NarsetTranscendentEffect1 copy() { + return new NarsetTranscendentEffect1(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null && controller != null && controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + CardsImpl cards = new CardsImpl(); + cards.add(card); + controller.lookAtCards(sourceObject.getLogName(), cards, game); + if (!card.getCardType().contains(CardType.CREATURE) && !card.getCardType().contains(CardType.LAND)) { + if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", game)) { + controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + controller.revealCards(sourceObject.getLogName(), cards, game); + } + } + return true; + } + } + return false; + } +} + + +class NarsetTranscendentTriggeredAbility extends DelayedTriggeredAbility { + + public NarsetTranscendentTriggeredAbility() { + super(new NarsetTranscendentGainAbilityEffect(), Duration.EndOfTurn, true); + } + + private NarsetTranscendentTriggeredAbility(final NarsetTranscendentTriggeredAbility ability) { + super(ability); + } + @Override + public NarsetTranscendentTriggeredAbility copy() { + return new NarsetTranscendentTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && spell.getFromZone().equals(Zone.HAND)) { + if (spell.getCard() != null && + spell.getCard().getCardType().contains(CardType.INSTANT) || spell.getCard().getCardType().contains(CardType.SORCERY)) { + for(Effect effect: getEffects()) { + effect.setTargetPointer(new FixedTarget(spell.getId())); + } + return true; + } + } + } + return false; + } + + @Override + public String getRule() { + return "When you cast your next instant or sorcery spell from your hand this turn, " + super.getRule() ; + } +} + +class NarsetTranscendentGainAbilityEffect extends OneShotEffect { + + private final Ability ability; + + public NarsetTranscendentGainAbilityEffect() { + super(Outcome.AddAbility); + this.ability = new ReboundAbility(); + staticText = "it gains rebound"; + } + + public NarsetTranscendentGainAbilityEffect(final NarsetTranscendentGainAbilityEffect effect) { + super(effect); + this.ability = effect.ability; + } + + @Override + public NarsetTranscendentGainAbilityEffect copy() { + return new NarsetTranscendentGainAbilityEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Spell spell = game.getState().getStack().getSpell(getTargetPointer().getFirst(game, source)); + if (spell != null) { + ReboundAbility.addReboundEffectToSpellIfMissing(spell); + } + return true; + } +} + +class NarsetTranscendentEmblem extends Emblem { + // "Your opponents can't cast noncreature spells. + + public NarsetTranscendentEmblem() { + + this.setName("EMBLEM: Narset Transcendent"); + + this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new NarsetTranscendentCantCastEffect())); + } +} + +class NarsetTranscendentCantCastEffect extends ContinuousRuleModifyingEffectImpl { + + public NarsetTranscendentCantCastEffect() { + super(Duration.EndOfGame, Outcome.Benefit); + staticText = "Your opponents can't cast noncreature spells"; + } + + public NarsetTranscendentCantCastEffect(final NarsetTranscendentCantCastEffect effect) { + super(effect); + } + + @Override + public NarsetTranscendentCantCastEffect copy() { + return new NarsetTranscendentCantCastEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject != null) { + return "You can't cast can't cast noncreature spells (it is prevented by emblem of " + mageObject.getLogName() + ")"; + } + return null; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) { + Card card = game.getCard(event.getSourceId()); + if (card != null && !card.getCardType().contains(CardType.CREATURE)) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java b/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java index 563f826fb9c..78da253b9cc 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java +++ b/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java @@ -177,16 +177,19 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifyingEffectImpl { } return null; } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL; + } @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == GameEvent.EventType.CAST_SPELL ) { - Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); - if (player != null && player.getId().equals(event.getPlayerId())) { - Card card = game.getCard(event.getSourceId()); - if (card != null && !card.getCardType().contains(CardType.CREATURE)) { - return true; - } + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (player != null && player.getId().equals(event.getPlayerId())) { + Card card = game.getCard(event.getSourceId()); + if (card != null && !card.getCardType().contains(CardType.CREATURE)) { + return true; } } return false; diff --git a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java index 3bcbea992a1..a88d2a40809 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java +++ b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java @@ -28,6 +28,7 @@ package mage.sets.gatecrash; import java.util.UUID; +import mage.MageObject; import mage.constants.CardType; import mage.constants.Duration; @@ -117,17 +118,17 @@ class DomriRadeEffect1 extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && controller.getLibrary().size() > 0) { + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null && controller != null && controller.getLibrary().size() > 0) { Card card = controller.getLibrary().getFromTop(game); if (card != null) { CardsImpl cards = new CardsImpl(); cards.add(card); - controller.lookAtCards("Domri Rade", cards, game); + controller.lookAtCards(sourceObject.getLogName(), cards, game); if (card.getCardType().contains(CardType.CREATURE)) { - if (controller.chooseUse(outcome, new StringBuilder("Reveal ").append(card.getName()).append(" and put it into your hand?").toString(), game)) { - card = controller.getLibrary().removeFromTop(game); + if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", game)) { controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); - controller.revealCards("Domri Rade", cards, game); + controller.revealCards(sourceObject.getLogName(), cards, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/IsolationCell.java b/Mage.Sets/src/mage/sets/newphyrexia/IsolationCell.java index dde6436feb9..02f45a9ffcb 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/IsolationCell.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/IsolationCell.java @@ -81,11 +81,15 @@ class IsolationCellTriggeredAbility extends TriggeredAbilityImpl { public IsolationCellTriggeredAbility copy() { return new IsolationCellTriggeredAbility(this); } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.SPELL_CAST - && game.getOpponents(controllerId).contains(event.getPlayerId())) { + if (game.getOpponents(controllerId).contains(event.getPlayerId())) { Card card = game.getCard(event.getSourceId()); if (card != null && card.getCardType().contains(CardType.CREATURE)) { this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId())); diff --git a/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java b/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java index 8704d77e731..5dcf58d5e90 100644 --- a/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java +++ b/Mage/src/mage/abilities/effects/ContinuousRuleModifyingEffectImpl.java @@ -68,7 +68,7 @@ public abstract class ContinuousRuleModifyingEffectImpl extends ContinuousEffect * @param duration * @param outcome * @param messageToUser - Every time the effect replaces an event, the user gets a message in a dialog window. - * Don't set it to true if the event heppens regularly or very often. The message can be + * Don't set it to true if the event happens regularly or very often. The message itself can be * changed by overriding the getInfoMessage method. * @param messageToLog - Every time the effect replaces an event, a message is posted to the game log. The message * can be changed by overriding the getInfoMessage method. diff --git a/Mage/src/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java b/Mage/src/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java index 5b977d1031a..ff4c157bfc3 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java @@ -34,6 +34,7 @@ import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; +import mage.constants.TargetController; import mage.game.Game; import mage.players.Player; @@ -42,22 +43,27 @@ import mage.players.Player; * @author LevelX2 */ public class CantGainLifeAllEffect extends ContinuousEffectImpl { - + + private TargetController targetController; + public CantGainLifeAllEffect() { this(Duration.WhileOnBattlefield); } public CantGainLifeAllEffect(Duration duration) { + this(duration, TargetController.ANY); + } + + public CantGainLifeAllEffect(Duration duration, TargetController targetController) { super(duration, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit); - StringBuilder sb = new StringBuilder("Players can't gain life"); - if (!this.duration.toString().isEmpty()) { - sb.append(" ").append(duration.toString()); - } - staticText = sb.toString(); + this.targetController = targetController; + staticText = setText(); + } public CantGainLifeAllEffect(final CantGainLifeAllEffect effect) { super(effect); + this.targetController = effect.targetController; } @Override @@ -68,17 +74,69 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID playerId: controller.getInRange()) { - Player player = game.getPlayer(playerId); - if (player != null) - { - player.setCanGainLife(false); - } + if (controller != null) { + switch (targetController) { + case YOU: + controller.setCanGainLife(false); + break; + case NOT_YOU: + for (UUID playerId: controller.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null && !player.equals(controller)) { + player.setCanGainLife(false); + } + } + break; + case OPPONENT: + for (UUID playerId: controller.getInRange()) { + if (controller.hasOpponent(playerId, game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.setCanGainLife(false); + } + } + } + break; + case ANY: + for (UUID playerId: controller.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.setCanGainLife(false); + } + } + break; } return true; } return false; } + private String setText() { + StringBuilder sb = new StringBuilder(); + switch (targetController) { + case YOU: + sb.append("You"); + break; + case NOT_YOU: + sb.append("Other players"); + break; + case OPPONENT: + sb.append("Your opponents"); + break; + case ANY: + sb.append("Players"); + break; + } + sb.append(" can't gain life"); + if (!this.duration.toString().isEmpty()) { + sb.append(" "); + if (duration.equals(Duration.EndOfTurn)) { + sb.append("this turn"); + } else { + sb.append(duration.toString()); + } + + } + return sb.toString(); + } } diff --git a/Mage/src/mage/abilities/keyword/ReboundAbility.java b/Mage/src/mage/abilities/keyword/ReboundAbility.java index 6edb0518186..59f56ad6f6e 100644 --- a/Mage/src/mage/abilities/keyword/ReboundAbility.java +++ b/Mage/src/mage/abilities/keyword/ReboundAbility.java @@ -106,17 +106,7 @@ public class ReboundAbility extends TriggeredAbilityImpl { if (event.getType() == EventType.SPELL_CAST && this.installReboundEffect) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && spell.getSourceId().equals(this.getSourceId())) { - Effect reboundEffect = new ReboundEffect(); - boolean found = false; - for (Effect effect : spell.getSpellAbility().getEffects()) { - if (effect instanceof ReboundEffect) { - found = true; - break; - } - } - if (!found) { - spell.getSpellAbility().addEffect(reboundEffect); - } + addReboundEffectToSpellIfMissing(spell); this.installReboundEffect = false; } } @@ -132,6 +122,20 @@ public class ReboundAbility extends TriggeredAbilityImpl { public ReboundAbility copy() { return new ReboundAbility(this); } + + static public void addReboundEffectToSpellIfMissing(Spell spell) { + Effect reboundEffect = new ReboundEffect(); + boolean found = false; + for (Effect effect : spell.getSpellAbility().getEffects()) { + if (effect instanceof ReboundEffect) { + found = true; + break; + } + } + if (!found) { + spell.getSpellAbility().addEffect(reboundEffect); + } + } } /** diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 5ec3d72317d..8210af87927 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25878,7 +25878,8 @@ Stampeding Elk Herd|Dragons of Tarkir|208|C|{3}{G}{G}|Creature - Elk|5|5|Form 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.)| Surrak, the Hunt Caller|Dragons of Tarkir|210|R|{2}{G}{G}|Legendary Creature - Human Warrior|5|4|Formidable - At the beginning of combat on your turn, if creatures you control have total power 8 or greater, target creature you control gains haste until end of turn.| Tread Upon|Dragons of Tarkir|211|C|{1}{G}|Instant|||Target creature gets +2/+2 and gains trample until 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.| +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 c93ec2030efeec8d772969132cb49c11af4d0842 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 17:11:43 +0100 Subject: [PATCH 11/13] [DTK] Added Gleam of Authority. Added Dragonstalker. --- .../dragonsoftarkir/GleamOfAuthority.java | 133 ++++++++++++++++++ .../src/mage/sets/scourge/Dragonstalker.java | 67 +++++++++ 2 files changed, 200 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/dragonsoftarkir/GleamOfAuthority.java create mode 100644 Mage.Sets/src/mage/sets/scourge/Dragonstalker.java diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/GleamOfAuthority.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/GleamOfAuthority.java new file mode 100644 index 00000000000..3c876f92439 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/GleamOfAuthority.java @@ -0,0 +1,133 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.keyword.BolsterEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class GleamOfAuthority extends CardImpl { + + public GleamOfAuthority(UUID ownerId) { + super(ownerId, 19, "Gleam of Authority", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control + DynamicValue amount = new CountersOnControlledCount(); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield))); + + // Enchanted creature has vigilance and "{W}, {T}: Bloster 1." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA))); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BolsterEffect(1), new ManaCostsImpl("{W}")); + ability.addCost(new TapSourceCost()); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.AURA))); + } + + public GleamOfAuthority(final GleamOfAuthority card) { + super(card); + } + + @Override + public GleamOfAuthority copy() { + return new GleamOfAuthority(this); + } +} + +class CountersOnControlledCount implements DynamicValue { + + static FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + public CountersOnControlledCount() { + } + + public CountersOnControlledCount(final CountersOnControlledCount dynamicValue) { + super(); + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + int count = 0; + for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, sourceAbility.getControllerId(), game)) { + if (!permanent.getId().equals(sourceAbility.getSourceId())) { + count += permanent.getCounters().getCount(CounterType.P1P1); + } + } + return count; + } + + @Override + public DynamicValue copy() { + return new CountersOnControlledCount(this); + } + + @Override + public String getMessage() { + return "+1/+1 counter on other creatures you control"; + } + + @Override + public String toString() { + return "X"; + } +} diff --git a/Mage.Sets/src/mage/sets/scourge/Dragonstalker.java b/Mage.Sets/src/mage/sets/scourge/Dragonstalker.java new file mode 100644 index 00000000000..d3e7b995618 --- /dev/null +++ b/Mage.Sets/src/mage/sets/scourge/Dragonstalker.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.scourge; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterPermanent; + +/** + * + * @author LevelX2 + */ +public class Dragonstalker extends CardImpl { + + public Dragonstalker(UUID ownerId) { + super(ownerId, 11, "Dragonstalker", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{W}"); + this.expansionSetCode = "SCG"; + this.subtype.add("Bird"); + this.subtype.add("Soldier"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // protection from Dragons + this.addAbility(new ProtectionAbility(new FilterPermanent("Dragon", "Dragons"))); + } + + public Dragonstalker(final Dragonstalker card) { + super(card); + } + + @Override + public Dragonstalker copy() { + return new Dragonstalker(this); + } +} From 68b5528afa2802c5c0e4f0c57c1063b8278208e3 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 18 Mar 2015 17:17:21 +0100 Subject: [PATCH 12/13] * Kaalia of the Vast - Fixed that the creature put into play was not tapped. --- Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java b/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java index b155946c466..4602fabd450 100644 --- a/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java +++ b/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java @@ -61,9 +61,6 @@ public class KaaliaOfTheVast extends CardImpl { this.supertype.add("Legendary"); this.subtype.add("Human"); this.subtype.add("Cleric"); - this.color.setWhite(true); - this.color.setBlack(true); - this.color.setRed(true); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -159,7 +156,7 @@ class KaaliaOfTheVastEffect extends OneShotEffect { UUID defenderId = game.getCombat().getDefendingPlayerId(source.getSourceId(), game); if (defenderId != null) { player.getHand().remove(card); - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); + player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), true); Permanent creature = game.getPermanent(cardId); if (creature != null) { game.getCombat().declareAttacker(card.getId(), defenderId, game); From 227052f1087869e41e0d7d4f6f299d321ad70140 Mon Sep 17 00:00:00 2001 From: fireshoes Date: Wed, 18 Mar 2015 11:33:11 -0500 Subject: [PATCH 13/13] Removed DTK from the ignore list in image.url.properties. [Homelands] Added Cemetery Gate --- .../src/main/resources/image.url.properties | 2 +- .../src/mage/sets/homelands/CemeteryGate.java | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/sets/homelands/CemeteryGate.java diff --git a/Mage.Client/src/main/resources/image.url.properties b/Mage.Client/src/main/resources/image.url.properties index ab80283ed8c..2a98f34c595 100644 --- a/Mage.Client/src/main/resources/image.url.properties +++ b/Mage.Client/src/main/resources/image.url.properties @@ -65,6 +65,6 @@ ddd=gvl unh=uh dde=pvc # Remove setname as soon as the images can be downloaded -ignore.urls=TOK,DTK,MMB,ORI +ignore.urls=TOK,MMB,ORI # sets ordered by release time (newest goes first) token.lookup.order=ORI,MMB,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/homelands/CemeteryGate.java b/Mage.Sets/src/mage/sets/homelands/CemeteryGate.java new file mode 100644 index 00000000000..b88935ab7cd --- /dev/null +++ b/Mage.Sets/src/mage/sets/homelands/CemeteryGate.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.homelands; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author fireshoes + */ +public class CemeteryGate extends CardImpl { + + private static final FilterCard filter = new FilterCard("Black"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + public CemeteryGate(UUID ownerId) { + super(ownerId, 5, "Cemetery Gate", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "HML"; + this.subtype.add("Wall"); + this.power = new MageInt(0); + this.toughness = new MageInt(5); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + + // Protection from black + this.addAbility(new ProtectionAbility(filter)); + } + + public CemeteryGate(final CemeteryGate card) { + super(card); + } + + @Override + public CemeteryGate copy() { + return new CemeteryGate(this); + } +}