From 1f44b8cde1d171f1cbd573c70c28cb4f3f5437eb Mon Sep 17 00:00:00 2001 From: wetterlicht Date: Mon, 16 May 2016 22:55:29 +0200 Subject: [PATCH 1/4] Implemented cards: Burden of Greed, Drill Skimmer, Drooling Ogre, Emissary of Despair, Psychic Overload, Pulse of the Tangle, Rebuking Ceremony, Tel-Jilad Wolf, Unforge, Vex --- .../mage/sets/darksteel/BurdenOfGreed.java | 101 ++++++++++++ .../src/mage/sets/darksteel/DrillSkimmer.java | 90 +++++++++++ .../src/mage/sets/darksteel/DroolingOgre.java | 145 ++++++++++++++++++ .../sets/darksteel/EmissaryOfDespair.java | 100 ++++++++++++ .../mage/sets/darksteel/PsychicOverload.java | 85 ++++++++++ .../mage/sets/darksteel/PulseOfTheTangle.java | 117 ++++++++++++++ .../mage/sets/darksteel/RebukingCeremony.java | 60 ++++++++ .../src/mage/sets/darksteel/TelJiladWolf.java | 74 +++++++++ .../src/mage/sets/darksteel/Unforge.java | 109 +++++++++++++ Mage.Sets/src/mage/sets/darksteel/Vex.java | 104 +++++++++++++ 10 files changed, 985 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/darksteel/BurdenOfGreed.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/DrillSkimmer.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/RebukingCeremony.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/TelJiladWolf.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/Unforge.java create mode 100644 Mage.Sets/src/mage/sets/darksteel/Vex.java diff --git a/Mage.Sets/src/mage/sets/darksteel/BurdenOfGreed.java b/Mage.Sets/src/mage/sets/darksteel/BurdenOfGreed.java new file mode 100644 index 0000000000..3bb212ffb6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/BurdenOfGreed.java @@ -0,0 +1,101 @@ +/* + * 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.darksteel; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.PermanentsTargetOpponentControlsCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterArtifactPermanent; +import mage.filter.predicate.other.OwnerIdPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.target.TargetPlayer; + +/** + * + * @author wetterlicht + */ +public class BurdenOfGreed extends CardImpl { + + public BurdenOfGreed(UUID ownerId) { + super(ownerId, 38, "Burden of Greed", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{B}"); + this.expansionSetCode = "DST"; + + // Target player loses 1 life for each tapped artifact he or she controls. + getSpellAbility().addTarget(new TargetPlayer()); + getSpellAbility().addEffect(new LoseLifeTargetEffect(new BurdenOfGreedCount())); + + } + + public BurdenOfGreed(final BurdenOfGreed card) { + super(card); + } + + @Override + public BurdenOfGreed copy() { + return new BurdenOfGreed(this); + } +} + +class BurdenOfGreedCount implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + if (sourceAbility.getFirstTarget() == null) { + return 0; + } + FilterArtifactPermanent filter = new FilterArtifactPermanent(); + filter.add(new TappedPredicate()); + filter.add(new ControllerIdPredicate(sourceAbility.getFirstTarget())); + return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game); + } + + @Override + public DynamicValue copy() { + return new BurdenOfGreedCount(); + } + + @Override + public String toString() { + return "1"; + } + + @Override + public String getMessage() { + return "tapped artifact he or she controls"; + } + +} diff --git a/Mage.Sets/src/mage/sets/darksteel/DrillSkimmer.java b/Mage.Sets/src/mage/sets/darksteel/DrillSkimmer.java new file mode 100644 index 0000000000..ff33a8def1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/DrillSkimmer.java @@ -0,0 +1,90 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.darksteel; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledArtifactPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledPlaneswalkerPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author wetterlicht + */ +public class DrillSkimmer extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("you control another artifact creature"); + + static { + filter.add(new AnotherPredicate()); + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + public DrillSkimmer(UUID ownerId) { + super(ownerId, 118, "Drill-Skimmer", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.expansionSetCode = "DST"; + this.subtype.add("Thopter"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Drill-Skimmer has shroud as long as you control another artifact creature. + Condition condition = new PermanentsOnTheBattlefieldCondition(filter, PermanentsOnTheBattlefieldCondition.CountType.MORE_THAN, 0); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousEffect(new GainAbilitySourceEffect(ShroudAbility.getInstance(), Duration.WhileOnBattlefield), + condition, "{this} has shroud as long as you control another artifact creature."))); + } + + public DrillSkimmer(final DrillSkimmer card) { + super(card); + } + + @Override + public DrillSkimmer copy() { + return new DrillSkimmer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java b/Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java new file mode 100644 index 0000000000..b2368462b4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java @@ -0,0 +1,145 @@ +/* + * 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.darksteel; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SpellCastAllTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +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.FilterArtifactSpell; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author wetterlicht + */ +public class DroolingOgre extends CardImpl { + + public DroolingOgre(UUID ownerId) { + super(ownerId, 58, "Drooling Ogre", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "DST"; + this.subtype.add("Ogre"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever a player casts an artifact spell, that player gains control of Drooling Ogre. + this.addAbility(new DroolingOgreTriggeredAbility()); + } + + public DroolingOgre(final DroolingOgre card) { + super(card); + } + + @Override + public DroolingOgre copy() { + return new DroolingOgre(this); + } + + private static class DroolingOgreEffect extends OneShotEffect { + + public DroolingOgreEffect() { + super(Outcome.GainControl); + this.staticText = "that player gains control of {this}"; + } + + private DroolingOgreEffect(DroolingOgreEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player newController = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (newController != null && controller != null && !controller.equals(newController)) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, newController.getId()); + effect.setTargetPointer(new FixedTarget(source.getSourceId())); + game.addEffect(effect, source); + return true; + } + return false; + } + + @Override + public Effect copy() { + return new DroolingOgreEffect(this); + } + + } + + class DroolingOgreTriggeredAbility extends TriggeredAbilityImpl { + + public DroolingOgreTriggeredAbility() { + super(Zone.BATTLEFIELD, new DroolingOgreEffect(), false); + } + + public DroolingOgreTriggeredAbility(final DroolingOgreTriggeredAbility ability) { + super(ability); + } + + @Override + public DroolingOgreTriggeredAbility copy() { + return new DroolingOgreTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && spell.getCardType().contains(CardType.ARTIFACT)) { + this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId())); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever a player casts an artifact spell, that player gains control of {this}"; + } + } +} diff --git a/Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java b/Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java new file mode 100644 index 0000000000..70a8a54d27 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java @@ -0,0 +1,100 @@ +/* + * 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.darksteel; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterArtifactPermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; + +/** + * + * @author wetterlicht + */ +public class EmissaryOfDespair extends CardImpl { + + public EmissaryOfDespair(UUID ownerId) { + super(ownerId, 42, "Emissary of Despair", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.expansionSetCode = "DST"; + this.subtype.add("Spirit"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Whenever Emissary of Despair deals combat damage to a player, that player loses 1 life for each artifact he or she controls. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new LoseLifeTargetEffect(new EmissaryOfDespairCount()), false, true)); + } + + public EmissaryOfDespair(final EmissaryOfDespair card) { + super(card); + } + + @Override + public EmissaryOfDespair copy() { + return new EmissaryOfDespair(this); + } +} + +class EmissaryOfDespairCount implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + if (sourceAbility.getFirstTarget() == null) { + return 0; + } + FilterArtifactPermanent filter = new FilterArtifactPermanent(); + filter.add(new ControllerIdPredicate(sourceAbility.getFirstTarget())); + return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game); + } + + @Override + public DynamicValue copy() { + return new EmissaryOfDespairCount(); + } + + @Override + public String toString() { + return "1"; + } + + @Override + public String getMessage() { + return "artifact he or she controls"; + } +} diff --git a/Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java b/Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java new file mode 100644 index 0000000000..04e8c82dcc --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java @@ -0,0 +1,85 @@ +/* + * 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.darksteel; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.common.DiscardXTargetCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; +import mage.abilities.effects.common.TapEnchantedEffect; +import mage.abilities.effects.common.UntapEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterArtifactCard; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInHand; + +/** + * + * @author wetterlicht + */ +public class PsychicOverload extends CardImpl { + + public PsychicOverload(UUID ownerId) { + super(ownerId, 28, "Psychic Overload", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); + this.expansionSetCode = "DST"; + this.subtype.add("Aura"); + + // Enchant permanent + TargetPermanent auraTarget = new TargetPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.addAbility(new EnchantAbility(auraTarget.getTargetName())); + + // When Psychic Overload enters the battlefield, tap enchanted permanent. + this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect())); + // Enchanted permanent doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect())); + // Enchanted permanent has "Discard two artifact cards: Untap this permanent." + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new DiscardTargetCost(new TargetCardInHand(2, new FilterArtifactCard("two artifact cards"))))); + } + + public PsychicOverload(final PsychicOverload card) { + super(card); + } + + @Override + public PsychicOverload copy() { + return new PsychicOverload(this); + } +} diff --git a/Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java new file mode 100644 index 0000000000..029347f42c --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.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.darksteel; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +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.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.token.BeastToken; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetOpponent; + +/** + * + * @author wetterlicht + */ +public class PulseOfTheTangle extends CardImpl { + + public PulseOfTheTangle(UUID ownerId) { + super(ownerId, 80, "Pulse of the Tangle", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{1}{G}{G}"); + this.expansionSetCode = "DST"; + + // Put a 3/3 green Beast creature token onto the battlefield. Then if an opponent controls more creatures than you, return Pulse of the Tangle to its owner's hand. + this.getSpellAbility().addEffect(new CreateTokenEffect(new BeastToken())); + this.getSpellAbility().addEffect(new PulseOfTheTangleReturnToHandEffect()); + } + + public PulseOfTheTangle(final PulseOfTheTangle card) { + super(card); + } + + @Override + public PulseOfTheTangle copy() { + return new PulseOfTheTangle(this); + } +} + +class PulseOfTheTangleReturnToHandEffect extends OneShotEffect { + + PulseOfTheTangleReturnToHandEffect() { + super(Outcome.Benefit); + this.staticText = "Then if an opponent controls more creatures than you, return Pulse of the Tangle to its owner's hand"; + } + + PulseOfTheTangleReturnToHandEffect(final PulseOfTheTangleReturnToHandEffect effect) { + super(effect); + } + + @Override + public PulseOfTheTangleReturnToHandEffect copy() { + return new PulseOfTheTangleReturnToHandEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + FilterControlledCreaturePermanent controllerFilter = new FilterControlledCreaturePermanent(); + PermanentsOnBattlefieldCount controllerCount = new PermanentsOnBattlefieldCount(controllerFilter); + boolean check = false; + if (controller != null) { + for (UUID opponentID : game.getOpponents(controller.getId())) { + if (opponentID != null) { + FilterCreaturePermanent opponentFilter = new FilterCreaturePermanent(); + opponentFilter.add(new ControllerIdPredicate(opponentID)); + PermanentsOnBattlefieldCount opponentCreatureCount = new PermanentsOnBattlefieldCount(opponentFilter); + check = opponentCreatureCount.calculate(game, source, this) > controllerCount.calculate(game, source, this); + if (check) { + break; + } + } + } + if (check) { + Card card = game.getCard(source.getSourceId()); + controller.moveCards(card, Zone.HAND, source, game); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/darksteel/RebukingCeremony.java b/Mage.Sets/src/mage/sets/darksteel/RebukingCeremony.java new file mode 100644 index 0000000000..8f800cd19d --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/RebukingCeremony.java @@ -0,0 +1,60 @@ +/* + * 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.darksteel; + +import java.util.UUID; +import mage.abilities.effects.common.PutOnLibraryTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetArtifactPermanent; + +/** + * + * @author wetterlicht + */ +public class RebukingCeremony extends CardImpl { + + public RebukingCeremony(UUID ownerId) { + super(ownerId, 82, "Rebuking Ceremony", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{G}{G}"); + this.expansionSetCode = "DST"; + + // Put two target artifacts on top of their owners' libraries. + getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true)); + getSpellAbility().addTarget(new TargetArtifactPermanent(2)); + } + + public RebukingCeremony(final RebukingCeremony card) { + super(card); + } + + @Override + public RebukingCeremony copy() { + return new RebukingCeremony(this); + } +} diff --git a/Mage.Sets/src/mage/sets/darksteel/TelJiladWolf.java b/Mage.Sets/src/mage/sets/darksteel/TelJiladWolf.java new file mode 100644 index 0000000000..ac25c3e509 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/TelJiladWolf.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.darksteel; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesBlockedAllTriggeredAbility; +import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility; +import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; + +/** + * + * @author wetterlicht + */ +public class TelJiladWolf extends CardImpl { + + private static FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creature"); + + static{ + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + public TelJiladWolf(UUID ownerId) { + super(ownerId, 88, "Tel-Jilad Wolf", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "DST"; + this.subtype.add("Wolf"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Tel-Jilad Wolf becomes blocked by an artifact creature, Tel-Jilad Wolf gets +3/+3 until end of turn. + this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(new BoostSourceEffect(3, 3, Duration.EndOfTurn), filter, false)); + } + + public TelJiladWolf(final TelJiladWolf card) { + super(card); + } + + @Override + public TelJiladWolf copy() { + return new TelJiladWolf(this); + } +} diff --git a/Mage.Sets/src/mage/sets/darksteel/Unforge.java b/Mage.Sets/src/mage/sets/darksteel/Unforge.java new file mode 100644 index 0000000000..023d1db70e --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/Unforge.java @@ -0,0 +1,109 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.darksteel; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterArtifactPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetArtifactPermanent; + +/** + * + * @author wetterlicht + */ +public class Unforge extends CardImpl { + + private static FilterArtifactPermanent filter = new FilterArtifactPermanent("equipment"); + + static{ + filter.add(new SubtypePredicate("Equipment")); + } + + public Unforge(UUID ownerId) { + super(ownerId, 71, "Unforge", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{R}"); + this.expansionSetCode = "DST"; + + // Destroy target Equipment. If that Equipment was attached to a creature, Unforge deals 2 damage to that creature. + getSpellAbility().addTarget(new TargetArtifactPermanent(filter)); + getSpellAbility().addEffect(new DestroyTargetEffect()); + getSpellAbility().addEffect(new UnforgeEffect()); + } + + public Unforge(final Unforge card) { + super(card); + } + + @Override + public Unforge copy() { + return new Unforge(this); + } + +} + +class UnforgeEffect extends OneShotEffect{ + + public UnforgeEffect(){ + super(Outcome.Damage); + staticText = "If that Equipment was attached to a creature, Unforge deals 2 damage to that creature."; + } + + public UnforgeEffect(final UnforgeEffect effect){ + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent equipment = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); + if(equipment != null){ + Permanent creature = game.getPermanent(equipment.getAttachedTo()); + if(creature != null){ + creature.damage(2, source.getId(), game, false, true); + return true; + } + } + + return false; + } + + @Override + public Effect copy() { + return new UnforgeEffect(this); + } + + +} diff --git a/Mage.Sets/src/mage/sets/darksteel/Vex.java b/Mage.Sets/src/mage/sets/darksteel/Vex.java new file mode 100644 index 0000000000..25b9675f3e --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/Vex.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.darksteel; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetSpell; + +/** + * + * @author wetterlicht + */ +public class Vex extends CardImpl { + + public Vex(UUID ownerId) { + super(ownerId, 36, "Vex", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{U}"); + this.expansionSetCode = "DST"; + + // Counter target spell. That spell's controller may draw a card. + getSpellAbility().addTarget(new TargetSpell()); + getSpellAbility().addEffect(new VexEffect()); + } + + public Vex(final Vex card) { + super(card); + } + + @Override + public Vex copy() { + return new Vex(this); + } +} + +class VexEffect extends OneShotEffect { + + public VexEffect() { + super(Outcome.Neutral); + this.staticText = "That spell's controller may draw a card"; + } + + public VexEffect(final VexEffect effect) { + super(effect); + } + + @Override + public VexEffect copy() { + return new VexEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID targetId = source.getFirstTarget(); + Player controller = null; + boolean countered = false; + if (targetId != null) { + controller = game.getPlayer(game.getControllerId(targetId)); + } + if (targetId != null + && game.getStack().counter(targetId, source.getSourceId(), game)) { + countered = true; + } + if (controller != null) { + controller.drawCards(1, game); + } + return countered; + } +} From 140d7e93761fb561479fba9d7d36dee16c2a8b11 Mon Sep 17 00:00:00 2001 From: wetterlicht Date: Mon, 16 May 2016 22:57:28 +0200 Subject: [PATCH 2/4] Added Filter to BecomesBlockedByCreatureTriggeredAbility --- ...omesBlockedByCreatureTriggeredAbility.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/common/BecomesBlockedByCreatureTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BecomesBlockedByCreatureTriggeredAbility.java index 641a4885ba..1386e11bcc 100644 --- a/Mage/src/main/java/mage/abilities/common/BecomesBlockedByCreatureTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BecomesBlockedByCreatureTriggeredAbility.java @@ -30,8 +30,10 @@ package mage.abilities.common; import mage.constants.Zone; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** @@ -40,10 +42,17 @@ import mage.target.targetpointer.FixedTarget; */ public class BecomesBlockedByCreatureTriggeredAbility extends TriggeredAbilityImpl { + private static FilterCreaturePermanent filter = new FilterCreaturePermanent(); + public BecomesBlockedByCreatureTriggeredAbility(Effect effect, boolean optional) { super(Zone.BATTLEFIELD, effect, optional); } + public BecomesBlockedByCreatureTriggeredAbility(Effect effect, FilterCreaturePermanent filter, boolean optional) { + super(Zone.BATTLEFIELD, effect, optional); + this.filter = filter; + } + public BecomesBlockedByCreatureTriggeredAbility(final BecomesBlockedByCreatureTriggeredAbility ability) { super(ability); } @@ -56,17 +65,20 @@ public class BecomesBlockedByCreatureTriggeredAbility extends TriggeredAbilityIm @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getTargetId().equals(this.getSourceId())) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getSourceId())); + Permanent blocker = game.getPermanent(event.getSourceId()); + if (filter.match(blocker, game)) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getSourceId())); + } + return true; } - return true; } return false; } @Override public String getRule() { - return "Whenever {this} becomes blocked by a creature, " + super.getRule(); + return "Whenever {this} becomes blocked by a " + filter.getMessage() + ", " + super.getRule(); } @Override From 28902e5616e7e98766a1be824ac392444e2a834d Mon Sep 17 00:00:00 2001 From: wetterlicht Date: Mon, 16 May 2016 22:58:27 +0200 Subject: [PATCH 3/4] Implemented Murderous Spoils --- .../mage/sets/darksteel/MurderousSpoils.java | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java diff --git a/Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java b/Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java new file mode 100644 index 0000000000..018c2b2c71 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.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.darksteel; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author wetterlicht + */ +public class MurderousSpoils extends CardImpl { + + private static final FilterCreaturePermanent FILTER = new FilterCreaturePermanent("nonblack creature"); + + static { + FILTER.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + + public MurderousSpoils(UUID ownerId) { + super(ownerId, 48, "Murderous Spoils", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{5}{B}"); + this.expansionSetCode = "DST"; + + // Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it. + this.getSpellAbility().addTarget(new TargetCreaturePermanent(FILTER)); + this.getSpellAbility().addEffect(new MurderousSpoilsEffect()); + + } + + public MurderousSpoils(final MurderousSpoils card) { + super(card); + } + + @Override + public MurderousSpoils copy() { + return new MurderousSpoils(this); + } +} + +class MurderousSpoilsEffect extends OneShotEffect { + + public MurderousSpoilsEffect() { + super(Outcome.DestroyPermanent); + staticText = "Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it."; + } + + public MurderousSpoilsEffect(final MurderousSpoilsEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent target = game.getPermanent(source.getFirstTarget()); + if (target != null) { + List attachments = new ArrayList(); + for (UUID uuid : target.getAttachments()) { + Permanent attached = game.getBattlefield().getPermanent(uuid); + if (attached.getSubtype().contains("Equipment")) { + attachments.add(attached); + } + } + for (Permanent p : attachments) { + ContinuousEffect gainControl = new GainControlTargetEffect(Duration.EndOfGame); + gainControl.setTargetPointer(new FixedTarget(p.getId())); + game.addEffect(gainControl, source); + } + target.destroy(source.getId(), game, true); + return true; + } + return false; + } + + @Override + public MurderousSpoilsEffect copy() { + return new MurderousSpoilsEffect(this); + } + +} From dc4168efaee35a1ea551627925e6a9e55b376bd7 Mon Sep 17 00:00:00 2001 From: wetterlicht Date: Sun, 22 May 2016 19:41:59 +0200 Subject: [PATCH 4/4] --- .../src/mage/sets/darksteel/DroolingOgre.java | 4 +--- .../mage/sets/darksteel/EmissaryOfDespair.java | 4 ++-- .../src/mage/sets/darksteel/MurderousSpoils.java | 4 ++-- .../src/mage/sets/darksteel/PsychicOverload.java | 15 ++++++++++----- .../src/mage/sets/darksteel/PulseOfTheTangle.java | 5 +++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java b/Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java index b2368462b4..9dba69254a 100644 --- a/Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java +++ b/Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.SpellCastAllTriggeredAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; @@ -42,7 +41,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.filter.common.FilterArtifactSpell; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -139,7 +137,7 @@ public class DroolingOgre extends CardImpl { @Override public String getRule() { - return "Whenever a player casts an artifact spell, that player gains control of {this}"; + return "Whenever a player casts an artifact spell, that player gains control of {this}."; } } } diff --git a/Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java b/Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java index 70a8a54d27..7647695b6e 100644 --- a/Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java +++ b/Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java @@ -75,11 +75,11 @@ class EmissaryOfDespairCount implements DynamicValue { @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { - if (sourceAbility.getFirstTarget() == null) { + if (effect.getTargetPointer().getFirst(game, sourceAbility) == null) { return 0; } FilterArtifactPermanent filter = new FilterArtifactPermanent(); - filter.add(new ControllerIdPredicate(sourceAbility.getFirstTarget())); + filter.add(new ControllerIdPredicate(effect.getTargetPointer().getFirst(game, sourceAbility))); return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game); } diff --git a/Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java b/Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java index 018c2b2c71..80c5130db5 100644 --- a/Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java +++ b/Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java @@ -105,8 +105,8 @@ class MurderousSpoilsEffect extends OneShotEffect { } } for (Permanent p : attachments) { - ContinuousEffect gainControl = new GainControlTargetEffect(Duration.EndOfGame); - gainControl.setTargetPointer(new FixedTarget(p.getId())); + ContinuousEffect gainControl = new GainControlTargetEffect(Duration.Custom); + gainControl.setTargetPointer(new FixedTarget(p, game)); game.addEffect(gainControl, source); } target.destroy(source.getId(), game, true); diff --git a/Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java b/Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java index 04e8c82dcc..d4fe61d82d 100644 --- a/Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java +++ b/Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java @@ -28,23 +28,25 @@ package mage.sets.darksteel; import java.util.UUID; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.DiscardTargetCost; -import mage.abilities.costs.common.DiscardXTargetCost; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; import mage.abilities.effects.common.TapEnchantedEffect; -import mage.abilities.effects.common.UntapEnchantedEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; 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.filter.FilterCard; import mage.filter.common.FilterArtifactCard; import mage.target.TargetPermanent; import mage.target.common.TargetCardInHand; @@ -70,8 +72,11 @@ public class PsychicOverload extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect())); // Enchanted permanent doesn't untap during its controller's untap step. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect())); + // Enchanted permanent has "Discard two artifact cards: Untap this permanent." - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new DiscardTargetCost(new TargetCardInHand(2, new FilterArtifactCard("two artifact cards"))))); + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new DiscardTargetCost(new TargetCardInHand(2, new FilterArtifactCard("two artifact cards")))); + Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA, Duration.WhileOnBattlefield, "Enchanted permanent has \"Discard two artifact cards: Untap this permanent.\""); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } public PsychicOverload(final PsychicOverload card) { diff --git a/Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java index 029347f42c..55e0a3d74f 100644 --- a/Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java +++ b/Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java @@ -76,7 +76,7 @@ class PulseOfTheTangleReturnToHandEffect extends OneShotEffect { PulseOfTheTangleReturnToHandEffect() { super(Outcome.Benefit); - this.staticText = "Then if an opponent controls more creatures than you, return Pulse of the Tangle to its owner's hand"; + this.staticText = "Then if an opponent controls more creatures than you, return {this} to its owner's hand"; } PulseOfTheTangleReturnToHandEffect(final PulseOfTheTangleReturnToHandEffect effect) { @@ -93,6 +93,7 @@ class PulseOfTheTangleReturnToHandEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); FilterControlledCreaturePermanent controllerFilter = new FilterControlledCreaturePermanent(); PermanentsOnBattlefieldCount controllerCount = new PermanentsOnBattlefieldCount(controllerFilter); + int controllerAmount = controllerCount.calculate(game, source, this); boolean check = false; if (controller != null) { for (UUID opponentID : game.getOpponents(controller.getId())) { @@ -100,7 +101,7 @@ class PulseOfTheTangleReturnToHandEffect extends OneShotEffect { FilterCreaturePermanent opponentFilter = new FilterCreaturePermanent(); opponentFilter.add(new ControllerIdPredicate(opponentID)); PermanentsOnBattlefieldCount opponentCreatureCount = new PermanentsOnBattlefieldCount(opponentFilter); - check = opponentCreatureCount.calculate(game, source, this) > controllerCount.calculate(game, source, this); + check = opponentCreatureCount.calculate(game, source, this) > controllerAmount; if (check) { break; }