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