diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java index c88500dbc3..579418d570 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java @@ -94,6 +94,7 @@ public class Vintage extends Constructed { restricted.add("Memory Jar"); restricted.add("Merchant Scroll"); restricted.add("Mind's Desire"); + restricted.add("Monastery Mentory"); restricted.add("Mox Emerald"); restricted.add("Mox Jet"); restricted.add("Mox Pearl"); @@ -104,6 +105,7 @@ public class Vintage extends Constructed { restricted.add("Ponder"); restricted.add("Sol Ring"); restricted.add("Strip Mine"); + restricted.add("Thorn of Amethyst"); restricted.add("Time Vault"); restricted.add("Time Walk"); restricted.add("Timetwister"); @@ -114,7 +116,6 @@ public class Vintage extends Constructed { restricted.add("Vampiric Tutor"); restricted.add("Wheel of Fortune"); restricted.add("Windfall"); - restricted.add("Yawgmoth's Bargain"); restricted.add("Yawgmoth's Will"); } diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index 985b8fc708..e1f0abd8fd 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -388,7 +388,7 @@ public class User { } else { // Table is missing after connection was lost during sideboard. // Means other players were removed or conceded the game? - logger.error("sideboarding id not found : " + entry.getKey()); + logger.debug(getName() + " reconnects during sideboarding but tableId not found: " + entry.getKey()); } } ServerMessagesUtil.instance.incReconnects(); @@ -450,12 +450,14 @@ public class User { TournamentManager.instance.quit(tournamentId, userId); } userTournaments.clear(); + constructing.clear(); logger.trace("REMOVE " + userName + " Tables " + tables.size()); for (Entry entry : tables.entrySet()) { logger.debug("-- leave tableId: " + entry.getValue().getId()); TableManager.instance.leaveTable(userId, entry.getValue().getId()); } tables.clear(); + sideboarding.clear(); logger.trace("REMOVE " + userName + " Game sessions: " + gameSessions.size()); for (GameSessionPlayer gameSessionPlayer : gameSessions.values()) { logger.debug("-- kill game session of gameId: " + gameSessionPlayer.getGameId()); diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java index 298914c94f..2b9efb3a4d 100644 --- a/Mage.Server/src/main/java/mage/server/UserManager.java +++ b/Mage.Server/src/main/java/mage/server/UserManager.java @@ -196,7 +196,7 @@ public enum UserManager { Calendar calendarRemove = Calendar.getInstance(); calendarRemove.add(Calendar.MINUTE, -8); List toRemove = new ArrayList<>(); - logger.info("Start Check Expired"); + logger.debug("Start Check Expired"); ArrayList userList = new ArrayList<>(); final Lock r = lock.readLock(); r.lock(); @@ -227,7 +227,7 @@ public enum UserManager { handleException(ex); } } - logger.info("Users to remove " + toRemove.size()); + logger.debug("Users to remove " + toRemove.size()); final Lock w = lock.readLock(); w.lock(); try { @@ -237,7 +237,7 @@ public enum UserManager { } finally { w.unlock(); } - logger.info("End Check Expired"); + logger.debug("End Check Expired"); } catch (Exception ex) { handleException(ex); } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java index cf4b16ee86..8819f262ec 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java @@ -170,9 +170,11 @@ public class TournamentSession { } private void removeTournamentForUser() { - UserManager.instance.getUser(userId).ifPresent(user - -> user.removeTournament(playerId)); - + Optional user = UserManager.instance.getUser(userId); + if (user.isPresent()) { + user.get().removeTable(playerId); + user.get().removeTournament(playerId); + } } } diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java new file mode 100644 index 0000000000..019db58bcb --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -0,0 +1,178 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetNonlandPermanent; +import mage.watchers.Watcher; + +/** + * + * @author TheElk801 + */ +public class AdmiralBeckettBrass extends CardImpl { + + private final UUID originalId; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other Pirates you control"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public AdmiralBeckettBrass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Other Pirates you control get +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); + + // At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn. + Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom), TargetController.YOU, false); + ability.addTarget(new TargetNonlandPermanent()); + originalId = ability.getOriginalId(); + this.addAbility(ability, new DamagedByPiratesWatcher()); + } + + public AdmiralBeckettBrass(final AdmiralBeckettBrass card) { + super(card); + this.originalId = card.originalId; + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability.getOriginalId().equals(originalId)) { + ability.getTargets().clear(); + FilterNonlandPermanent playerFilter = new FilterNonlandPermanent("nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"); + playerFilter.add(new ControllerDealtDamageByPiratesPredicate()); + TargetNonlandPermanent target = new TargetNonlandPermanent(1, 1, playerFilter, true); + ability.addTarget(target); + } + } + + @Override + public AdmiralBeckettBrass copy() { + return new AdmiralBeckettBrass(this); + } +} + +class DamagedByPiratesWatcher extends Watcher { + + private final Map> damageSourceIds = new HashMap<>(); + + public DamagedByPiratesWatcher() { + super(DamagedByPiratesWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public DamagedByPiratesWatcher(final DamagedByPiratesWatcher watcher) { + super(watcher); + for (UUID playerId : watcher.damageSourceIds.keySet()) { + Set creatures = new HashSet<>(); + creatures.addAll(watcher.damageSourceIds.get(playerId)); + this.damageSourceIds.put(playerId, creatures); + } + } + + @Override + public DamagedByPiratesWatcher copy() { + return new DamagedByPiratesWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER && event.getFlag()) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null && creature.getSubtype(game).contains(SubType.PIRATE)) { + if (damageSourceIds.keySet().contains(event.getTargetId())) { + damageSourceIds.get(event.getTargetId()).add(creature.getId()); + } else { + Set creatureSet = new HashSet(); + creatureSet.add(creature.getId()); + damageSourceIds.put(event.getTargetId(), creatureSet); + } + } + } + } + + public boolean damagedByEnoughPirates(UUID sourceId, Game game) { + return damageSourceIds.keySet().contains(sourceId) && damageSourceIds.get(sourceId).size() > 2; + } + + @Override + public void reset() { + super.reset(); + damageSourceIds.clear(); + } +} + +class ControllerDealtDamageByPiratesPredicate implements Predicate { + + public ControllerDealtDamageByPiratesPredicate() { + } + + @Override + public boolean apply(Permanent input, Game game) { + DamagedByPiratesWatcher watcher = (DamagedByPiratesWatcher) game.getState().getWatchers().get(DamagedByPiratesWatcher.class.getSimpleName()); + if (watcher != null) { + return watcher.damagedByEnoughPirates(input.getControllerId(), game); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/a/AlphaTyrranax.java b/Mage.Sets/src/mage/cards/a/AlphaTyrranax.java index ad52403a27..70f3a694f3 100644 --- a/Mage.Sets/src/mage/cards/a/AlphaTyrranax.java +++ b/Mage.Sets/src/mage/cards/a/AlphaTyrranax.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.a; import java.util.UUID; @@ -41,15 +40,16 @@ import mage.constants.SubType; */ public class AlphaTyrranax extends CardImpl { - public AlphaTyrranax (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); + public AlphaTyrranax(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); this.subtype.add(SubType.BEAST); this.power = new MageInt(6); this.toughness = new MageInt(5); } - public AlphaTyrranax (final AlphaTyrranax card) { + public AlphaTyrranax(final AlphaTyrranax card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java b/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java new file mode 100644 index 0000000000..5ad32f20df --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.FatefulHourCondition; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.t.TempleOfAclazotz; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class ArguelsBloodFast extends CardImpl { + + public ArguelsBloodFast(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); + + addSuperType(SuperType.LEGENDARY); + this.transformable = true; + this.secondSideCardClazz = TempleOfAclazotz.class; + + // {1}{B}, Pay 2 life: Draw a card. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}")); + ability.addCost(new PayLifeCost(2)); + this.addAbility(ability); + + // At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast. + this.addAbility(new TransformAbility()); + this.addAbility(new ConditionalTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, true), + FatefulHourCondition.instance, + "At the beginning of your upkeep, if you have 5 or less life, you may transform {this}" + )); + } + + public ArguelsBloodFast(final ArguelsBloodFast card) { + super(card); + } + + @Override + public ArguelsBloodFast copy() { + return new ArguelsBloodFast(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java b/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java new file mode 100644 index 0000000000..6591636360 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java @@ -0,0 +1,110 @@ +/* + * 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.cards.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author TheElk801 + */ +public class AshesOfTheAbhorrent extends CardImpl { + + public AshesOfTheAbhorrent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + // Players can't cast spells from graveyards or activate abilities from graveyards. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AshesOfTheAbhorrentEffect())); + + // Whenever a creature dies, you gain 1 life. + this.addAbility(new DiesCreatureTriggeredAbility(new GainLifeEffect(1), false)); + } + + public AshesOfTheAbhorrent(final AshesOfTheAbhorrent card) { + super(card); + } + + @Override + public AshesOfTheAbhorrent copy() { + return new AshesOfTheAbhorrent(this); + } +} + +class AshesOfTheAbhorrentEffect extends ContinuousRuleModifyingEffectImpl { + + public AshesOfTheAbhorrentEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + staticText = "Players can't cast spells from graveyards or activate abilities from graveyards"; + } + + public AshesOfTheAbhorrentEffect(final AshesOfTheAbhorrentEffect effect) { + super(effect); + } + + @Override + public AshesOfTheAbhorrentEffect copy() { + return new AshesOfTheAbhorrentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL + || event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Card card = game.getCard(event.getSourceId()); + if (card != null) { + Zone zone = game.getState().getZone(card.getId()); + if (zone != null && (zone == Zone.GRAVEYARD)) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java index 19b501fc9f..b9348f249a 100644 --- a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java +++ b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java @@ -30,12 +30,10 @@ package mage.cards.a; import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.costs.common.TapTargetCost; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.KickerAbility; import mage.abilities.keyword.TrampleAbility; import mage.abilities.text.TextPartSubType; import mage.cards.CardImpl; @@ -48,7 +46,6 @@ import mage.filter.predicate.permanent.TappedPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.target.common.TargetControlledCreaturePermanent; import mage.target.targetpointer.FixedTarget; /** @@ -75,7 +72,6 @@ public class AtarkaWorldRender extends CardImpl { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Dragon you control"); filter.add(new TextPartSubtypePredicate(textPart1)); filter.add(Predicates.not(new TappedPredicate())); - this.addAbility(new KickerAbility(new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)))); this.addAbility(new AtarkaWorldRenderEffect(filter)); } diff --git a/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java b/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java index c91caa44ee..c056da0ca2 100644 --- a/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java +++ b/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java @@ -33,7 +33,7 @@ import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -57,7 +57,7 @@ public class BackFromTheBrink extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}{U}"); // Exile a creature card from your graveyard and pay its mana cost: Create a token that's a copy of that card. Activate this ability only any time you could cast a sorcery. - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setText("create a token that's a copy of that card"); this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, effect, new BackFromTheBrinkCost())); diff --git a/Mage.Sets/src/mage/cards/b/Bedlam.java b/Mage.Sets/src/mage/cards/b/Bedlam.java index 0baceb297d..ccee7bc212 100644 --- a/Mage.Sets/src/mage/cards/b/Bedlam.java +++ b/Mage.Sets/src/mage/cards/b/Bedlam.java @@ -25,18 +25,19 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.b; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.combat.CantBlockAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; @@ -47,11 +48,10 @@ import mage.game.permanent.Permanent; public class Bedlam extends CardImpl { public Bedlam(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}"); // Creatures can't block. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BedlamEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES, Duration.WhileOnBattlefield))); } public Bedlam(final Bedlam card) { @@ -63,33 +63,3 @@ public class Bedlam extends CardImpl { return new Bedlam(this); } } - -class BedlamEffect extends RestrictionEffect { - - BedlamEffect() { - super(Duration.WhileOnBattlefield); - staticText = "Creatures can't block"; - } - - BedlamEffect(final BedlamEffect effect) { - super(effect); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - if (permanent.isCreature()) { - return true; - } - return false; - } - - @Override - public BedlamEffect copy() { - return new BedlamEffect(this); - } - - @Override - public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java new file mode 100644 index 0000000000..81647dab15 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java @@ -0,0 +1,109 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; + +/** + * + * @author TheElk801 + */ +public class BelligerentBrontodon extends CardImpl { + + public BelligerentBrontodon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(4); + this.toughness = new MageInt(6); + + // Each creature you control assigns combat damage equal to its toughness rather than its power. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MilitantDinosaurCombatDamageRuleEffect())); + } + + public BelligerentBrontodon(final BelligerentBrontodon card) { + super(card); + } + + @Override + public BelligerentBrontodon copy() { + return new BelligerentBrontodon(this); + } +} + +class MilitantDinosaurCombatDamageRuleEffect extends ContinuousEffectImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public MilitantDinosaurCombatDamageRuleEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Each creature you control assigns combat damage equal to its toughness rather than its power"; + } + + public MilitantDinosaurCombatDamageRuleEffect(final MilitantDinosaurCombatDamageRuleEffect effect) { + super(effect); + } + + @Override + public MilitantDinosaurCombatDamageRuleEffect copy() { + return new MilitantDinosaurCombatDamageRuleEffect(this); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + // Change the rule + game.getCombat().setUseToughnessForDamage(true); + game.getCombat().addUseToughnessForDamageFilter(filter); + return true; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.RulesEffects; + } +} diff --git a/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java new file mode 100644 index 0000000000..c0c4bbdf4a --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java @@ -0,0 +1,78 @@ +/* + * 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.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class BellowingAegisaur extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each other creature you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new AnotherPredicate()); + } + + public BellowingAegisaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Enrage - Whenever Bellowing Aegisaur is dealt damage, put a +1/+1 counter on each other creature you control. + Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, true); + this.addAbility(ability); + } + + public BellowingAegisaur(final BellowingAegisaur card) { + super(card); + } + + @Override + public BellowingAegisaur copy() { + return new BellowingAegisaur(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java b/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java index 10c5aab52a..98d934b7c5 100644 --- a/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java +++ b/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java @@ -30,7 +30,7 @@ package mage.cards.b; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; @@ -81,7 +81,7 @@ public class BloodforgedBattleAxe extends CardImpl { class BloodforgedBattleAxeAbility extends TriggeredAbilityImpl { public BloodforgedBattleAxeAbility() { - super(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopySourceEffect()); + super(Zone.BATTLEFIELD, new CreateTokenCopySourceEffect()); } public BloodforgedBattleAxeAbility(final BloodforgedBattleAxeAbility ability) { diff --git a/Mage.Sets/src/mage/cards/b/BoneyardParley.java b/Mage.Sets/src/mage/cards/b/BoneyardParley.java new file mode 100644 index 0000000000..74874f678a --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BoneyardParley.java @@ -0,0 +1,162 @@ +/* + * 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.cards.b; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetCard; +import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class BoneyardParley extends CardImpl { + + public BoneyardParley(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}"); + + // Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards. + this.getSpellAbility().addEffect(new BoneyardParleyEffect()); + this.getSpellAbility().addTarget(new TargetCardInGraveyard(0, 5, new FilterCard("cards from graveyards"))); + } + + public BoneyardParley(final BoneyardParley card) { + super(card); + } + + @Override + public BoneyardParley copy() { + return new BoneyardParley(this); + } +} + +class BoneyardParleyEffect extends OneShotEffect { + + BoneyardParleyEffect() { + super(Outcome.Benefit); + this.staticText = "Exile up to five target creature cards from graveyards. " + + "An opponent separates those cards into two piles. " + + "Put all cards from the pile of your choice onto the battlefield under your control " + + "and the rest into their owners' graveyards"; + } + + BoneyardParleyEffect(final BoneyardParleyEffect effect) { + super(effect); + } + + @Override + public BoneyardParleyEffect copy() { + return new BoneyardParleyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + Cards cards = new CardsImpl(); + for (Target target : source.getTargets()) { + for (UUID cardId : target.getTargets()) { + cards.add(cardId); + } + } + if (!cards.isEmpty() && player.moveCards(cards, Zone.EXILED, source, game)) { + TargetOpponent targetOpponent = new TargetOpponent(true); + if (player.choose(Outcome.Neutral, targetOpponent, source.getSourceId(), game)) { + Player opponent = game.getPlayer(targetOpponent.getFirstTarget()); + if (opponent != null) { + TargetCard targetCards = new TargetCard(0, cards.size(), Zone.EXILED, new FilterCard("cards to put in the first pile")); + List pile1 = new ArrayList<>(); + if (opponent.choose(Outcome.Neutral, cards, targetCards, game)) { + List targets = targetCards.getTargets(); + for (UUID targetId : targets) { + Card card = cards.get(targetId, game); + if (card != null) { + pile1.add(card); + cards.remove(card); + } + } + } + List pile2 = new ArrayList<>(); + pile2.addAll(cards.getCards(game)); + boolean choice = player.choosePile(outcome, "Choose a pile to put onto the battlefield.", pile1, pile2, game); + + Zone pile1Zone = Zone.GRAVEYARD; + Zone pile2Zone = Zone.BATTLEFIELD; + if (choice) { + pile1Zone = Zone.BATTLEFIELD; + pile2Zone = Zone.GRAVEYARD; + } + Set pile1Set = new HashSet<>(); + Set pile2Set = new HashSet<>(); + pile1Set.addAll(pile1); + pile2Set.addAll(pile2); + +// Cards toBattlefield = new CardsImpl(); +// Cards toGraveyard = new CardsImpl(); +// +// if (pile1Zone == Zone.BATTLEFIELD) { +// toBattlefield.addAll(pile1); +// toGraveyard.addAll(pile2); +// } else { +// toBattlefield.addAll(pile2); +// toGraveyard.addAll(pile1); +// } + player.moveCards(pile1Set, pile1Zone, source, game, false, false, false, null); + player.moveCards(pile2Set, pile2Zone, source, game, false, false, false, null); + +// StringBuilder sb = new StringBuilder("Pile 1, going to ").append(pile1Zone == Zone.BATTLEFIELD ? "Battlefield" : "Graveyard").append(": "); +// game.informPlayers(sb.toString()); +// sb = new StringBuilder("Pile 2, going to ").append(pile2Zone == Zone.BATTLEFIELD ? "Battlefield" : "Graveyard").append(':'); +// game.informPlayers(sb.toString()); + } + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java b/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java index 22c7c059e9..1db428edc3 100644 --- a/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java +++ b/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java @@ -29,7 +29,7 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.FlashbackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -46,7 +46,7 @@ public class CacklingCounterpart extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}{U}"); // Create a token that's a copy of target creature you control. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); // Flashback {5}{U}{U} diff --git a/Mage.Sets/src/mage/cards/c/CallToTheFeast.java b/Mage.Sets/src/mage/cards/c/CallToTheFeast.java new file mode 100644 index 0000000000..9408afd4ef --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CallToTheFeast.java @@ -0,0 +1,58 @@ +/* + * 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.cards.c; + +import java.util.UUID; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.IxalanVampireToken; + +/** + * + * @author TheElk801 + */ +public class CallToTheFeast extends CardImpl { + + public CallToTheFeast(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}{B}"); + + // Create three 1/1 white Vampire creature tokens with lifelink. + this.getSpellAbility().addEffect(new CreateTokenEffect(new IxalanVampireToken(), 3)); + } + + public CallToTheFeast(final CallToTheFeast card) { + super(card); + } + + @Override + public CallToTheFeast copy() { + return new CallToTheFeast(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CastawaysDespair.java b/Mage.Sets/src/mage/cards/c/CastawaysDespair.java new file mode 100644 index 0000000000..92fd4ac9dc --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CastawaysDespair.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.cards.c; + +import java.util.UUID; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; +import mage.abilities.effects.common.TapEnchantedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class CastawaysDespair extends CardImpl { + + public CastawaysDespair(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); + + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When Castaway's Despair enters the battlefield, tap enchanted creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect())); + + // Enchanted creature doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect())); + } + + public CastawaysDespair(final CastawaysDespair card) { + super(card); + } + + @Override + public CastawaysDespair copy() { + return new CastawaysDespair(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java b/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java index 93d012fc42..261f27f1fe 100644 --- a/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java +++ b/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java @@ -64,7 +64,7 @@ public class CaughtInTheBrights extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.LoseAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/c/Chronozoa.java b/Mage.Sets/src/mage/cards/c/Chronozoa.java index 39fdd61b6f..8d3980b5e3 100644 --- a/Mage.Sets/src/mage/cards/c/Chronozoa.java +++ b/Mage.Sets/src/mage/cards/c/Chronozoa.java @@ -35,7 +35,7 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.LastTimeCounterRemovedCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VanishingSacrificeAbility; @@ -69,7 +69,7 @@ public class Chronozoa extends CardImpl { this.addAbility(new VanishingSacrificeAbility()); // When Chronozoa is put into a graveyard from play, if it had no time counters on it, create two tokens that are copies of it. - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(2); + Effect effect = new CreateTokenCopySourceEffect(2); effect.setText("create two tokens that are copies of it"); this.addAbility(new ConditionalTriggeredAbility(new DiesTriggeredAbility(effect, false), LastTimeCounterRemovedCondition.instance, diff --git a/Mage.Sets/src/mage/cards/c/CloneLegion.java b/Mage.Sets/src/mage/cards/c/CloneLegion.java index cfe1eecbdd..423b0c22ff 100644 --- a/Mage.Sets/src/mage/cards/c/CloneLegion.java +++ b/Mage.Sets/src/mage/cards/c/CloneLegion.java @@ -30,7 +30,7 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -90,7 +90,7 @@ class CloneLegionEffect extends OneShotEffect { if (controller != null && targetPlayer != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, targetPlayer.getId(), game)) { if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java index e96f8e13bc..811512b53e 100644 --- a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java +++ b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java @@ -28,6 +28,7 @@ package mage.cards.c; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -36,7 +37,12 @@ import mage.abilities.effects.common.ruleModifying.TargetsHaveToTargetPermanentI import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -50,7 +56,7 @@ public class CoalitionFlag extends CardImpl { public CoalitionFlag(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); - this.subtype.add("Aura"); + this.subtype.add(SubType.AURA); // Enchant creature you control TargetPermanent auraTarget = new TargetCreaturePermanent(); @@ -60,7 +66,7 @@ public class CoalitionFlag extends CardImpl { this.addAbility(ability); // Enchanted creature is a Flagbearer. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.FLAGBEARER, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA, SubType.FLAGBEARER))); // While choosing targets as part of casting a spell or activating an ability, your opponents must choose at least one Flagbearer on the battlefield if able. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TargetsHaveToTargetPermanentIfAbleEffect(new FilterPermanent(SubType.FLAGBEARER, "one Flagbearer")))); diff --git a/Mage.Sets/src/mage/cards/c/CogworkAssembler.java b/Mage.Sets/src/mage/cards/c/CogworkAssembler.java index 0432779b8b..7aa000630d 100644 --- a/Mage.Sets/src/mage/cards/c/CogworkAssembler.java +++ b/Mage.Sets/src/mage/cards/c/CogworkAssembler.java @@ -36,7 +36,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -96,7 +96,7 @@ class CogworkAssemblerCreateTokenEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent copiedPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (copiedPermanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ARTIFACT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ARTIFACT, true); if (effect.apply(game, source)) { for (Permanent copyPermanent : effect.getAddedPermanent()) { ExileTargetEffect exileEffect = new ExileTargetEffect(); diff --git a/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java b/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java new file mode 100644 index 0000000000..0c50dac919 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.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.cards.c; + +import java.util.UUID; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author TheElk801 + */ +public class ConquerorsFoothold extends CardImpl { + + public ConquerorsFoothold(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.nightCard = true; + + // {T}: Add {C} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {2}, {T}: Draw a card, then discard a card. + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DrawDiscardControllerEffect(), + new ManaCostsImpl("{2}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + // {4}, {T}: Draw a card. + SimpleActivatedAbility ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DrawCardSourceControllerEffect(1), + new ManaCostsImpl("{4}")); + ability2.addCost(new TapSourceCost()); + this.addAbility(ability2); + + // {6}, {T}: Return target card from your graveyard to your hand. + SimpleActivatedAbility ability3 = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new ReturnToHandTargetEffect(), + new ManaCostsImpl("{6}")); + ability3.addCost(new TapSourceCost()); + ability3.addTarget(new TargetCardInYourGraveyard()); + this.addAbility(ability3); + } + + public ConquerorsFoothold(final ConquerorsFoothold card) { + super(card); + } + + @Override + public ConquerorsFoothold copy() { + return new ConquerorsFoothold(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ConquerorsGalleon.java b/Mage.Sets/src/mage/cards/c/ConquerorsGalleon.java new file mode 100644 index 0000000000..beefa13d4d --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConquerorsGalleon.java @@ -0,0 +1,78 @@ +/* + * 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.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileAndReturnTransformedSourceEffect; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class ConquerorsGalleon extends CardImpl { + + public ConquerorsGalleon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + this.subtype.add("Vehicle"); + this.power = new MageInt(2); + this.toughness = new MageInt(10); + + this.transformable = true; + this.secondSideCardClazz = ConquerorsFoothold.class; + + // When Conqueror's Galleon attacks, exile it at the end of combat, then return it to the battlefield transformed under your control. + this.addAbility(new TransformAbility()); + this.addAbility(new AttacksTriggeredAbility( + new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new ExileAndReturnTransformedSourceEffect())), + false, + "When {this} attacks, exile it at the end of combat, then return it to the battlefield transformed under your control.")); + + // Crew 4 + this.addAbility(new CrewAbility(4)); + } + + public ConquerorsGalleon(final ConquerorsGalleon card) { + super(card); + } + + @Override + public ConquerorsGalleon copy() { + return new ConquerorsGalleon(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java index 137ec3a036..64938d9c4a 100644 --- a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java +++ b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java @@ -97,7 +97,7 @@ class CrimsonHonorGuardEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(game.getActivePlayerId()); if (player != null) { - int numCommanders = game.getBattlefield().getActivePermanents(filter, player.getId(), game).size(); + int numCommanders = game.getBattlefield().getAllActivePermanents(filter, player.getId(), game).size(); if (numCommanders == 0) { player.damage(4, source.getSourceId(), game, false, true); return true; diff --git a/Mage.Sets/src/mage/cards/d/DanceOfMany.java b/Mage.Sets/src/mage/cards/d/DanceOfMany.java index 62f2f7ea4f..773f801ac3 100644 --- a/Mage.Sets/src/mage/cards/d/DanceOfMany.java +++ b/Mage.Sets/src/mage/cards/d/DanceOfMany.java @@ -38,7 +38,7 @@ import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.InfoEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; @@ -114,7 +114,7 @@ class DanceOfManyCreateTokenCopyEffect extends OneShotEffect { Permanent sourceObject = game.getPermanent(source.getSourceId()); if (permanent != null && sourceObject != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); game.getState().setValue(source.getSourceId() + "_token", effect.getAddedPermanent()); diff --git a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java index 839b49512d..8da715a5dc 100644 --- a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java +++ b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java @@ -36,7 +36,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -87,7 +87,7 @@ public class DarettiIngeniousIconoclast extends CardImpl { // -6: Choose target artifact card in a graveyard or artifact on the battlefield. Create three tokens that are copies of it. ability = new LoyaltyAbility( - new PutTokenOntoBattlefieldCopyTargetEffect(null, null, false, 3), + new CreateTokenCopyTargetEffect(null, null, false, 3), -6); ability.addTarget(new TargetCardInGraveyardOrBattlefield(new FilterArtifactCard("artifact card in a graveyard or artifact on the battlefield"))); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/d/DeadeyePlunderers.java b/Mage.Sets/src/mage/cards/d/DeadeyePlunderers.java new file mode 100644 index 0000000000..6c20494978 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeadeyePlunderers.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.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author TheElk801 + */ +public class DeadeyePlunderers extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("artifact you control"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public DeadeyePlunderers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Deadeye Plunderers gets +1/+1 for each artifact you control. + PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(count, count, Duration.WhileOnBattlefield))); + + // {2}{U}{B}: Create a colorless artifact token named Treasure with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new TreasureToken()), new ManaCostsImpl("{2}{U}{B}"))); + } + + public DeadeyePlunderers(final DeadeyePlunderers card) { + super(card); + } + + @Override + public DeadeyePlunderers copy() { + return new DeadeyePlunderers(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java new file mode 100644 index 0000000000..c51e6b9da0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class DeadeyeQuartermaster extends CardImpl { + + private static final FilterCard filter = new FilterCard("an Equipment or Vehicle card"); + + static { + filter.add(Predicates.or(new SubtypePredicate(SubType.EQUIPMENT), new SubtypePredicate(SubType.EQUIPMENT))); + } + + public DeadeyeQuartermaster(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Deadeye Quartermaster enters the battlefield, you may search your library for an Equipment or a Vehicle card and put it into your hand. If you do, shuffle your library. + TargetCardInLibrary target = new TargetCardInLibrary(1, 1, filter); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); + } + + public DeadeyeQuartermaster(final DeadeyeQuartermaster card) { + super(card); + } + + @Override + public DeadeyeQuartermaster copy() { + return new DeadeyeQuartermaster(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DeathlessAncient.java b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java new file mode 100644 index 0000000000..eb88cb4450 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author caldover + */ +public class DeathlessAncient extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("untapped Vampires you control"); + + static { + filter.add(Predicates.not(new TappedPredicate())); + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + } + + public DeathlessAncient(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + + this.subtype.add("Vampire"); + this.subtype.add("Knight"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand. + this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new TapTargetCost(new TargetControlledPermanent(3, 3, filter, true)))); + + } + + public DeathlessAncient(final DeathlessAncient card) { + super(card); + } + + @Override + public DeathlessAncient copy() { + return new DeathlessAncient(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java b/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java index e0d8cdeefd..0eea387ca7 100644 --- a/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java +++ b/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java @@ -41,6 +41,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; @@ -53,9 +54,9 @@ import mage.players.Player; public class DeathmistRaptor extends CardImpl { public DeathmistRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); - this.subtype.add("Lizard"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/d/DeeprootWaters.java b/Mage.Sets/src/mage/cards/d/DeeprootWaters.java new file mode 100644 index 0000000000..f1c3aa6b8f --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeeprootWaters.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.cards.d; + +import java.util.UUID; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.permanent.token.MerfolkHexproofToken; + +/** + * + * @author TacomenX + */ +public class DeeprootWaters extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("a Merfolk spell"); + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + } + + public DeeprootWaters(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + + // Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof. + this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new MerfolkHexproofToken()), filter, false)); + } + + public DeeprootWaters(final DeeprootWaters card) { + super(card); + } + + @Override + public DeeprootWaters copy() { + return new DeeprootWaters(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java b/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java new file mode 100644 index 0000000000..1c0b87f4ff --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java @@ -0,0 +1,78 @@ +/* + * 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.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author TheElk801 + */ +public class DireFleetCaptain extends CardImpl { + + private static final FilterAttackingCreature filter = new FilterAttackingCreature("other attacking Pirate"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new AnotherPredicate()); + } + + public DireFleetCaptain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}"); + + this.subtype.add("Orc"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Dire Fleet Captain attacks, it gets +1/+1 until end of turn for each other attacking Pirate. + PermanentsOnBattlefieldCount value = new PermanentsOnBattlefieldCount(filter); + this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(value, value, Duration.EndOfTurn, true), false)); + } + + public DireFleetCaptain(final DireFleetCaptain card) { + super(card); + } + + @Override + public DireFleetCaptain copy() { + return new DireFleetCaptain(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/Dromosaur.java b/Mage.Sets/src/mage/cards/d/Dromosaur.java index a154addcd3..18966f7110 100644 --- a/Mage.Sets/src/mage/cards/d/Dromosaur.java +++ b/Mage.Sets/src/mage/cards/d/Dromosaur.java @@ -35,6 +35,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; /** * @@ -43,8 +44,8 @@ import mage.constants.Duration; public class Dromosaur extends CardImpl { public Dromosaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(2); this.toughness = new MageInt(3); @@ -61,4 +62,4 @@ public class Dromosaur extends CardImpl { public Dromosaur copy() { return new Dromosaur(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java new file mode 100644 index 0000000000..ca6476f76f --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java @@ -0,0 +1,78 @@ +/* + * 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.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostSourceWhileControlsEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class DroverOfTheMighty extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("a Dinosaur"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public DroverOfTheMighty(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add("Human"); + this.subtype.add("Druid"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Drover of the Mighty gets +2/+2 as long as you control a Dinosaur. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceWhileControlsEffect(filter, 2, 2))); + + // {T}: Add one mana of any color to your mana pool. + this.addAbility(new AnyColorManaAbility()); + } + + public DroverOfTheMighty(final DroverOfTheMighty card) { + super(card); + } + + @Override + public DroverOfTheMighty copy() { + return new DroverOfTheMighty(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java b/Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java new file mode 100644 index 0000000000..8af6045cd3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java @@ -0,0 +1,68 @@ +/* + * 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.cards.d; + +import java.util.UUID; + +import mage.MageInt; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class DuskLegionDreadnought extends CardImpl { + + public DuskLegionDreadnought(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); + + this.subtype.add("Vehicle"); + this.power = new MageInt(4); + this.toughness = new MageInt(6); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Crew 2 + this.addAbility(new CrewAbility(2)); + + } + + public DuskLegionDreadnought(final DuskLegionDreadnought card) { + super(card); + } + + @Override + public DuskLegionDreadnought copy() { + return new DuskLegionDreadnought(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java new file mode 100644 index 0000000000..43b9623fc8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.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.cards.d; + +import java.util.UUID; +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.continuous.BoostTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class DuskborneSkymarcher extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.VAMPIRE, "attacking Vampire"); + + static { + filter.add(new AttackingPredicate()); + } + + public DuskborneSkymarcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add("Vampire"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {W}, {T}: Target attacking vampire gets +1/+1 until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{W}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public DuskborneSkymarcher(final DuskborneSkymarcher card) { + super(card); + } + + @Override + public DuskborneSkymarcher copy() { + return new DuskborneSkymarcher(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/ElderwoodScion.java b/Mage.Sets/src/mage/cards/e/ElderwoodScion.java index 87361e6c49..c008357b67 100644 --- a/Mage.Sets/src/mage/cards/e/ElderwoodScion.java +++ b/Mage.Sets/src/mage/cards/e/ElderwoodScion.java @@ -51,7 +51,7 @@ import mage.util.CardUtil; public class ElderwoodScion extends CardImpl { public ElderwoodScion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{W}"); this.subtype.add("Elemental"); this.power = new MageInt(4); @@ -139,13 +139,13 @@ class ElderwoodScionCostReductionEffect2 extends CostModificationEffectImpl { @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { SpellAbility spellAbility = (SpellAbility) abilityToModify; - CardUtil.adjustCost(spellAbility, -2); + CardUtil.increaseCost(spellAbility, 2); return true; } @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (abilityToModify instanceof SpellAbility) { + if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED) { if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { for (Target target : abilityToModify.getTargets()) { for (UUID targetUUID : target.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/f/FaerieArtisans.java b/Mage.Sets/src/mage/cards/f/FaerieArtisans.java index dd66fb2c92..8caf385e5f 100644 --- a/Mage.Sets/src/mage/cards/f/FaerieArtisans.java +++ b/Mage.Sets/src/mage/cards/f/FaerieArtisans.java @@ -33,7 +33,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -110,7 +110,7 @@ class FaerieArtisansEffect extends OneShotEffect { Permanent permanentToCopy = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && permanentToCopy != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ARTIFACT, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ARTIFACT, false); effect.setTargetPointer(new FixedTarget(permanentToCopy, game)); if (effect.apply(game, source)) { String oldTokens = (String) game.getState().getValue(source.getSourceId().toString() + source.getSourceObjectZoneChangeCounter()); diff --git a/Mage.Sets/src/mage/cards/f/FatedInfatuation.java b/Mage.Sets/src/mage/cards/f/FatedInfatuation.java index db36763b33..a5c82de3d8 100644 --- a/Mage.Sets/src/mage/cards/f/FatedInfatuation.java +++ b/Mage.Sets/src/mage/cards/f/FatedInfatuation.java @@ -30,7 +30,7 @@ package mage.cards.f; import java.util.UUID; import mage.abilities.condition.common.MyTurnCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,7 +48,7 @@ public class FatedInfatuation extends CardImpl { // Create a token that's a copy of target creature you control. If it's your turn, scry 2. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new ScryEffect(2), MyTurnCondition.instance, "If it's your turn, scry 2")); } diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java new file mode 100644 index 0000000000..5ca4677a1a --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.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.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.PirateToken; + +/** + * + * @author TheElk801 + */ +public class FathomFleetCaptain extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("another nontoken Pirate"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new AnotherPredicate()); + filter.add(Predicates.not(new TokenPredicate())); + } + + public FathomFleetCaptain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Menace + this.addAbility(new MenaceAbility()); + + // Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace. + this.addAbility(new ConditionalTriggeredAbility( + new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new PirateToken()), new GenericManaCost(2)), false), + new PermanentsOnTheBattlefieldCondition(filter), + "Whenever {this} attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace")); + } + + public FathomFleetCaptain(final FathomFleetCaptain card) { + super(card); + } + + @Override + public FathomFleetCaptain copy() { + return new FathomFleetCaptain(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java b/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java index 1903cd2290..40adbbd86f 100644 --- a/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java +++ b/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java @@ -36,7 +36,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -103,7 +103,7 @@ class FeldonOfTheThirdPathEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), CardType.ARTIFACT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), CardType.ARTIFACT, true); effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId()))); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java b/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java index 8da4e58b75..ef29cb8cf3 100644 --- a/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java +++ b/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java @@ -36,7 +36,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.InspiredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -105,7 +105,7 @@ class FelhideSpiritbinderEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ENCHANTMENT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ENCHANTMENT, true); effect.setTargetPointer(getTargetPointer()); if (effect.apply(game, source)) { for (Permanent tokenPermanent : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FlamerushRider.java b/Mage.Sets/src/mage/cards/f/FlamerushRider.java index d9f816482a..6147c56174 100644 --- a/Mage.Sets/src/mage/cards/f/FlamerushRider.java +++ b/Mage.Sets/src/mage/cards/f/FlamerushRider.java @@ -36,7 +36,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.DashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -111,7 +111,7 @@ class FlamerushRiderEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); if (controller != null && permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true, 1, true, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true, 1, true, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java b/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java index b57cb5448b..1c017740df 100644 --- a/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java +++ b/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java @@ -36,7 +36,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -105,7 +105,7 @@ class FlameshadowConjuringEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = ((FixedTarget) getTargetPointer()).getTargetedPermanentOrLKIBattlefield(game); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, null, true); effect.setTargetPointer(getTargetPointer()); if (effect.apply(game, source)) { for (Permanent tokenPermanent : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java b/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java index dc214e80eb..dd846509e2 100644 --- a/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java +++ b/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java @@ -33,7 +33,7 @@ import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -99,7 +99,7 @@ class FollowedFootstepsEffect extends OneShotEffect { Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent target = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo()); if (target != null) { - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(enchantment.getAttachedTo())); return effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/f/FracturedIdentity.java b/Mage.Sets/src/mage/cards/f/FracturedIdentity.java index 49ae7d81c0..7a7d532aa4 100644 --- a/Mage.Sets/src/mage/cards/f/FracturedIdentity.java +++ b/Mage.Sets/src/mage/cards/f/FracturedIdentity.java @@ -30,7 +30,7 @@ package mage.cards.f; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -90,7 +90,7 @@ class FracturedIdentityEffect extends OneShotEffect { permanent.moveToExile(null, null, source.getSourceId(), game); UUID controllerId = permanent.getControllerId(); for (UUID opponentId : game.getOpponents(controllerId)) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(opponentId, null, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(opponentId, null, false); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/f/FreneticRaptor.java b/Mage.Sets/src/mage/cards/f/FreneticRaptor.java new file mode 100644 index 0000000000..096276a83c --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FreneticRaptor.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.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.combat.CantBlockAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class FreneticRaptor extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.BEAST, "Beasts"); + + public FreneticRaptor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); + + this.subtype.add("Dinosaur"); + this.subtype.add("Beast"); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Beasts can't block. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockAllEffect(filter, Duration.WhileOnBattlefield))); + } + + public FreneticRaptor(final FreneticRaptor card) { + super(card); + } + + @Override + public FreneticRaptor copy() { + return new FreneticRaptor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java b/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java index fbaae28128..d1e29fd869 100644 --- a/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java +++ b/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java @@ -27,7 +27,6 @@ */ package mage.cards.f; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -41,6 +40,8 @@ import mage.constants.Duration; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -57,7 +58,7 @@ public class FrenziedGoblin extends CardImpl { // Whenever Frenzied Goblin attacks, you may pay {R}. If you do, target creature can't block this turn. Ability ability = new AttacksTriggeredAbility(new DoIfCostPaid(new CantBlockTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{R}")),false, - "Whenever {this} attacks you may pay {R}. If you do, target creature can't block this turn."); + "Whenever {this} attacks you, may pay {R}. If you do, target creature can't block this turn."); Target target = new TargetCreaturePermanent(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/f/Fungusaur.java b/Mage.Sets/src/mage/cards/f/Fungusaur.java index 54595e11b2..9b8690c443 100644 --- a/Mage.Sets/src/mage/cards/f/Fungusaur.java +++ b/Mage.Sets/src/mage/cards/f/Fungusaur.java @@ -34,6 +34,7 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; @@ -44,9 +45,9 @@ import mage.counters.CounterType; public class Fungusaur extends CardImpl { public Fungusaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); - this.subtype.add("Fungus"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.subtype.add(SubType.FUNGUS); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/g/GiantAdephage.java b/Mage.Sets/src/mage/cards/g/GiantAdephage.java index 813a91faa2..17171f9dbf 100644 --- a/Mage.Sets/src/mage/cards/g/GiantAdephage.java +++ b/Mage.Sets/src/mage/cards/g/GiantAdephage.java @@ -30,7 +30,7 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -53,7 +53,7 @@ public class GiantAdephage extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever Giant Adephage deals combat damage to a player, create a token that is a copy of Giant Adephage. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new PutTokenOntoBattlefieldCopySourceEffect(), false)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenCopySourceEffect(), false)); } diff --git a/Mage.Sets/src/mage/cards/g/GoringCeratops.java b/Mage.Sets/src/mage/cards/g/GoringCeratops.java new file mode 100644 index 0000000000..0a05aa811d --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoringCeratops.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.StaticFilters; + +/** + * + * @author caldover + */ +public class GoringCeratops extends CardImpl { + + public GoringCeratops(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Double Strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn. + Effect effect = new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE, true); + effect.setText("other creatures you control gain double strike"); + Ability ability = new AttacksTriggeredAbility(effect, false); + this.addAbility(ability); + } + + public GoringCeratops(final GoringCeratops card) { + super(card); + } + + @Override + public GoringCeratops copy() { + return new GoringCeratops(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GraspingCurrent.java b/Mage.Sets/src/mage/cards/g/GraspingCurrent.java new file mode 100644 index 0000000000..cbc5d71444 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GraspingCurrent.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.cards.g; + +import java.util.UUID; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class GraspingCurrent extends CardImpl { + + private final static FilterCard filter = new FilterCard("Jace, Ingenious Mind-Mage"); + + static { + filter.add(new NamePredicate("Jace, Ingenious Mind-Mage")); + } + + public GraspingCurrent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}"); + + // Return up to two target creatures to their owner's hand. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + + // Search your library and/or graveyard for a card named Jace, Ingenious Mind-Mage, reveal it, then put it into your hand. If you searched your library this way, shuffle it. + this.getSpellAbility().addEffect(new SearchLibraryGraveyardPutInHandEffect(filter)); + } + + public GraspingCurrent(final GraspingCurrent card) { + super(card); + } + + @Override + public GraspingCurrent copy() { + return new GraspingCurrent(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java index bf163641dc..60786e5e2e 100644 --- a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java +++ b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java @@ -54,7 +54,7 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.ExileZone; import mage.game.Game; -import mage.game.events.DamageEvent; +import mage.game.events.DamagedEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.ManaPoolItem; @@ -125,7 +125,7 @@ class GrenzoHavocRaiserTriggeredAbility extends TriggeredAbilityImpl { Player damagedPlayer = game.getPlayer(event.getPlayerId()); Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (damagedPlayer != null && permanent != null - && ((DamageEvent) event).isCombatDamage() + && ((DamagedEvent) event).isCombatDamage() && getControllerId().equals(permanent.getControllerId())) { FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + damagedPlayer.getLogName() + " controls"); filter.add(new ControllerIdPredicate(damagedPlayer.getId())); diff --git a/Mage.Sets/src/mage/cards/h/HeadwaterSentries.java b/Mage.Sets/src/mage/cards/h/HeadwaterSentries.java new file mode 100644 index 0000000000..26b86e7e65 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeadwaterSentries.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class HeadwaterSentries extends CardImpl { + + public HeadwaterSentries(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add("Merfolk"); + this.subtype.add("Warrior"); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + } + + public HeadwaterSentries(final HeadwaterSentries card) { + super(card); + } + + @Override + public HeadwaterSentries copy() { + return new HeadwaterSentries(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HeatShimmer.java b/Mage.Sets/src/mage/cards/h/HeatShimmer.java index 76e1cacb42..68967ad6ab 100644 --- a/Mage.Sets/src/mage/cards/h/HeatShimmer.java +++ b/Mage.Sets/src/mage/cards/h/HeatShimmer.java @@ -34,7 +34,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -90,7 +90,7 @@ class HeatShimmerEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); if (controller != null && permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/h/HostageTaker.java b/Mage.Sets/src/mage/cards/h/HostageTaker.java new file mode 100644 index 0000000000..c4457ce74b --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HostageTaker.java @@ -0,0 +1,225 @@ +/* + * 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.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.AsThoughManaEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.ManaType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.ManaPoolItem; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class HostageTaker extends CardImpl { + + private final static FilterPermanent filter = new FilterPermanent("another target artifact or creature"); + + static { + filter.add(new AnotherPredicate()); + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE))); + } + + public HostageTaker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell. + Ability ability = new EntersBattlefieldTriggeredAbility(new HostageTakerExileEffect(filter.getMessage())); + ability.addTarget(new TargetPermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + this.addAbility(ability); + } + + public HostageTaker(final HostageTaker card) { + super(card); + } + + @Override + public HostageTaker copy() { + return new HostageTaker(this); + } +} + +class HostageTakerExileEffect extends OneShotEffect { + + public HostageTakerExileEffect(String targetName) { + super(Outcome.Benefit); + this.staticText = "exile another target artifact or creature until {this} leaves the battlefield. " + + "You may cast that card as long as it remains exiled, " + + "and you may spend mana as though it were mana of any type to cast that spell"; + } + + public HostageTakerExileEffect(final HostageTakerExileEffect effect) { + super(effect); + } + + @Override + public HostageTakerExileEffect copy() { + return new HostageTakerExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent card = game.getPermanent(targetPointer.getFirst(game, source)); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && card != null) { + Player controller = game.getPlayer(card.getControllerId()); + if (controller != null) { + // move card to exile + UUID exileId = CardUtil.getCardExileZoneId(game, source); + controller.moveCardToExileWithInfo(card, exileId, permanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); + // allow to cast the card + ContinuousEffect effect = new HostageTakerCastFromExileEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + // and you may spend mana as though it were mana of any color to cast it + effect = new HostageTakerSpendAnyManaEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } + } + return false; + } +} + +class HostageTakerCastFromExileEffect extends AsThoughEffectImpl { + + public HostageTakerCastFromExileEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); + staticText = "You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell"; + } + + public HostageTakerCastFromExileEffect(final HostageTakerCastFromExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public HostageTakerCastFromExileEffect copy() { + return new HostageTakerCastFromExileEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (objectId.equals(getTargetPointer().getFirst(game, source))) { + if (affectedControllerId.equals(source.getControllerId())) { + return true; + } + } else { + if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { + // object has moved zone so effect can be discarted + this.discard(); + } + } + return false; + } +} + +class HostageTakerSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { + + public HostageTakerSpendAnyManaEffect() { + super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit); + staticText = "you may spend mana as though it were mana of any color to cast it"; + } + + public HostageTakerSpendAnyManaEffect(final HostageTakerSpendAnyManaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public HostageTakerSpendAnyManaEffect copy() { + return new HostageTakerSpendAnyManaEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) + && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { + + if (affectedControllerId.equals(source.getControllerId())) { + // if the card moved from exile to spell the zone change counter is increased by 1 + if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { + return true; + } + } + + } else { + if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { + // object has moved zone so effect can be discarted + this.discard(); + } + } + return false; + } + + @Override + public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { + return mana.getFirstAvailable(); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java b/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java new file mode 100644 index 0000000000..51fa9e6ecd --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java @@ -0,0 +1,176 @@ +/* + * 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.cards.h; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.Mode; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.PayVariableLoyaltyCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.GreatestPowerAmongControlledCreaturesValue; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.combat.CantBlockTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.DinosaurToken; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanentAmount; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class HuatliWarriorPoet extends CardImpl { + + public HuatliWarriorPoet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{R}{W}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUATLI); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); + + // +2: You gain life equal to the greatest power among creatures you control. + this.addAbility(new LoyaltyAbility(new GainLifeEffect(new GreatestPowerAmongControlledCreaturesValue(), "You gain life equal to the greatest power among creatures you control"), 2)); + + // 0: Create a 3/3 green Dinosaur creature token with trample. + this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new DinosaurToken()), 0)); + + // -X: Huatli, Warrior Poet deals X damage divided as you choose among any number of target creatures. Creatures dealt damage this way can't block this turn. + Ability ability = new LoyaltyAbility(new HuatliWarriorPoetDamageEffect(new HuatliXValue())); + ability.addTarget(new TargetCreaturePermanentAmount(new HuatliXValue())); + this.addAbility(ability); + } + + public HuatliWarriorPoet(final HuatliWarriorPoet card) { + super(card); + } + + @Override + public HuatliWarriorPoet copy() { + return new HuatliWarriorPoet(this); + } +} + +class HuatliXValue implements DynamicValue { + + private static final HuatliXValue defaultValue = new HuatliXValue(); + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + for (Cost cost : sourceAbility.getCosts()) { + if (cost instanceof PayVariableLoyaltyCost) { + return ((PayVariableLoyaltyCost) cost).getAmount(); + } + } + return 0; + } + + @Override + public DynamicValue copy() { + return defaultValue; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "X"; + } + + public static HuatliXValue getDefault() { + return defaultValue; + } +} + +class HuatliWarriorPoetDamageEffect extends OneShotEffect { + + protected DynamicValue amount; + + public HuatliWarriorPoetDamageEffect(DynamicValue amount) { + super(Outcome.Damage); + this.amount = amount; + } + + public HuatliWarriorPoetDamageEffect(final HuatliWarriorPoetDamageEffect effect) { + super(effect); + this.amount = effect.amount; + } + + @Override + public HuatliWarriorPoetDamageEffect copy() { + return new HuatliWarriorPoetDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (!source.getTargets().isEmpty()) { + Target multiTarget = source.getTargets().get(0); + for (UUID target : multiTarget.getTargets()) { + Permanent permanent = game.getPermanent(target); + if (permanent != null && permanent.damage(multiTarget.getTargetAmount(target), source.getSourceId(), game, false, true) > 0) { + ContinuousEffect effect = new CantBlockTargetEffect(Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + } + } + } + return true; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + return "{source} deals " + + amount.toString() + + " damage divided as you choose among any number of target " + + mode.getTargets().get(0).getTargetName() + + ". Creatures dealt damage this way can't block this turn"; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java b/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java new file mode 100644 index 0000000000..74a2c6ea24 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java @@ -0,0 +1,64 @@ +/* + * 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.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class HuatlisSnubhorn extends CardImpl { + + public HuatlisSnubhorn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + } + + public HuatlisSnubhorn(final HuatlisSnubhorn card) { + super(card); + } + + @Override + public HuatlisSnubhorn copy() { + return new HuatlisSnubhorn(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HuatlisSpurring.java b/Mage.Sets/src/mage/cards/h/HuatlisSpurring.java new file mode 100644 index 0000000000..0346ac0dc4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HuatlisSpurring.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.cards.h; + +import java.util.UUID; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class HuatlisSpurring extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("a Jace planeswalker"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new CardTypePredicate(CardType.PLANESWALKER)); + filter.add(new SubtypePredicate(SubType.HUATLI)); + } + + public HuatlisSpurring(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); + + // Target creature gets +2/+0 until end of turn. If you control a Huatli planeswalker, that creature gets +4/+0 until end of turn instead. + this.getSpellAbility().addEffect(new ConditionalContinuousEffect( + new BoostTargetEffect(4, 0, Duration.EndOfTurn), + new BoostTargetEffect(2, 0, Duration.EndOfTurn), + new PermanentsOnTheBattlefieldCondition(filter), + "Target creature gets +2/+0 until end of turn. If you control a Huatli planeswalker, that creature gets +4/+0 until end of turn instead.")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public HuatlisSpurring(final HuatlisSpurring card) { + super(card); + } + + @Override + public HuatlisSpurring copy() { + return new HuatlisSpurring(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/Imperiosaur.java b/Mage.Sets/src/mage/cards/i/Imperiosaur.java index 785a643cd3..a630c9a3f9 100644 --- a/Mage.Sets/src/mage/cards/i/Imperiosaur.java +++ b/Mage.Sets/src/mage/cards/i/Imperiosaur.java @@ -33,6 +33,7 @@ import mage.abilities.StaticAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.common.FilterLandPermanent; @@ -45,13 +46,14 @@ import mage.filter.predicate.mageobject.SupertypePredicate; public class Imperiosaur extends CardImpl { private static final FilterLandPermanent filter = new FilterLandPermanent(); + static { filter.add(new SupertypePredicate(SuperType.BASIC)); } public Imperiosaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(5); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java b/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java index b5748d102e..a9cfb55618 100644 --- a/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java +++ b/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java @@ -42,7 +42,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AbilityWord; @@ -139,7 +139,7 @@ class InallaArchmageRitualistEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = ((FixedTarget) getTargetPointer()).getTargetedPermanentOrLKIBattlefield(game); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, null, true); effect.setTargetPointer(getTargetPointer()); if (effect.apply(game, source)) { for (Permanent tokenPermanent : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/i/IxalansBinding.java b/Mage.Sets/src/mage/cards/i/IxalansBinding.java new file mode 100644 index 0000000000..0e562625f0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IxalansBinding.java @@ -0,0 +1,142 @@ +/* + * 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.cards.i; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class IxalansBinding extends CardImpl { + + private final static FilterNonlandPermanent filter = new FilterNonlandPermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public IxalansBinding(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield. + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(filter.getMessage())); + ability.addTarget(new TargetPermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + this.addAbility(ability); + + // Your opponents can't cast spells with the same name as the exiled card. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new IxalansBindingReplacementEffect())); + } + + public IxalansBinding(final IxalansBinding card) { + super(card); + } + + @Override + public IxalansBinding copy() { + return new IxalansBinding(this); + } +} + +class IxalansBindingReplacementEffect extends ContinuousRuleModifyingEffectImpl { + + IxalansBindingReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Your opponents can't cast spells with the same name as the exiled card"; + } + + IxalansBindingReplacementEffect(final IxalansBindingReplacementEffect effect) { + super(effect); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL_LATE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Card card = game.getCard(event.getSourceId()); + if (sourcePermanent != null && card != null) { + UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); + if (exileZone != null) { + ExileZone exile = game.getExile().getExileZone(exileZone); + if (exile == null) { + // try without ZoneChangeCounter - that is useful for tokens + exileZone = CardUtil.getCardExileZoneId(game, source); + if (exileZone != null) { + exile = game.getExile().getExileZone(exileZone); + } + } + if (exile != null) { + for (Card crad : exile.getCards(game)) { + if (crad.getName().equals(card.getName())) { + return true; + } + } + } + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public IxalansBindingReplacementEffect copy() { + return new IxalansBindingReplacementEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java index c41c432980..f1c02d0bd1 100644 --- a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java +++ b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java @@ -37,7 +37,7 @@ import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -66,7 +66,7 @@ public class JaceCunningCastaway extends CardImpl { this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card. - this.addAbility(new LoyaltyAbility(new JaceArchitectOfThouStartEffect1(), 1)); + this.addAbility(new LoyaltyAbility(new JaceCunningCastawayEffect1(), 1)); // -2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it." this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new JaceCunningCastawayIllusionToken()), -2)); @@ -85,45 +85,45 @@ public class JaceCunningCastaway extends CardImpl { } } -class JaceArchitectOfThouStartEffect1 extends OneShotEffect { +class JaceCunningCastawayEffect1 extends OneShotEffect { - public JaceArchitectOfThouStartEffect1() { + public JaceCunningCastawayEffect1() { super(Outcome.DrawCard); this.staticText = "Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card"; } - public JaceArchitectOfThouStartEffect1(final JaceArchitectOfThouStartEffect1 effect) { + public JaceCunningCastawayEffect1(final JaceCunningCastawayEffect1 effect) { super(effect); } @Override - public JaceArchitectOfThouStartEffect1 copy() { - return new JaceArchitectOfThouStartEffect1(this); + public JaceCunningCastawayEffect1 copy() { + return new JaceCunningCastawayEffect1(this); } @Override public boolean apply(Game game, Ability source) { - DelayedTriggeredAbility delayedAbility = new ThopterSpyNetwoDamageTriggeredAbility(); + DelayedTriggeredAbility delayedAbility = new JaceCunningCastawayDamageTriggeredAbility(); game.addDelayedTriggeredAbility(delayedAbility, source); return true; } } -class ThopterSpyNetwoDamageTriggeredAbility extends DelayedTriggeredAbility { +class JaceCunningCastawayDamageTriggeredAbility extends DelayedTriggeredAbility { List damagedPlayerIds = new ArrayList<>(); - public ThopterSpyNetwoDamageTriggeredAbility() { + public JaceCunningCastawayDamageTriggeredAbility() { super(new DrawDiscardControllerEffect(1, 1), Duration.EndOfTurn, false); } - public ThopterSpyNetwoDamageTriggeredAbility(final ThopterSpyNetwoDamageTriggeredAbility ability) { + public JaceCunningCastawayDamageTriggeredAbility(final JaceCunningCastawayDamageTriggeredAbility ability) { super(ability); } @Override - public ThopterSpyNetwoDamageTriggeredAbility copy() { - return new ThopterSpyNetwoDamageTriggeredAbility(this); + public JaceCunningCastawayDamageTriggeredAbility copy() { + return new JaceCunningCastawayDamageTriggeredAbility(this); } @Override @@ -176,8 +176,8 @@ class JaceCunningCastawayCopyEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false, 2); - effect.setTargetPointer(new FixedTarget(source.getSourceId())); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, 2); + effect.setTargetPointer(new FixedTarget(source.getSourceId(), game)); effect.setIsntLegendary(true); return effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/j/JacesSentinel.java b/Mage.Sets/src/mage/cards/j/JacesSentinel.java new file mode 100644 index 0000000000..711ea8b814 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JacesSentinel.java @@ -0,0 +1,91 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class JacesSentinel extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("a Jace planeswalker"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new CardTypePredicate(CardType.PLANESWALKER)); + filter.add(new SubtypePredicate(SubType.JACE)); + } + + public JacesSentinel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add("Merfolk"); + this.subtype.add("Warrior"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // As long as you control a Jace planeswalker, Jace's Sentinel gets +1/+0 and can't be blocked. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 0, Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filter), + "As long as you control a Jace planeswalker, {this} gets +1/+0")); + ability.addEffect(new ConditionalContinuousEffect( + new CantBeBlockedSourceEffect(), + new PermanentsOnTheBattlefieldCondition(filter), + "and has can't be blocked")); + } + + public JacesSentinel(final JacesSentinel card) { + super(card); + } + + @Override + public JacesSentinel copy() { + return new JacesSentinel(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java b/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java index b1f72d5731..34bef1325d 100644 --- a/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java +++ b/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java @@ -29,37 +29,48 @@ package mage.cards.k; import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DiesThisOrAnotherCreatureTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DoIfCostPaid; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; 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.players.Player; import mage.target.TargetPlayer; /** * - * @author maurer.it_at_gmail.com + * @author maurer.it_at_gmail.com, TheElk801 */ public class KalastriaHighborn extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Vampire you control"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + public KalastriaHighborn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}"); this.subtype.add("Vampire"); this.subtype.add("Shaman"); this.power = new MageInt(2); this.toughness = new MageInt(2); - this.addAbility(new KalastriaHighbornTriggeredAbility()); + Ability ability = new DiesThisOrAnotherCreatureTriggeredAbility(new DoIfCostPaid(new LoseGainEffect(), new ManaCostsImpl("{B}")), false, filter); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); } public KalastriaHighborn(final KalastriaHighborn card) { @@ -72,52 +83,35 @@ public class KalastriaHighborn extends CardImpl { } } -class KalastriaHighbornTriggeredAbility extends TriggeredAbilityImpl { - KalastriaHighbornTriggeredAbility ( ) { - super(Zone.ALL, new LoseLifeTargetEffect(2), false); - this.addCost(new ManaCostsImpl("{B}")); - this.addTarget(new TargetPlayer()); - this.getEffects().add(new GainLifeEffect(2)); +class LoseGainEffect extends OneShotEffect { + + LoseGainEffect() { + super(Outcome.Benefit); + this.staticText = "target player loses 2 life and you gain 2 life"; } - KalastriaHighbornTriggeredAbility ( KalastriaHighbornTriggeredAbility ability ) { - super(ability); + LoseGainEffect(final LoseGainEffect effect) { + super(effect); } @Override - public KalastriaHighbornTriggeredAbility copy() { - return new KalastriaHighbornTriggeredAbility(this); + public LoseGainEffect copy() { + return new LoseGainEffect(this); } @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - // ayrat: make sure Kalastria Highborn is on battlefield - if (game.getPermanent(this.getSourceId()) == null) { - // or it is being removed - if (game.getLastKnownInformation(this.getSourceId(), Zone.BATTLEFIELD) == null) { - return false; - } - } - - ZoneChangeEvent zEvent = (ZoneChangeEvent)event; - Permanent permanent = zEvent.getTarget(); - - return permanent != null && - zEvent.getToZone() == Zone.GRAVEYARD && - zEvent.getFromZone() == Zone.BATTLEFIELD && - (permanent.getControllerId().equals(this.getControllerId()) && - permanent.hasSubtype(SubType.VAMPIRE, game) || permanent.getId().equals(this.getSourceId())); - } - - @Override - public String getRule() { - return "Whenever {this} or another Vampire you control is put" - + " into a graveyard from the battlefield, you may pay {B}. If you" - + " do, target player loses 2 life and you gain 2 life."; + public boolean apply(Game game, Ability source) { + Player you = game.getPlayer(source.getControllerId()); + Player them = game.getPlayer(source.getFirstTarget()); + if (you == null && them == null) { + return false; + } + if (you != null) { + you.gainLife(2, game); + } + if (them != null) { + them.loseLife(2, game, false); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java b/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java index 6e56f122b0..c35c73f2fb 100644 --- a/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java +++ b/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java @@ -34,7 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; @@ -111,7 +111,7 @@ class KikiJikiMirrorBreakerEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/k/KindredCharge.java b/Mage.Sets/src/mage/cards/k/KindredCharge.java index bc93536051..46ef8164c3 100644 --- a/Mage.Sets/src/mage/cards/k/KindredCharge.java +++ b/Mage.Sets/src/mage/cards/k/KindredCharge.java @@ -37,7 +37,7 @@ import mage.abilities.effects.common.ChooseCreatureTypeEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -100,7 +100,7 @@ class KindredChargeEffect extends OneShotEffect { filter.add(new SubtypePredicate(SubType.byDescription(creatureType))); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/k/KinjallisSunwing.java b/Mage.Sets/src/mage/cards/k/KinjallisSunwing.java new file mode 100644 index 0000000000..8f03a7d3af --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KinjallisSunwing.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class KinjallisSunwing extends CardImpl { + + public KinjallisSunwing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Creatures your opponents control enter the battlefield tapped. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KinjallisSunwingEffect())); + } + + public KinjallisSunwing(final KinjallisSunwing card) { + super(card); + } + + @Override + public KinjallisSunwing copy() { + return new KinjallisSunwing(this); + } +} + +class KinjallisSunwingEffect extends ReplacementEffectImpl { + + KinjallisSunwingEffect() { + super(Duration.WhileOnBattlefield, Outcome.Tap); + staticText = "Creatures your opponents control enter the battlefield tapped"; + } + + KinjallisSunwingEffect(final KinjallisSunwingEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); + if (target != null) { + target.tap(game); + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null && permanent.isCreature()) { + return true; + } + } + return false; + } + + @Override + public KinjallisSunwingEffect copy() { + return new KinjallisSunwingEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java b/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java new file mode 100644 index 0000000000..697d6a5ab2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java @@ -0,0 +1,206 @@ +/* + * 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.cards.k; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class KitesailFreebooter extends CardImpl { + + public KitesailFreebooter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Kitesail Freebooter enters the battlefield, target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield. + Ability ability = new EntersBattlefieldTriggeredAbility(new KitesailFreebooterExileEffect()); + ability.addTarget(new TargetOpponent()); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new KitesailFreebooterReturnExiledCardAbility())); + this.addAbility(ability); + } + + public KitesailFreebooter(final KitesailFreebooter card) { + super(card); + } + + @Override + public KitesailFreebooter copy() { + return new KitesailFreebooter(this); + } +} + +class KitesailFreebooterExileEffect extends OneShotEffect { + + public KitesailFreebooterExileEffect() { + super(Outcome.Benefit); + this.staticText = "target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until {this} leaves the battlefield"; + } + + public KitesailFreebooterExileEffect(final KitesailFreebooterExileEffect effect) { + super(effect); + } + + @Override + public KitesailFreebooterExileEffect copy() { + return new KitesailFreebooterExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && opponent != null && sourcePermanent != null) { + if (!opponent.getHand().isEmpty()) { + opponent.revealCards(sourcePermanent.getIdName(), opponent.getHand(), game); + + FilterCard filter = new FilterNonlandCard("noncreature, nonland card to exile"); + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + TargetCard target = new TargetCard(Zone.HAND, filter); + if (opponent.getHand().count(filter, game) > 0 && controller.choose(Outcome.Exile, opponent.getHand(), target, game)) { + Card card = opponent.getHand().get(target.getFirstTarget(), game); + // If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled. + if (card != null && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) { + controller.moveCardToExileWithInfo(card, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.HAND, true); + } + } + } + return true; + } + return false; + + } +} + +/** + * Returns the exiled card as source permanent leaves battlefield Uses no stack + * + * @author LevelX2 + */ +class KitesailFreebooterReturnExiledCardAbility extends DelayedTriggeredAbility { + + public KitesailFreebooterReturnExiledCardAbility() { + super(new KitesailFreebooterReturnExiledCardEffect(), Duration.OneUse); + this.usesStack = false; + this.setRuleVisible(false); + } + + public KitesailFreebooterReturnExiledCardAbility(final KitesailFreebooterReturnExiledCardAbility ability) { + super(ability); + } + + @Override + public KitesailFreebooterReturnExiledCardAbility copy() { + return new KitesailFreebooterReturnExiledCardAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getTargetId().equals(this.getSourceId())) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD) { + return true; + } + } + return false; + } +} + +class KitesailFreebooterReturnExiledCardEffect extends OneShotEffect { + + public KitesailFreebooterReturnExiledCardEffect() { + super(Outcome.Benefit); + this.staticText = "Return exiled nonland card to its owner's hand"; + } + + public KitesailFreebooterReturnExiledCardEffect(final KitesailFreebooterReturnExiledCardEffect effect) { + super(effect); + } + + @Override + public KitesailFreebooterReturnExiledCardEffect copy() { + return new KitesailFreebooterReturnExiledCardEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null && controller != null) { + ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (exile != null && sourcePermanent != null) { + controller.moveCards(exile, Zone.HAND, source, game); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java b/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java new file mode 100644 index 0000000000..ed4a51b1fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java @@ -0,0 +1,184 @@ +/* + * 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.cards.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.Target; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class KopalaWardenOfWaves extends CardImpl { + + public KopalaWardenOfWaves(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("Merfolk"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Spells your opponents cast that target a Merfolk you control cost {2} more to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KopalaWardenOfWavesCostReductionEffect())); + + // Abilities your opponents activate that target a Merfolk you control cost {2} more to activate. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KopalaWardenOfWavesCostReductionEffect2())); + } + + public KopalaWardenOfWaves(final KopalaWardenOfWaves card) { + super(card); + } + + @Override + public KopalaWardenOfWaves copy() { + return new KopalaWardenOfWaves(this); + } +} + +class KopalaWardenOfWavesCostReductionEffect extends CostModificationEffectImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a Merfolk you control"); + private static final String effectText = "Spells your opponents cast that target a Merfolk you control cost {2} more to cast"; + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + } + + KopalaWardenOfWavesCostReductionEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST); + staticText = effectText; + } + + KopalaWardenOfWavesCostReductionEffect(KopalaWardenOfWavesCostReductionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + SpellAbility spellAbility = (SpellAbility) abilityToModify; + CardUtil.adjustCost(spellAbility, -2); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify.getAbilityType() == AbilityType.SPELL) { + if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { + for (Target target : abilityToModify.getTargets()) { + for (UUID targetUUID : target.getTargets()) { + Permanent creature = game.getPermanent(targetUUID); + if (creature != null + && filter.match(creature, game) + && creature.getControllerId().equals(source.getControllerId())) { + return true; + } + } + } + } + } + return false; + } + + @Override + public KopalaWardenOfWavesCostReductionEffect copy() { + return new KopalaWardenOfWavesCostReductionEffect(this); + } + +} + +class KopalaWardenOfWavesCostReductionEffect2 extends CostModificationEffectImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a Merfolk you control"); + private static final String effectText = "Abilities your opponents activate that target a Merfolk you control cost {2} more to activate"; + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + } + + KopalaWardenOfWavesCostReductionEffect2() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST); + staticText = effectText; + } + + KopalaWardenOfWavesCostReductionEffect2(KopalaWardenOfWavesCostReductionEffect2 effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + CardUtil.increaseCost(abilityToModify, 2); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED) { + if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { + for (Target target : abilityToModify.getTargets()) { + for (UUID targetUUID : target.getTargets()) { + Permanent creature = game.getPermanent(targetUUID); + if (creature != null + && filter.match(creature, game) + && creature.getControllerId().equals(source.getControllerId())) { + return true; + } + } + } + } + } + return false; + } + + @Override + public KopalaWardenOfWavesCostReductionEffect2 copy() { + return new KopalaWardenOfWavesCostReductionEffect2(this); + } + +} diff --git a/Mage.Sets/src/mage/cards/k/KumenasOmenspeaker.java b/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java similarity index 90% rename from Mage.Sets/src/mage/cards/k/KumenasOmenspeaker.java rename to Mage.Sets/src/mage/cards/k/KumenasSpeaker.java index 0eea31a498..a6eeff50fc 100644 --- a/Mage.Sets/src/mage/cards/k/KumenasOmenspeaker.java +++ b/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java @@ -45,9 +45,9 @@ import mage.filter.predicate.permanent.AnotherPredicate; * * @author TheElk801 */ -public class KumenasOmenspeaker extends CardImpl { +public class KumenasSpeaker extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("another Merfolk or Island"); + private static final FilterPermanent filter = new FilterPermanent("another Merfolk or an Island"); static { filter.add(Predicates.or( @@ -59,7 +59,7 @@ public class KumenasOmenspeaker extends CardImpl { )); } - public KumenasOmenspeaker(UUID ownerId, CardSetInfo setInfo) { + public KumenasSpeaker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add("Merfolk"); @@ -70,12 +70,12 @@ public class KumenasOmenspeaker extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceWhileControlsEffect(filter, 1, 1))); } - public KumenasOmenspeaker(final KumenasOmenspeaker card) { + public KumenasSpeaker(final KumenasSpeaker card) { super(card); } @Override - public KumenasOmenspeaker copy() { - return new KumenasOmenspeaker(this); + public KumenasSpeaker copy() { + return new KumenasSpeaker(this); } } diff --git a/Mage.Sets/src/mage/cards/l/LilianaVess.java b/Mage.Sets/src/mage/cards/l/LilianaVess.java index 193f718a78..7e2681a93b 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaVess.java +++ b/Mage.Sets/src/mage/cards/l/LilianaVess.java @@ -27,9 +27,6 @@ */ package mage.cards.l; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; @@ -49,6 +46,10 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCardInLibrary; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -89,7 +90,7 @@ class LilianaVessEffect extends OneShotEffect { public LilianaVessEffect() { super(Outcome.PutCreatureInPlay); - staticText = "Put all creature cards in all graveyards onto the battlefield under your control"; + staticText = "Put all creature cards from all graveyards onto the battlefield under your control"; } public LilianaVessEffect(final LilianaVessEffect effect) { diff --git a/Mage.Sets/src/mage/cards/m/Magmasaur.java b/Mage.Sets/src/mage/cards/m/Magmasaur.java index 82fe68b611..5878c29ca6 100644 --- a/Mage.Sets/src/mage/cards/m/Magmasaur.java +++ b/Mage.Sets/src/mage/cards/m/Magmasaur.java @@ -40,6 +40,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; @@ -57,9 +58,9 @@ import mage.players.Player; public class Magmasaur extends CardImpl { public Magmasaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}"); - this.subtype.add("Elemental"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(0); this.toughness = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java new file mode 100644 index 0000000000..d1b2227e0e --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java @@ -0,0 +1,123 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +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.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.IxalanVampireToken; + +/** + * + * @author TheElk801 + */ +public class MavrenFeinDuskApostle extends CardImpl { + + public MavrenFeinDuskApostle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("Vampire"); + this.subtype.add("Cleric"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever one or more nontoken Vampires you control attack, create a 1/1 white Vampire creature token with lifelink. + this.addAbility(new MavrenFeinDuskApostleTriggeredAbility()); + } + + public MavrenFeinDuskApostle(final MavrenFeinDuskApostle card) { + super(card); + } + + @Override + public MavrenFeinDuskApostle copy() { + return new MavrenFeinDuskApostle(this); + } +} + +class MavrenFeinDuskApostleTriggeredAbility extends TriggeredAbilityImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken Vampire you control"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + filter.add(Predicates.not(new TokenPredicate())); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public MavrenFeinDuskApostleTriggeredAbility() { + super(Zone.BATTLEFIELD, new CreateTokenEffect(new IxalanVampireToken()), false); + } + + public MavrenFeinDuskApostleTriggeredAbility(final MavrenFeinDuskApostleTriggeredAbility ability) { + super(ability); + } + + @Override + public MavrenFeinDuskApostleTriggeredAbility copy() { + return new MavrenFeinDuskApostleTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + for (UUID creatureId : game.getCombat().getAttackers()) { + Permanent creature = game.getPermanent(creatureId); + if (creature != null && filter.match(creature, game)) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever one or more nontoken Vampires you control attack, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MimicVat.java b/Mage.Sets/src/mage/cards/m/MimicVat.java index 21e3ae8a9c..8fd4c37ba9 100644 --- a/Mage.Sets/src/mage/cards/m/MimicVat.java +++ b/Mage.Sets/src/mage/cards/m/MimicVat.java @@ -39,7 +39,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -206,7 +206,7 @@ class MimicVatCreateTokenEffect extends OneShotEffect { if (!permanent.getImprinted().isEmpty()) { Card card = game.getCard(permanent.getImprinted().get(0)); if (card != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/m/MinionReflector.java b/Mage.Sets/src/mage/cards/m/MinionReflector.java index 506f9ac33c..a9ae22da15 100644 --- a/Mage.Sets/src/mage/cards/m/MinionReflector.java +++ b/Mage.Sets/src/mage/cards/m/MinionReflector.java @@ -35,7 +35,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.cards.CardImpl; @@ -137,7 +137,7 @@ class MinionReflectorEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/m/MirrorMatch.java b/Mage.Sets/src/mage/cards/m/MirrorMatch.java index 3aa3fd7ab5..d5d3f8d584 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorMatch.java +++ b/Mage.Sets/src/mage/cards/m/MirrorMatch.java @@ -33,7 +33,7 @@ import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -97,7 +97,7 @@ class MirrorMatchEffect extends OneShotEffect { Permanent attacker = game.getPermanent(attackerId); if (attacker != null && source.getControllerId().equals(game.getCombat().getDefendingPlayerId(attackerId, game))) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false); effect.setTargetPointer(new FixedTarget(attacker, game)); effect.apply(game, source); CombatGroup group = game.getCombat().findGroup(attacker.getId()); diff --git a/Mage.Sets/src/mage/cards/m/MirrorMockery.java b/Mage.Sets/src/mage/cards/m/MirrorMockery.java index 6adcef3291..d5b14c0045 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorMockery.java +++ b/Mage.Sets/src/mage/cards/m/MirrorMockery.java @@ -34,7 +34,7 @@ import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -102,7 +102,7 @@ class MirrorMockeryEffect extends OneShotEffect { } Permanent enchanted = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo()); if (enchanted != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(enchanted, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java b/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java index 9e6d32754c..a01b37b68d 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java +++ b/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java @@ -35,7 +35,7 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -71,7 +71,7 @@ public class MirrorSigilSergeant extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // At the beginning of your upkeep, if you control a blue permanent, you may create a token that's a copy of Mirror-Sigil Sergeant. - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); + Effect effect = new CreateTokenCopySourceEffect(); effect.setText("you may create a token that's a copy of {this}"); TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, true); this.addAbility(new ConditionalTriggeredAbility(ability, new PermanentsOnTheBattlefieldCondition(filter), rule)); diff --git a/Mage.Sets/src/mage/cards/m/Mirrorpool.java b/Mage.Sets/src/mage/cards/m/Mirrorpool.java index baa09029bb..76adc1b069 100644 --- a/Mage.Sets/src/mage/cards/m/Mirrorpool.java +++ b/Mage.Sets/src/mage/cards/m/Mirrorpool.java @@ -35,7 +35,7 @@ import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CopyTargetSpellEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -81,7 +81,7 @@ public class Mirrorpool extends CardImpl { this.addAbility(ability); // {4}{C}, {T}, Sacrifice Mirrorpool: Create a token that's a copy of target creature you control. - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopyTargetEffect(), new ManaCostsImpl("{4}{C}")); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenCopyTargetEffect(), new ManaCostsImpl("{4}{C}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetControlledCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/m/Mirrorworks.java b/Mage.Sets/src/mage/cards/m/Mirrorworks.java index 2d1e051fb9..d461aebcc8 100644 --- a/Mage.Sets/src/mage/cards/m/Mirrorworks.java +++ b/Mage.Sets/src/mage/cards/m/Mirrorworks.java @@ -32,7 +32,7 @@ import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -61,7 +61,7 @@ public class Mirrorworks extends CardImpl { // Whenever another nontoken artifact enters the battlefield under your control, you may pay {2}. // If you do, create a token that's a copy of that artifact. - Effect effect = new DoIfCostPaid(new PutTokenOntoBattlefieldCopyTargetEffect(true), + Effect effect = new DoIfCostPaid(new CreateTokenCopyTargetEffect(true), new ManaCostsImpl("{2}"), "Create a token that's a copy of that artifact?"); effect.setText("you may pay {2}. If you do, create a token that's a copy of that artifact"); this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, filter, false, SetTargetPointer.PERMANENT, null)); diff --git a/Mage.Sets/src/mage/cards/m/MyrPropagator.java b/Mage.Sets/src/mage/cards/m/MyrPropagator.java index 6a7e2a6ef2..9795b4e107 100644 --- a/Mage.Sets/src/mage/cards/m/MyrPropagator.java +++ b/Mage.Sets/src/mage/cards/m/MyrPropagator.java @@ -33,7 +33,7 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -53,7 +53,7 @@ public class MyrPropagator extends CardImpl { this.toughness = new MageInt(1); // {3}, {tap}: Create a token that's a copy of Myr Propagator. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopySourceEffect(), new GenericManaCost(3)); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenCopySourceEffect(), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/n/NaturesLore.java b/Mage.Sets/src/mage/cards/n/NaturesLore.java index c07a21d454..1f73d2deaa 100644 --- a/Mage.Sets/src/mage/cards/n/NaturesLore.java +++ b/Mage.Sets/src/mage/cards/n/NaturesLore.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,13 +36,15 @@ import mage.filter.FilterCard; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.target.common.TargetCardInLibrary; +import java.util.UUID; + /** * * @author LevelX2 */ public class NaturesLore extends CardImpl { - private static final FilterCard filter = new FilterCard("a Forest card"); + private static final FilterCard filter = new FilterCard("Forest card"); static { filter.add(new SubtypePredicate(SubType.FOREST)); diff --git a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java index 7936a68083..1558de8636 100644 --- a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java +++ b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; @@ -54,13 +53,15 @@ import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author spjspj */ public class NazahnReveredBladesmith extends CardImpl { - private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent("equipped creatures you control"); + private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent("equipped creature you control"); static { equippedFilter.add(new EquippedPredicate()); @@ -88,7 +89,7 @@ public class NazahnReveredBladesmith extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandOrOnBattlefieldEffect(target, true, true, "Hammer of Nazahn"), true)); // Whenever an equipped creature you control attacks, you may tap target creature defending player controls. - Ability ability = new AttacksCreatureYouControlTriggeredAbility(new NazahnTapEffect(), false, equippedFilter, true); + Ability ability = new AttacksCreatureYouControlTriggeredAbility(new NazahnTapEffect(), true, equippedFilter, true); ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/n/NemesisTrap.java b/Mage.Sets/src/mage/cards/n/NemesisTrap.java index af5f67aafd..1a28e4260d 100644 --- a/Mage.Sets/src/mage/cards/n/NemesisTrap.java +++ b/Mage.Sets/src/mage/cards/n/NemesisTrap.java @@ -37,7 +37,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -111,7 +111,7 @@ class NemesisTrapEffect extends OneShotEffect { // exile target controller.moveCards(targetedCreature, Zone.EXILED, source, game); // create token - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(targetedCreature, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java index add8f8fe35..968ba66159 100644 --- a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java +++ b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java @@ -28,6 +28,7 @@ package mage.cards.n; import java.util.UUID; + import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -44,7 +45,12 @@ import mage.abilities.keyword.IntimidateAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -62,7 +68,7 @@ public class NimDeathmantle extends CardImpl { public NimDeathmantle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - this.subtype.add("Equipment"); + this.subtype.add(SubType.EQUIPMENT); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4))); @@ -70,7 +76,7 @@ public class NimDeathmantle extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardColorAttachedEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.ZOMBIE, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT, SubType.ZOMBIE))); // Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach Nim Deathmantle to it. this.addAbility(new NimDeathmantleTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/o/OniPossession.java b/Mage.Sets/src/mage/cards/o/OniPossession.java index c68e5dab47..03473e8a04 100644 --- a/Mage.Sets/src/mage/cards/o/OniPossession.java +++ b/Mage.Sets/src/mage/cards/o/OniPossession.java @@ -27,9 +27,8 @@ */ package mage.cards.o; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -42,12 +41,7 @@ import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -58,16 +52,9 @@ import mage.target.common.TargetCreaturePermanent; */ public class OniPossession extends CardImpl { - private static final List setSubtypes = new ArrayList<>(); - - static { - setSubtypes.add("Demon"); - setSubtypes.add("Spirit"); - } - public OniPossession(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}"); - this.subtype.add("Aura"); + this.subtype.add(SubType.AURA); // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); @@ -84,7 +71,7 @@ public class OniPossession extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA))); // Enchanted creature is a Demon Spirit. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(setSubtypes, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA, SubType.DEMON, SubType.SPIRIT))); } public OniPossession(final OniPossession card) { diff --git a/Mage.Sets/src/mage/cards/o/OverflowingInsight.java b/Mage.Sets/src/mage/cards/o/OverflowingInsight.java new file mode 100644 index 0000000000..8a0f2d805b --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OverflowingInsight.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.o; + +import java.util.UUID; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class OverflowingInsight extends CardImpl { + + public OverflowingInsight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}{U}"); + + // Target player draws seven cards. + this.getSpellAbility().addEffect(new DrawCardTargetEffect(7)); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public OverflowingInsight(final OverflowingInsight card) { + super(card); + } + + @Override + public OverflowingInsight copy() { + return new OverflowingInsight(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PackRat.java b/Mage.Sets/src/mage/cards/p/PackRat.java index 1f0cb97b75..4a8bbb951d 100644 --- a/Mage.Sets/src/mage/cards/p/PackRat.java +++ b/Mage.Sets/src/mage/cards/p/PackRat.java @@ -35,7 +35,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -83,7 +83,7 @@ public class PackRat extends CardImpl { // Pack Rat's power and toughness are each equal to the number of Rats you control. this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(filter), Duration.EndOfGame))); // {2}{B}, Discard a card: Create a token that's a copy of Pack Rat. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopySourceEffect(), new ManaCostsImpl("{2}{B}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenCopySourceEffect(), new ManaCostsImpl("{2}{B}")); ability.addCost(new DiscardCardCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/Pangosaur.java b/Mage.Sets/src/mage/cards/p/Pangosaur.java index 61658b75e0..8f4c448081 100644 --- a/Mage.Sets/src/mage/cards/p/Pangosaur.java +++ b/Mage.Sets/src/mage/cards/p/Pangosaur.java @@ -34,6 +34,7 @@ import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -46,8 +47,8 @@ import mage.game.events.GameEvent.EventType; public class Pangosaur extends CardImpl { public Pangosaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(6); this.toughness = new MageInt(6); @@ -66,6 +67,7 @@ public class Pangosaur extends CardImpl { } class PangosaurTriggeredAbility extends TriggeredAbilityImpl { + PangosaurTriggeredAbility() { super(Zone.BATTLEFIELD, new ReturnToHandSourceEffect()); } @@ -83,7 +85,7 @@ class PangosaurTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { return true; } - + @Override public PangosaurTriggeredAbility copy() { return new PangosaurTriggeredAbility(this); diff --git a/Mage.Sets/src/mage/cards/p/ParallelEvolution.java b/Mage.Sets/src/mage/cards/p/ParallelEvolution.java index dedb99c3ca..ae1fba4247 100644 --- a/Mage.Sets/src/mage/cards/p/ParallelEvolution.java +++ b/Mage.Sets/src/mage/cards/p/ParallelEvolution.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.FlashbackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -97,7 +97,7 @@ class ParallelEvolutionEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(permanent.getControllerId()); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(permanent.getControllerId()); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/p/PillarOfOrigins.java b/Mage.Sets/src/mage/cards/p/PillarOfOrigins.java new file mode 100644 index 0000000000..6aed375d7f --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PillarOfOrigins.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.cards.p; + +import java.util.UUID; +import mage.ConditionalMana; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.abilities.mana.ConditionalAnyColorManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.abilities.mana.conditional.CreatureCastManaCondition; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class PillarOfOrigins extends CardImpl { + + public PillarOfOrigins(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // As Pillar of Origins enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Benefit))); + + // {T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type. + this.addAbility(new ConditionalAnyColorManaAbility(new TapSourceCost(), 1, new PillarOfOriginsManaBuilder(), true)); + } + + public PillarOfOrigins(final PillarOfOrigins card) { + super(card); + } + + @Override + public PillarOfOrigins copy() { + return new PillarOfOrigins(this); + } +} + +class PillarOfOriginsManaBuilder extends ConditionalManaBuilder { + + SubType creatureType; + + @Override + public ConditionalManaBuilder setMana(Mana mana, Ability source, Game game) { + SubType value = (SubType) game.getState().getValue(source.getSourceId() + "_type"); + if (value != null) { + creatureType = value; + } + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + game.informPlayers(controller.getLogName() + " produces " + mana.toString() + " with " + sourceObject.getLogName() + + " (can only be spent to cast creatures of type " + creatureType + ")"); + } + return super.setMana(mana, source, game); + } + + @Override + public ConditionalMana build(Object... options) { + return new PillarOfOriginsConditionalMana(this.mana, creatureType); + } + + @Override + public String getRule() { + return "Spend this mana only to cast a creature spell of the chosen type"; + } +} + +class PillarOfOriginsConditionalMana extends ConditionalMana { + + public PillarOfOriginsConditionalMana(Mana mana, SubType creatureType) { + super(mana); + staticText = "Spend this mana only to cast a creature spell of the chosen type"; + addCondition(new PillarOfOriginsManaCondition(creatureType)); + } +} + +class PillarOfOriginsManaCondition extends CreatureCastManaCondition { + + SubType creatureType; + + PillarOfOriginsManaCondition(SubType creatureType) { + this.creatureType = creatureType; + } + + @Override + public boolean apply(Game game, Ability source, UUID originalId, Cost costToPay) { + // check: ... to cast a creature spell + if (super.apply(game, source)) { + // check: ... of the chosen type + MageObject object = game.getObject(source.getSourceId()); + if (creatureType != null && object.hasSubtype(creatureType, game)) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PiratesCutlass.java b/Mage.Sets/src/mage/cards/p/PiratesCutlass.java new file mode 100644 index 0000000000..0c6b00b464 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiratesCutlass.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.cards.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class PiratesCutlass extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Pirate you control"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public PiratesCutlass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + this.subtype.add("Equipment"); + + // When Pirate's Cutlass enters the battlefield, attach it to target Pirate you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AttachEffect(Outcome.BoostCreature, "attach it to target Pirate you control"), false); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + + // Equipped creature gets +2/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 1))); + + // Equip 2 + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + + } + + public PiratesCutlass(final PiratesCutlass card) { + super(card); + } + + @Override + public PiratesCutlass copy() { + return new PiratesCutlass(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PowderKeg.java b/Mage.Sets/src/mage/cards/p/PowderKeg.java index 25dacb3504..b0a087c32b 100644 --- a/Mage.Sets/src/mage/cards/p/PowderKeg.java +++ b/Mage.Sets/src/mage/cards/p/PowderKeg.java @@ -38,10 +38,15 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.ComparisonType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.game.permanent.Permanent; @@ -58,8 +63,8 @@ public class PowderKeg extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.FUSE.createInstance(), true), TargetController.YOU, true)); // {T}, Sacrifice Powder Keg: Destroy each artifact and creature with converted mana cost equal to the number of fuse counters on Powder Keg. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PowderKegEffect(), new SacrificeSourceCost()); - ability.addCost(new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PowderKegEffect(), new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } @@ -77,7 +82,7 @@ class PowderKegEffect extends OneShotEffect { public PowderKegEffect() { super(Outcome.DestroyPermanent); - staticText = "Destroy each artifact and creature with converted mana cost equal to the number of fuse counters on Powder Keg {this}"; + staticText = "Destroy each artifact and creature with converted mana cost equal to the number of fuse counters on {this}"; } public PowderKegEffect(final PowderKegEffect effect) { @@ -86,22 +91,17 @@ class PowderKegEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent p = game.getBattlefield().getPermanent(source.getSourceId()); - if (p == null) { - p = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if (p == null) { - return false; - } + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourcePermanent == null) { + return false; } - - int count = p.getCounters(game).getCount(CounterType.FUSE); - for (Permanent perm : game.getBattlefield().getAllActivePermanents()) { - if (perm.getConvertedManaCost() == count && ((perm.isArtifact()) - || (perm.isCreature()))) { - perm.destroy(source.getSourceId(), game, false); - } + int count = sourcePermanent.getCounters(game).getCount(CounterType.FUSE); + FilterPermanent filter = new FilterPermanent(); + filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE))); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, count)); + for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + perm.destroy(source.getSourceId(), game, false); } - return true; } diff --git a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java new file mode 100644 index 0000000000..ee8ef721a6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java @@ -0,0 +1,140 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author spjspj + */ +public class PriestOfTheWakeningSun extends CardImpl { + + private static final FilterCard filter = new FilterCard("a Dinosaur card"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public PriestOfTheWakeningSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // At the beginning of your upkeep, you may reveal a Dinosaur card from your hand. If you do, you gain 2 life. + Ability ability = new BeginningOfUpkeepTriggeredAbility(new PriestOfTheWakeningSunEffect(), TargetController.YOU, true); + this.addAbility(ability); + + // {3}{W}{W}, Sacrifice Priest of the Wakening Sun: Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle your library. + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(target), true, true), new ManaCostsImpl("{3}{W}{W}")); + ability2.addCost(new SacrificeSourceCost()); + this.addAbility(ability2); + } + + public PriestOfTheWakeningSun(final PriestOfTheWakeningSun card) { + super(card); + } + + @Override + public PriestOfTheWakeningSun copy() { + return new PriestOfTheWakeningSun(this); + } +} + +class PriestOfTheWakeningSunEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("a Dinosaur card to reveal"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + PriestOfTheWakeningSunEffect() { + super(Outcome.Benefit); + this.staticText = "reveal a Dinosaur card from your hand. If you do, you gain 2 life"; + } + + PriestOfTheWakeningSunEffect(final PriestOfTheWakeningSunEffect effect) { + super(effect); + } + + @Override + public PriestOfTheWakeningSunEffect copy() { + return new PriestOfTheWakeningSunEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + + if (controller != null && sourceObject != null) { + if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { + if (controller.chooseUse(outcome, "Reveal a Dinosaur card?", source, game)) { + TargetCardInHand target = new TargetCardInHand(0, 1, filter); + if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) { + Cards cards = new CardsImpl(); + cards.addAll(target.getTargets()); + controller.revealCards(sourceObject.getIdName(), cards, game); + controller.gainLife(2, game); + return true; + } + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PrimalAmulet.java b/Mage.Sets/src/mage/cards/p/PrimalAmulet.java new file mode 100644 index 0000000000..e62c449573 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrimalAmulet.java @@ -0,0 +1,123 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class PrimalAmulet extends CardImpl { + + private static final FilterCard filter = new FilterCard("Instant and sorcery spells"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY) + )); + } + + public PrimalAmulet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + this.transformable = true; + this.secondSideCardClazz = PrimalWellspring.class; + + // Instant and sorcery spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it. + this.addAbility(new TransformAbility()); + this.addAbility(new SpellCastControllerTriggeredAbility(new PrimalAmuletEffect(), new FilterInstantOrSorcerySpell(), false)); + } + + public PrimalAmulet(final PrimalAmulet card) { + super(card); + } + + @Override + public PrimalAmulet copy() { + return new PrimalAmulet(this); + } +} + +class PrimalAmuletEffect extends OneShotEffect { + + PrimalAmuletEffect() { + super(Outcome.Benefit); + this.staticText = "put a charge counter on {this}. " + + "Then if there are four or more charge counters on it, " + + "you may remove those counters and transform it"; + } + + PrimalAmuletEffect(final PrimalAmuletEffect effect) { + super(effect); + } + + @Override + public PrimalAmuletEffect copy() { + return new PrimalAmuletEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && player != null) { + permanent.addCounters(CounterType.CHARGE.createInstance(), source, game); + int counters = permanent.getCounters(game).getCount(CounterType.CHARGE); + if (counters > 3 && player.chooseUse(Outcome.Benefit, "Transform this?", source, game)) { + permanent.removeCounters("charge", counters, game); + new TransformSourceEffect(true).apply(game, source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java new file mode 100644 index 0000000000..fc8793547e --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrimalWellspring.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.cards.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyTargetSpellEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class PrimalWellspring extends CardImpl { + + public PrimalWellspring(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.nightCard = true; + + // Add one mana of any color to your mana pool. + Ability ability = new AnyColorManaAbility(); + this.addAbility(ability); + + // When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy. + Effect effect = new CopyTargetSpellEffect(); + effect.setText("copy that spell and you may choose new targets for the copy"); + this.addAbility(new PyrimalWellspringTriggeredAbility(ability.getOriginalId(), effect)); + } + + public PrimalWellspring(final PrimalWellspring card) { + super(card); + } + + @Override + public PrimalWellspring copy() { + return new PrimalWellspring(this); + } +} + +class PyrimalWellspringTriggeredAbility extends TriggeredAbilityImpl { + + private final static FilterInstantOrSorcerySpell filter = new FilterInstantOrSorcerySpell(); + + String abilityOriginalId; + + public PyrimalWellspringTriggeredAbility(UUID abilityOriginalId, Effect effect) { + super(Zone.ALL, effect, true); + this.abilityOriginalId = abilityOriginalId.toString(); + } + + public PyrimalWellspringTriggeredAbility(final PyrimalWellspringTriggeredAbility ability) { + super(ability); + this.abilityOriginalId = ability.abilityOriginalId; + } + + @Override + public PyrimalWellspringTriggeredAbility copy() { + return new PyrimalWellspringTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.MANA_PAID; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getData().equals(abilityOriginalId)) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && filter.match(spell, getSourceId(), getControllerId(), game)) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "When that mana is used to cast an instant or sorcery spell, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java b/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java index 09301b3f9b..9b71ac9057 100644 --- a/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java +++ b/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java @@ -34,7 +34,7 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -67,7 +67,7 @@ public class ProgenitorMimic extends CardImpl { // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield // except it gains "At the beginning of your upkeep, if this creature isn't a token, // create a token that's a copy of this creature." - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); + Effect effect = new CreateTokenCopySourceEffect(); effect.setText("create a token that's a copy of this creature"); AbilityApplier applier = new AbilityApplier( diff --git a/Mage.Sets/src/mage/cards/p/PutridRaptor.java b/Mage.Sets/src/mage/cards/p/PutridRaptor.java index 38f11681e9..afc93ff5e9 100644 --- a/Mage.Sets/src/mage/cards/p/PutridRaptor.java +++ b/Mage.Sets/src/mage/cards/p/PutridRaptor.java @@ -51,10 +51,10 @@ public class PutridRaptor extends CardImpl { } public PutridRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}"); - this.subtype.add("Zombie"); - this.subtype.add("Lizard"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(4); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java b/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java index ea2b4f0bc1..2174447741 100644 --- a/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java +++ b/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java @@ -33,6 +33,7 @@ import mage.abilities.keyword.SwampwalkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -41,8 +42,8 @@ import mage.constants.CardType; public class PygmyAllosaurus extends CardImpl { public PygmyAllosaurus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java b/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java new file mode 100644 index 0000000000..20f4415c2f --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RagingSwordtooth.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.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author TheElk801 + */ +public class RagingSwordtooth extends CardImpl { + + private static FilterCreaturePermanent filter = new FilterCreaturePermanent("other creature"); + + static { + filter.add(new AnotherPredicate()); + } + + public RagingSwordtooth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature. + addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(1, filter))); + } + + public RagingSwordtooth(final RagingSwordtooth card) { + super(card); + } + + @Override + public RagingSwordtooth copy() { + return new RagingSwordtooth(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RangingRaptors.java b/Mage.Sets/src/mage/cards/r/RangingRaptors.java new file mode 100644 index 0000000000..6dd035fb8d --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RangingRaptors.java @@ -0,0 +1,72 @@ +/* + * 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.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class RangingRaptors extends CardImpl { + + public RangingRaptors(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Enrage - Whenever Ranging Raptors is dealt damage, you may search your library for a basic land card, put it onto the battlefield, then shuffle your library. + Ability ability = new DealtDamageToSourceTriggeredAbility( + Zone.BATTLEFIELD, + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + true, + true); + this.addAbility(ability); + } + + public RangingRaptors(final RangingRaptors card) { + super(card); + } + + @Override + public RangingRaptors copy() { + return new RangingRaptors(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RaptorHatchling.java b/Mage.Sets/src/mage/cards/r/RaptorHatchling.java new file mode 100644 index 0000000000..b19be5c2f1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RaptorHatchling.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.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.permanent.token.DinosaurToken; + +/** + * + * @author TheElk801 + */ +public class RaptorHatchling extends CardImpl { + + public RaptorHatchling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Enrage - Whenever Raptor Hatchling is dealt damage, create a 3/3 green Dinosaur creature token with trample. + Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new DinosaurToken()), false, true); + this.addAbility(ability); } + + public RaptorHatchling(final RaptorHatchling card) { + super(card); + } + + @Override + public RaptorHatchling copy() { + return new RaptorHatchling(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RavenousDaggertooth.java b/Mage.Sets/src/mage/cards/r/RavenousDaggertooth.java new file mode 100644 index 0000000000..15e0794523 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RavenousDaggertooth.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.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class RavenousDaggertooth extends CardImpl { + + public RavenousDaggertooth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Enrage - Whenever Ravenous Daggertooth is dealt damage, you gain 2 life. + Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), false, true); + this.addAbility(ability); + } + + public RavenousDaggertooth(final RavenousDaggertooth card) { + super(card); + } + + @Override + public RavenousDaggertooth copy() { + return new RavenousDaggertooth(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RecklessSpite.java b/Mage.Sets/src/mage/cards/r/RecklessSpite.java index c2b1f67de8..040b7de848 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessSpite.java +++ b/Mage.Sets/src/mage/cards/r/RecklessSpite.java @@ -27,7 +27,6 @@ */ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; @@ -39,13 +38,15 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author Loki */ public class RecklessSpite extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creatures"); static { filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); diff --git a/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java new file mode 100644 index 0000000000..8b1f69312b --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java @@ -0,0 +1,85 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.permanent.token.DinosaurToken; + +/** + * + * @author TheElk801 + */ +public class RegisaurAlpha extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("other Dinosaurss you control"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public RegisaurAlpha(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Other Dinosaurs you control have haste. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true))); + + // When Regisaur Alpha enters the battlefield, create a 3/3 green Dinosaur creature token with trample. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new DinosaurToken()))); + } + + public RegisaurAlpha(final RegisaurAlpha card) { + super(card); + } + + @Override + public RegisaurAlpha copy() { + return new RegisaurAlpha(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java b/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java index e5e11655e6..c5b37477a3 100644 --- a/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java +++ b/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java @@ -35,7 +35,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -117,7 +117,7 @@ class RhysTheRedeemedEffect extends OneShotEffect { if (controller != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { if (permanent.getControllerId().equals(source.getControllerId())) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java b/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java index 78094359aa..5c3be5f1fd 100644 --- a/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java +++ b/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java @@ -33,6 +33,7 @@ import mage.abilities.keyword.DoubleStrikeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -41,9 +42,9 @@ import mage.constants.CardType; public class RidgetopRaptor extends CardImpl { public RidgetopRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); - this.subtype.add("Lizard"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(2); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java b/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java index f2cdde3f9d..ad0ecfdfc7 100644 --- a/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java +++ b/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java @@ -35,7 +35,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyTargetSpellEffect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -82,7 +82,7 @@ public class RikuOfTwoReflections extends CardImpl { this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(effect, new ManaCostsImpl("{U}{R}")), filter, false, true)); // Whenever another nontoken creature enters the battlefield under your control, you may pay {G}{U}. If you do, create a token that's a copy of that creature. - effect = new DoIfCostPaid(new PutTokenOntoBattlefieldCopyTargetEffect(true), + effect = new DoIfCostPaid(new CreateTokenCopyTargetEffect(true), new ManaCostsImpl("{G}{U}"), "Create a token that's a copy of that creature?"); effect.setText("you may pay {G}{U}. If you do, create a token that's a copy of that creature"); this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, filterPermanent, false, SetTargetPointer.PERMANENT, null)); diff --git a/Mage.Sets/src/mage/cards/r/RipscalePredator.java b/Mage.Sets/src/mage/cards/r/RipscalePredator.java index afc172951e..916b3383d9 100644 --- a/Mage.Sets/src/mage/cards/r/RipscalePredator.java +++ b/Mage.Sets/src/mage/cards/r/RipscalePredator.java @@ -33,6 +33,7 @@ import mage.abilities.keyword.MenaceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -41,8 +42,8 @@ import mage.constants.CardType; public class RipscalePredator extends CardImpl { public RipscalePredator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(6); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/r/RiteOfReplication.java b/Mage.Sets/src/mage/cards/r/RiteOfReplication.java index 0801769a28..5b0a31ac7b 100644 --- a/Mage.Sets/src/mage/cards/r/RiteOfReplication.java +++ b/Mage.Sets/src/mage/cards/r/RiteOfReplication.java @@ -30,7 +30,7 @@ package mage.cards.r; import java.util.UUID; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -51,8 +51,8 @@ public class RiteOfReplication extends CardImpl { // Create a token that's a copy of target creature. If Rite of Replication was kicked, create five of those tokens instead. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new PutTokenOntoBattlefieldCopyTargetEffect(null, null, false, 5), - new PutTokenOntoBattlefieldCopyTargetEffect(), KickedCondition.instance, + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new CreateTokenCopyTargetEffect(null, null, false, 5), + new CreateTokenCopyTargetEffect(), KickedCondition.instance, "Create a token that's a copy of target creature. If {this} was kicked, create five of those tokens instead")); } diff --git a/Mage.Sets/src/mage/cards/s/SaheeliRai.java b/Mage.Sets/src/mage/cards/s/SaheeliRai.java index b66844ae70..b6528ecbf6 100644 --- a/Mage.Sets/src/mage/cards/s/SaheeliRai.java +++ b/Mage.Sets/src/mage/cards/s/SaheeliRai.java @@ -37,7 +37,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.Card; @@ -115,7 +115,7 @@ class SaheeliRaiCreateTokenEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent copiedPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (copiedPermanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ARTIFACT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ARTIFACT, true); if (effect.apply(game, source)) { for (Permanent copyPermanent : effect.getAddedPermanent()) { ExileTargetEffect exileEffect = new ExileTargetEffect(); diff --git a/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java b/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java index b24622c005..35e47ac56b 100644 --- a/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java +++ b/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Mode; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -50,13 +50,13 @@ public class SaheelisArtistry extends CardImpl { this.getSpellAbility().getModes().setMaxModes(2); // • Create a token that's a copy of target artifact. this.getSpellAbility().addTarget(new TargetArtifactPermanent()); - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setText("Create a token that's a copy of target artifact"); this.getSpellAbility().addEffect(effect); // • Create a token that's a copy of target creature, except that it's an artifact in addition to its other types. Mode mode1 = new Mode(); mode1.getTargets().add(new TargetCreaturePermanent()); - effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + effect = new CreateTokenCopyTargetEffect(); effect.setBecomesArtifact(true); effect.setText("Create a token that's a copy of target creature, except that it's an artifact in addition to its other types"); mode1.getEffects().add(effect); diff --git a/Mage.Sets/src/mage/cards/s/SanctumSeeker.java b/Mage.Sets/src/mage/cards/s/SanctumSeeker.java new file mode 100644 index 0000000000..3b526974b1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanctumSeeker.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.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class SanctumSeeker extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a Vampire you control attacks"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + } + + public SanctumSeeker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + + this.subtype.add("Vampire"); + this.subtype.add("Knight"); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Whenever a Vampire you control attacks, each opponent loses 1 life and you gain 1 life. + Ability ability = new AttacksCreatureYouControlTriggeredAbility(new LoseLifeOpponentsEffect(1), false, filter); + Effect effect = new GainLifeEffect(1); + effect.setText("and you gain 1 life"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public SanctumSeeker(final SanctumSeeker card) { + super(card); + } + + @Override + public SanctumSeeker copy() { + return new SanctumSeeker(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SanguineSacrament.java b/Mage.Sets/src/mage/cards/s/SanguineSacrament.java new file mode 100644 index 0000000000..ccf88fce75 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanguineSacrament.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.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.ReturnToLibrarySpellEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; + +/** + * + * @author spjspj + */ +public class SanguineSacrament extends CardImpl { + + public SanguineSacrament(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{W}{W}"); + + // You gain twice X life. Put Sanguine Sacrament on the bottom of its owner's library. + this.getSpellAbility().addEffect(new GainLifeEffect(new SanguineSacramentValue())); + this.getSpellAbility().addEffect(new ReturnToLibrarySpellEffect(false)); + } + + public SanguineSacrament(final SanguineSacrament card) { + super(card); + } + + @Override + public SanguineSacrament copy() { + return new SanguineSacrament(this); + } +} + +class SanguineSacramentValue extends ManacostVariableValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return super.calculate(game, sourceAbility, effect) * 2; + } + + @Override + public SanguineSacramentValue copy() { + return new SanguineSacramentValue(); + } + + @Override + public String toString() { + return "twice X"; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SavageStomp.java b/Mage.Sets/src/mage/cards/s/SavageStomp.java new file mode 100644 index 0000000000..1b8b13dd8b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SavageStomp.java @@ -0,0 +1,125 @@ +/* + * 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.cards.s; + +import java.util.Iterator; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; +import mage.target.Target; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SavageStomp extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you don't control"); + + static { + filter.add(new ControllerPredicate(TargetController.NOT_YOU)); + } + + public SavageStomp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); + + // Savage Stomp costs {2} less to cast if it targets a Dinosaur you control. + this.addAbility(new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(2, SavageStompCondition.instance))); + + // Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control. + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); + effect.setApplyEffectsAfter(); + this.getSpellAbility().addEffect(effect); + effect = new FightTargetsEffect(); + effect.setText("Then that creature fights target creature you don't control"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + Target target = new TargetCreaturePermanent(filter); + this.getSpellAbility().addTarget(target); + } + + public SavageStomp(final SavageStomp card) { + super(card); + } + + @Override + public SavageStomp copy() { + return new SavageStomp(this); + } +} + +enum SavageStompCondition implements Condition { + instance; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaur you control"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + @Override + public boolean apply(Game game, Ability source) { + StackObject sourceSpell = game.getStack().getStackObject(source.getSourceId()); + if (sourceSpell != null) { + Iterator targets = sourceSpell.getStackAbility().getTargets().iterator(); + while (targets.hasNext()) { + Permanent permanent = game.getPermanentOrLKIBattlefield(targets.next().getFirstTarget()); + if (permanent != null && filter.match(permanent, game) && permanent.getControllerId().equals(source.getControllerId())) { + return true; + } + } + } + return false; + } + + @Override + public String toString() { + return "it targets a Dinosaur you control"; + } + +} diff --git a/Mage.Sets/src/mage/cards/s/ScareTactics.java b/Mage.Sets/src/mage/cards/s/ScareTactics.java new file mode 100644 index 0000000000..582716bd0b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScareTactics.java @@ -0,0 +1,58 @@ +/* + * 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.cards.s; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author Ekkaia + */ +public class ScareTactics extends CardImpl { + + public ScareTactics(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); + + // Creatures you control get +1/+0 until end of turn. + this.getSpellAbility().addEffect(new BoostControlledEffect(1, 0, Duration.EndOfTurn)); + } + + public ScareTactics(final ScareTactics card) { + super(card); + } + + @Override + public ScareTactics copy() { + return new ScareTactics(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/Seance.java b/Mage.Sets/src/mage/cards/s/Seance.java index 8a5794460d..68615fe293 100644 --- a/Mage.Sets/src/mage/cards/s/Seance.java +++ b/Mage.Sets/src/mage/cards/s/Seance.java @@ -34,7 +34,7 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -96,7 +96,7 @@ class SeanceEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && card != null) { controller.moveCards(card, Zone.EXILED, source, game); // Also if the move to exile is replaced, the copy takes place - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setAdditionalSubType("Spirit"); effect.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/s/SecondHarvest.java b/Mage.Sets/src/mage/cards/s/SecondHarvest.java index 8350f3fa3b..e2793a550b 100644 --- a/Mage.Sets/src/mage/cards/s/SecondHarvest.java +++ b/Mage.Sets/src/mage/cards/s/SecondHarvest.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -89,7 +89,7 @@ class SecondHarvestEffect extends OneShotEffect { filter.add(new TokenPredicate()); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/s/SentinelTotem.java b/Mage.Sets/src/mage/cards/s/SentinelTotem.java new file mode 100644 index 0000000000..81499265ba --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SentinelTotem.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.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.ExileSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class SentinelTotem extends CardImpl { + + public SentinelTotem(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + // When Sentinel Totem enters the battlefield, scry 1. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(1))); + + // {T}, Exile Sentinel Totem: Exile all cards from all graveyards. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileGraveyardAllPlayersEffect(), new TapSourceCost()); + ability.addCost(new ExileSourceCost()); + this.addAbility(ability); + } + + public SentinelTotem(final SentinelTotem card) { + super(card); + } + + @Override + public SentinelTotem copy() { + return new SentinelTotem(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java new file mode 100644 index 0000000000..7cc8bd744a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java @@ -0,0 +1,114 @@ +/* + * 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.cards.s; + +import java.util.Iterator; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class SettleTheWreckage extends CardImpl { + + public SettleTheWreckage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{W}"); + + // Exile all attacking creatures target player controls. That player may search his or her library for that many basic land cards, put those cards onto the battlefield tapped, then shuffle his or her library. + this.getSpellAbility().addEffect(new SettleTheWreckageEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public SettleTheWreckage(final SettleTheWreckage card) { + super(card); + } + + @Override + public SettleTheWreckage copy() { + return new SettleTheWreckage(this); + } +} + +class SettleTheWreckageEffect extends OneShotEffect { + + SettleTheWreckageEffect() { + super(Outcome.Neutral); + this.staticText = "Exile all attacking creatures target player controls. That player may search his or her library for that many basic land cards, put those cards onto the battlefield tapped, then shuffle his or her library"; + } + + SettleTheWreckageEffect(final SettleTheWreckageEffect effect) { + super(effect); + } + + @Override + public SettleTheWreckageEffect copy() { + return new SettleTheWreckageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + int attackers = 0; + Iterator creatureIds = game.getCombat().getAttackers().iterator(); + while (creatureIds.hasNext()) { + Permanent creature = game.getPermanent(creatureIds.next()); + if (creature != null && creature.getControllerId().equals(player.getId())) { + creature.moveToExile(null, null, source.getId(), game); + attackers++; + } + } + TargetCardInLibrary target = new TargetCardInLibrary(0, attackers, StaticFilters.FILTER_BASIC_LAND_CARD); + if (player.chooseUse(Outcome.Benefit, "Search for up to " + attackers + " basic land" + ((attackers == 1) ? "" : "s") + "?", source, game) && player.searchLibrary(target, game)) { + for (UUID cardId : target.getTargets()) { + Card card = player.getLibrary().getCard(cardId, game); + if (card != null) { + card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); + } + } + player.shuffleLibrary(source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShapersOfNature.java b/Mage.Sets/src/mage/cards/s/ShapersOfNature.java new file mode 100644 index 0000000000..83ee9ce6c2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShapersOfNature.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.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCounterCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ShapersOfNature extends CardImpl { + + public ShapersOfNature(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}"); + + this.subtype.add("Merfolk"); + this.subtype.add("Shaman"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // {3}{G}: Put a +1/+1 counter on target creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance(1)), new ManaCostsImpl("{3}{G}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // {2}{U}, Remove a +1/+1 counter from a creature you control: Draw a card. + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{2}{U}")); + ability.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(), CounterType.P1P1)); + this.addAbility(ability); + } + + public ShapersOfNature(final ShapersOfNature card) { + super(card); + } + + @Override + public ShapersOfNature copy() { + return new ShapersOfNature(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShivanRaptor.java b/Mage.Sets/src/mage/cards/s/ShivanRaptor.java index 0bc6cf6a6c..bd590865ac 100644 --- a/Mage.Sets/src/mage/cards/s/ShivanRaptor.java +++ b/Mage.Sets/src/mage/cards/s/ShivanRaptor.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.s; import java.util.UUID; @@ -36,6 +35,7 @@ import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -44,15 +44,15 @@ import mage.constants.CardType; public class ShivanRaptor extends CardImpl { public ShivanRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(3); this.toughness = new MageInt(1); - this.addAbility(FirstStrikeAbility.getInstance()); - this.addAbility(HasteAbility.getInstance()); - this.addAbility(new EchoAbility("{2}{R}")); + this.addAbility(FirstStrikeAbility.getInstance()); + this.addAbility(HasteAbility.getInstance()); + this.addAbility(new EchoAbility("{2}{R}")); } public ShivanRaptor(final ShivanRaptor card) { @@ -64,4 +64,4 @@ public class ShivanRaptor extends CardImpl { return new ShivanRaptor(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SirenStormtamer.java b/Mage.Sets/src/mage/cards/s/SirenStormtamer.java new file mode 100644 index 0000000000..10f6b519fe --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SirenStormtamer.java @@ -0,0 +1,183 @@ +/* + * 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.cards.s; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackAbility; +import mage.game.stack.StackObject; +import mage.target.Target; +import mage.target.TargetObject; +import mage.target.Targets; + +/** + * + * @author spjspj + */ +public class SirenStormtamer extends CardImpl { + + public SirenStormtamer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + + this.subtype.add("Siren"); + this.subtype.add("Pirate"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl("{U}")); + ability.addTarget(new SirenStormtamerTargetObject()); + ability.addCost(new SacrificeSourceCost()); + + this.addAbility(ability); + } + + public SirenStormtamer(final SirenStormtamer card) { + super(card); + } + + @Override + public SirenStormtamer copy() { + return new SirenStormtamer(this); + } +} + +class SirenStormtamerTargetObject extends TargetObject { + + public SirenStormtamerTargetObject() { + this.minNumberOfTargets = 1; + this.maxNumberOfTargets = 1; + this.zone = Zone.STACK; + this.targetName = "spell or ability that targets you or a creature you control"; + } + + public SirenStormtamerTargetObject(final SirenStormtamerTargetObject target) { + super(target); + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + StackObject stackObject = game.getStack().getStackObject(id); + return (stackObject instanceof Spell) || (stackObject instanceof StackAbility); + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + return canChoose(sourceControllerId, game); + } + + @Override + public boolean canChoose(UUID sourceControllerId, Game game) { + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null + && targetedPermanent.getControllerId().equals(sourceControllerId) + && targetedPermanent.isCreature()) { + return true; + } + + if (sourceControllerId.equals(targetId)) { + return true; + } + + } + } + } + } + } + return false; + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, + Game game) { + return possibleTargets(sourceControllerId, game); + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null + && targetedPermanent.getControllerId().equals(sourceControllerId) + && targetedPermanent.isCreature()) { + possibleTargets.add(stackObject.getId()); + } + + if (sourceControllerId.equals(targetId)) { + possibleTargets.add(stackObject.getId()); + } + } + } + } + } + } + return possibleTargets; + } + + @Override + public SirenStormtamerTargetObject copy() { + return new SirenStormtamerTargetObject(this); + } + + @Override + public Filter getFilter() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} diff --git a/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java b/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java new file mode 100644 index 0000000000..3bee634072 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.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.cards.s; + +import java.util.Optional; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.NameACardEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class SorcerousSpyglass extends CardImpl { + + public SorcerousSpyglass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name. + this.addAbility(new AsEntersBattlefieldAbility(new SorcerousSpyglassEntersEffect())); + + // Activated abilities of sources with the chosen name can't be activated unless they're mana abilities. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SorcerousSpyglassActivationEffect())); + } + + public SorcerousSpyglass(final SorcerousSpyglass card) { + super(card); + } + + @Override + public SorcerousSpyglass copy() { + return new SorcerousSpyglass(this); + } +} + +class SorcerousSpyglassEntersEffect extends NameACardEffect { + + SorcerousSpyglassEntersEffect() { + super(NameACardEffect.TypeOfName.ALL); + staticText = "look at an opponent's hand, then choose any card name"; + } + + SorcerousSpyglassEntersEffect(final SorcerousSpyglassEntersEffect effect) { + super(effect); + } + + @Override + public SorcerousSpyglassEntersEffect copy() { + return new SorcerousSpyglassEntersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + TargetOpponent target = new TargetOpponent(true); + if (player.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + Player opponent = game.getPlayer(target.getFirstTarget()); + if (opponent != null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + player.lookAtCards(sourceObject != null ? sourceObject.getIdName() : null, opponent.getHand(), game); + player.chooseUse(Outcome.Benefit, "Press ok to name a card", "You won't be able to resize the window once you do", "Ok", " ", source, game); + } + } + } + return super.apply(game, source); + } +} + +class SorcerousSpyglassActivationEffect extends ContinuousRuleModifyingEffectImpl { + + public SorcerousSpyglassActivationEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Activated abilities of sources with the chosen name can't be activated unless they're mana abilities"; + } + + public SorcerousSpyglassActivationEffect(final SorcerousSpyglassActivationEffect effect) { + super(effect); + } + + @Override + public SorcerousSpyglassActivationEffect copy() { + return new SorcerousSpyglassActivationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject object = game.getObject(event.getSourceId()); + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() && object != null) { + if (game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId()) // controller in range + && ability.get().getAbilityType() != AbilityType.MANA + && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY))) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SoulFoundry.java b/Mage.Sets/src/mage/cards/s/SoulFoundry.java index 80e7ce2392..34544acfda 100644 --- a/Mage.Sets/src/mage/cards/s/SoulFoundry.java +++ b/Mage.Sets/src/mage/cards/s/SoulFoundry.java @@ -37,7 +37,7 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -175,7 +175,7 @@ class SoulFoundryEffect extends OneShotEffect { Card imprinted = game.getCard(soulFoundry.getImprinted().get(0)); if (imprinted != null && game.getState().getZone(imprinted.getId()) == Zone.EXILED) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(imprinted.getId(), imprinted.getZoneChangeCounter(game))); return effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/s/SoulSeparator.java b/Mage.Sets/src/mage/cards/s/SoulSeparator.java index aa5f131223..725652828f 100644 --- a/Mage.Sets/src/mage/cards/s/SoulSeparator.java +++ b/Mage.Sets/src/mage/cards/s/SoulSeparator.java @@ -34,7 +34,7 @@ import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -59,7 +59,7 @@ public class SoulSeparator extends CardImpl { // {5}, {T}, Sacrifice Soul Separator: Exile target creature card from your graveyard. // Create a token that's a copy of that card except it's 1/1, it's a Spirit in addition to its other types, and it has flying. // Create a black Zombie creature token with power equal to that card's power and toughness equal that card's toughness. - PutTokenOntoBattlefieldCopyTargetEffect copyEffect = new PutTokenOntoBattlefieldCopyTargetEffect(null, null, false, 1, false, false, null, 1, 1, true); + CreateTokenCopyTargetEffect copyEffect = new CreateTokenCopyTargetEffect(null, null, false, 1, false, false, null, 1, 1, true); copyEffect.setAdditionalSubType("Spirit"); copyEffect.setText("Create a token that's a copy of that card except it's 1/1, it's a Spirit in addition to its other types, and it has flying."); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, copyEffect, new ManaCostsImpl("{5}")); diff --git a/Mage.Sets/src/mage/cards/s/Spawnwrithe.java b/Mage.Sets/src/mage/cards/s/Spawnwrithe.java index e4fa9482c2..17eeeca17a 100644 --- a/Mage.Sets/src/mage/cards/s/Spawnwrithe.java +++ b/Mage.Sets/src/mage/cards/s/Spawnwrithe.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -52,7 +52,7 @@ public class Spawnwrithe extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); // Whenever Spawnwrithe deals combat damage to a player, create a token that's a copy of Spawnwrithe. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new PutTokenOntoBattlefieldCopySourceEffect(), false)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenCopySourceEffect(), false)); } diff --git a/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java b/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java new file mode 100644 index 0000000000..a26d61a122 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.RemoveFromCombatTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SpiresOfOrazca extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("attacking creature an opponent controls"); + + static { + filter.add(new AttackingPredicate()); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public SpiresOfOrazca(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + this.nightCard = true; + + // {T}: Add {C} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {T}: Untap target attacking creature an opponent controls and remove it from combat. + Effect effect = new UntapTargetEffect(); + effect.setText("Untap target attacking creature an opponent controls and remove it from combat."); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); + effect = new RemoveFromCombatTargetEffect(); + effect.setText(" "); + ability.addEffect(effect); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public SpiresOfOrazca(final SpiresOfOrazca card) { + super(card); + } + + @Override + public SpiresOfOrazca copy() { + return new SpiresOfOrazca(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpittingImage.java b/Mage.Sets/src/mage/cards/s/SpittingImage.java index 735419229c..b1209264be 100644 --- a/Mage.Sets/src/mage/cards/s/SpittingImage.java +++ b/Mage.Sets/src/mage/cards/s/SpittingImage.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.RetraceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -54,7 +54,7 @@ public class SpittingImage extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{G/U}{G/U}"); // Create a token that's a copy of target creature. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); // Retrace (You may cast this card from your graveyard by discarding a land card in addition to paying its other costs.) diff --git a/Mage.Sets/src/mage/cards/s/SplinterTwin.java b/Mage.Sets/src/mage/cards/s/SplinterTwin.java index 36a0e5fe35..c9981a97fb 100644 --- a/Mage.Sets/src/mage/cards/s/SplinterTwin.java +++ b/Mage.Sets/src/mage/cards/s/SplinterTwin.java @@ -37,7 +37,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; @@ -103,7 +103,7 @@ class SplinterTwinEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/s/SplittingSlime.java b/Mage.Sets/src/mage/cards/s/SplittingSlime.java index 6322473028..45c544ca9c 100644 --- a/Mage.Sets/src/mage/cards/s/SplittingSlime.java +++ b/Mage.Sets/src/mage/cards/s/SplittingSlime.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.MonstrosityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -52,7 +52,7 @@ public class SplittingSlime extends CardImpl { this.addAbility(new MonstrosityAbility("{4}{G}{G}", 3)); // When Splitting Slime becomes monstrous, create a token that's a copy of Splitting Slime. - this.addAbility(new BecomesMonstrousSourceTriggeredAbility(new PutTokenOntoBattlefieldCopySourceEffect())); + this.addAbility(new BecomesMonstrousSourceTriggeredAbility(new CreateTokenCopySourceEffect())); } diff --git a/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java b/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java index e8e6ac9974..106f1f9572 100644 --- a/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java +++ b/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealtDamageToSourceTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -54,7 +54,7 @@ public class SproutingPhytohydra extends CardImpl { // Defender this.addAbility(DefenderAbility.getInstance()); // Whenever Sprouting Phytohydra is dealt damage, you may create a token that's a copy of Sprouting Phytohydra. - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); + Effect effect = new CreateTokenCopySourceEffect(); effect.setText("you may create a token that's a copy of {this}"); this.addAbility(new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, effect, true)); } diff --git a/Mage.Sets/src/mage/cards/s/StolenIdentity.java b/Mage.Sets/src/mage/cards/s/StolenIdentity.java index fb5856e320..3a0d8a23f3 100644 --- a/Mage.Sets/src/mage/cards/s/StolenIdentity.java +++ b/Mage.Sets/src/mage/cards/s/StolenIdentity.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.effects.common.CipherEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -54,7 +54,7 @@ public class StolenIdentity extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{U}{U}"); // Create a token that's a copy of target artifact or creature. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent(filter)); // Cipher this.getSpellAbility().addEffect(new CipherEffect()); diff --git a/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java new file mode 100644 index 0000000000..4ae4bb5a88 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.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.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class StormFleetAerialist extends CardImpl { + + public StormFleetAerialist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), + RaidCondition.instance, + "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", + "{this} enters the battlefield with a +1/+1 counter"), + new PlayerAttackedWatcher()); + } + + public StormFleetAerialist(final StormFleetAerialist card) { + super(card); + } + + @Override + public StormFleetAerialist copy() { + return new StormFleetAerialist(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java b/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java new file mode 100644 index 0000000000..82c7377a01 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormFleetArsonist.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.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.target.common.TargetOpponent; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class StormFleetArsonist extends CardImpl { + + public StormFleetArsonist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add("Orc"); + this.subtype.add("Pirate"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Raid - When Storm Fleet Arsonist enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent. + Ability ability = new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new SacrificeEffect(new FilterPermanent(), 1, "Target opponent")), + RaidCondition.instance, + "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent."); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability, new PlayerAttackedWatcher()); + } + + public StormFleetArsonist(final StormFleetArsonist card) { + super(card); + } + + @Override + public StormFleetArsonist copy() { + return new StormFleetArsonist(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SunBlessedMount.java b/Mage.Sets/src/mage/cards/s/SunBlessedMount.java new file mode 100644 index 0000000000..e993d92bd1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunBlessedMount.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.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; + +/** + * + * @author TheElk801 + */ +public class SunBlessedMount extends CardImpl { + + private final static FilterCard filter = new FilterCard("Huatli, Dinosaur Knight"); + + static { + filter.add(new NamePredicate("Huatli, Dinosaur Knight")); + } + + public SunBlessedMount(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Sun-Blessed Mount enters the battlefield, you may search your library and/or graveyard for a card named Huatli, Dinosaur Knight, reveal it, then put it into your hand. If you searched your library this way, shuffle it. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutInHandEffect(filter), true)); + } + + public SunBlessedMount(final SunBlessedMount card) { + super(card); + } + + @Override + public SunBlessedMount copy() { + return new SunBlessedMount(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java new file mode 100644 index 0000000000..37f66ca4e6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -0,0 +1,165 @@ +/* + * 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.cards.s; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author spjspj + */ +public class SunbirdsInvocation extends CardImpl { + + public SunbirdsInvocation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}"); + + // Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order. + this.addAbility(new SunbirdsInvocationTriggeredAbility()); + } + + public SunbirdsInvocation(final SunbirdsInvocation card) { + super(card); + } + + @Override + public SunbirdsInvocation copy() { + return new SunbirdsInvocation(this); + } +} + +class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbility { + + public SunbirdsInvocationTriggeredAbility() { + super(new SunbirdsInvocationEffect(), false); + } + + public SunbirdsInvocationTriggeredAbility(SunbirdsInvocationTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && spell.getFromZone() == Zone.HAND) { + if (spell.getCard() != null) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(spell.getId())); + } + return true; + } + } + } + return false; + } + + @Override + public SunbirdsInvocationTriggeredAbility copy() { + return new SunbirdsInvocationTriggeredAbility(this); + } +} + +class SunbirdsInvocationEffect extends OneShotEffect { + + public SunbirdsInvocationEffect() { + super(Outcome.PutCardInPlay); + staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + } + + public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } + Cards cards = new CardsImpl(); + int xValue = game.getStack().getSpell(getTargetPointer().getFirst(game, source)).getConvertedManaCost(); + cards.addAll(controller.getLibrary().getTopCards(game, xValue)); + if (!cards.isEmpty()) { + controller.revealCards(sourceObject.getIdName(), cards, game); + + FilterCard filter = new FilterNonlandCard("card revealed this way with converted mana cost " + xValue + " or less"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + TargetCard target = new TargetCard(1, Zone.LIBRARY, filter); + + if (controller.chooseTarget(Outcome.PlayForFree, cards, target, source, game)) { + Card card = cards.get(target.getFirstTarget(), game); + if (card != null) { + if (controller.chooseUse(outcome, "Do you wish to cast " + card.getName(), source, game)) { + Card copy = game.copyCard(card, source, source.getControllerId()); + controller.cast(copy.getSpellAbility(), game, true); + } + return true; + } + } + } + + while (!cards.isEmpty()) { + Card card = cards.getRandom(game); + if (card != null) { + cards.remove(card); + card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); + } + } + + return true; + } + + @Override + public SunbirdsInvocationEffect copy() { + return new SunbirdsInvocationEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SupplantForm.java b/Mage.Sets/src/mage/cards/s/SupplantForm.java index bf83582175..1ed9b2032d 100644 --- a/Mage.Sets/src/mage/cards/s/SupplantForm.java +++ b/Mage.Sets/src/mage/cards/s/SupplantForm.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,7 +48,7 @@ public class SupplantForm extends CardImpl { // Return target creature to its owner's hand. You create a token that's a copy of that creature. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setText("You create a token that's a copy of that creature"); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/s/SylvanRanger.java b/Mage.Sets/src/mage/cards/s/SylvanRanger.java index f3adf52350..9ffcb4728b 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanRanger.java +++ b/Mage.Sets/src/mage/cards/s/SylvanRanger.java @@ -55,7 +55,7 @@ public class SylvanRanger extends CardImpl { // When Sylvan Ranger enters the battlefield, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); } public SylvanRanger(final SylvanRanger card) { diff --git a/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java b/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java new file mode 100644 index 0000000000..456e62b94c --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java @@ -0,0 +1,112 @@ +/* + * 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.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.mana.BlackManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class TempleOfAclazotz extends CardImpl { + + public TempleOfAclazotz(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + addSuperType(SuperType.LEGENDARY); + this.nightCard = true; + + // {T}: Add {B} to your mana pool + this.addAbility(new BlackManaAbility()); + + // {T}, Sacrifice a creature: You gain life equal to the sacrificed creature’s toughness. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TempleOfAclazotzEffect(), new TapSourceCost()); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("a creature"), true))); + this.addAbility(ability); + } + + public TempleOfAclazotz(final TempleOfAclazotz card) { + super(card); + } + + @Override + public TempleOfAclazotz copy() { + return new TempleOfAclazotz(this); + } +} + +class TempleOfAclazotzEffect extends OneShotEffect { + + public TempleOfAclazotzEffect() { + super(Outcome.GainLife); + this.staticText = "You gain life equal to the sacrificed creature's toughness"; + } + + public TempleOfAclazotzEffect(final TempleOfAclazotzEffect effect) { + super(effect); + } + + @Override + public TempleOfAclazotzEffect copy() { + return new TempleOfAclazotzEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (Cost cost : source.getCosts()) { + if (cost instanceof SacrificeTargetCost) { + int amount = ((SacrificeTargetCost) cost).getPermanents().get(0).getToughness().getValue(); + if (amount > 0) { + controller.gainLife(amount, game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TemptWithReflections.java b/Mage.Sets/src/mage/cards/t/TemptWithReflections.java index ad80e9bc86..0c75bfe781 100644 --- a/Mage.Sets/src/mage/cards/t/TemptWithReflections.java +++ b/Mage.Sets/src/mage/cards/t/TemptWithReflections.java @@ -33,7 +33,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -88,7 +88,7 @@ class TemptWithReflectionsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); if (permanent != null) { - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); @@ -111,13 +111,13 @@ class TemptWithReflectionsEffect extends OneShotEffect { } while (!player.getId().equals(game.getActivePlayerId())); for (UUID playerId : playersSaidYes) { - effect = new PutTokenOntoBattlefieldCopyTargetEffect(playerId); + effect = new CreateTokenCopyTargetEffect(playerId); effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); } if (!playersSaidYes.isEmpty()) { - effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java new file mode 100644 index 0000000000..e8272c8103 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java @@ -0,0 +1,88 @@ +/* + * 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.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.s.SpiresOfOrazca; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class ThaumaticCompass extends CardImpl { + + public ThaumaticCompass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.transformable = true; + this.secondSideCardClazz = SpiresOfOrazca.class; + + // {3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new GenericManaCost(3)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + // At the beginning of your end step, if you control seven or more lands, transform Thaumatic Compass. + this.addAbility(new TransformAbility()); + TriggeredAbility ability2 = new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, false); + this.addAbility(new ConditionalTriggeredAbility( + ability2, + new PermanentsOnTheBattlefieldCondition(new FilterLandPermanent(), ComparisonType.MORE_THAN, 6, true), + "At the beginning of your end step, if you control seven or more lands, transform {this}.")); + } + + public ThaumaticCompass(final ThaumaticCompass card) { + super(card); + } + + @Override + public ThaumaticCompass copy() { + return new ThaumaticCompass(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheScarabGod.java b/Mage.Sets/src/mage/cards/t/TheScarabGod.java index f793d92e0f..d5b5fd1c26 100644 --- a/Mage.Sets/src/mage/cards/t/TheScarabGod.java +++ b/Mage.Sets/src/mage/cards/t/TheScarabGod.java @@ -39,7 +39,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.Card; @@ -161,7 +161,7 @@ class TheScarabGodEffect2 extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && card != null) { controller.moveCards(card, Zone.EXILED, source, game); // Also if the move to exile is replaced, the copy takes place - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false, 1, false, false, null, 4, 4, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, 1, false, false, null, 4, 4, false); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setOnlySubType("Zombie"); effect.setOnlyColor(ObjectColor.BLACK); diff --git a/Mage.Sets/src/mage/cards/t/TilonallisSkinshifter.java b/Mage.Sets/src/mage/cards/t/TilonallisSkinshifter.java new file mode 100644 index 0000000000..dd30193bd3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TilonallisSkinshifter.java @@ -0,0 +1,119 @@ +/* + * 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.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.util.functions.EmptyApplyToPermanent; + +/** + * + * @author TheElk801 + */ +public class TilonallisSkinshifter extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(Predicates.not(new SupertypePredicate(SuperType.LEGENDARY))); + filter.add(new AttackingPredicate()); + filter.add(new AnotherPredicate()); + } + + public TilonallisSkinshifter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Whenever Tilonalli's Skinshifter attacks, it becomes a copy of another target nonlegendary attacking creature until end of turn. + Ability ability = new AttacksTriggeredAbility(new TilonallisSkinshifterCopyEffect(), false); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + public TilonallisSkinshifter(final TilonallisSkinshifter card) { + super(card); + } + + @Override + public TilonallisSkinshifter copy() { + return new TilonallisSkinshifter(this); + } +} + +class TilonallisSkinshifterCopyEffect extends OneShotEffect { + + public TilonallisSkinshifterCopyEffect() { + super(Outcome.Copy); + this.staticText = "it becomes a copy of another target nonlegendary attacking creature until end of turn"; + } + + public TilonallisSkinshifterCopyEffect(final TilonallisSkinshifterCopyEffect effect) { + super(effect); + } + + @Override + public TilonallisSkinshifterCopyEffect copy() { + return new TilonallisSkinshifterCopyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (sourcePermanent != null && copyFromPermanent != null) { + game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent()); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TrueConviction.java b/Mage.Sets/src/mage/cards/t/TrueConviction.java index 9e3e4051f4..66a2312b49 100644 --- a/Mage.Sets/src/mage/cards/t/TrueConviction.java +++ b/Mage.Sets/src/mage/cards/t/TrueConviction.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; @@ -39,7 +38,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.StaticFilters; + +import java.util.UUID; /** * @@ -51,8 +52,8 @@ public class TrueConviction extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}{W}"); // Creatures you control have double strike and lifelink. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent())); - Effect effect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent()); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)); + Effect effect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES); effect.setText(" and lifelink"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/TrustyMachete.java b/Mage.Sets/src/mage/cards/t/TrustyMachete.java index ba0f973043..3f64f88a0f 100644 --- a/Mage.Sets/src/mage/cards/t/TrustyMachete.java +++ b/Mage.Sets/src/mage/cards/t/TrustyMachete.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.t; import java.util.UUID; @@ -45,14 +44,15 @@ import mage.constants.Zone; */ public class TrustyMachete extends CardImpl { - public TrustyMachete (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); + public TrustyMachete(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); this.subtype.add("Equipment"); - this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 1))); + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); } - public TrustyMachete (final TrustyMachete card) { + public TrustyMachete(final TrustyMachete card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/t/Twinflame.java b/Mage.Sets/src/mage/cards/t/Twinflame.java index 565e9b91b3..17bd0ce651 100644 --- a/Mage.Sets/src/mage/cards/t/Twinflame.java +++ b/Mage.Sets/src/mage/cards/t/Twinflame.java @@ -33,7 +33,7 @@ import mage.abilities.abilityword.StriveAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -101,7 +101,7 @@ class TwinflameCopyEffect extends OneShotEffect { for (UUID creatureId : this.getTargetPointer().getTargets(game, source)) { Permanent creature = game.getPermanentOrLKIBattlefield(creatureId); if (creature != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(creature, game)); effect.apply(game, source); toExile.addAll(effect.getAddedPermanent()); diff --git a/Mage.Sets/src/mage/cards/t/Tyrranax.java b/Mage.Sets/src/mage/cards/t/Tyrranax.java index 12d9b26384..ed12ed6ac8 100644 --- a/Mage.Sets/src/mage/cards/t/Tyrranax.java +++ b/Mage.Sets/src/mage/cards/t/Tyrranax.java @@ -36,6 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; /** @@ -45,8 +46,9 @@ import mage.constants.Zone; public class Tyrranax extends CardImpl { public Tyrranax(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(5); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/v/VisionCharm.java b/Mage.Sets/src/mage/cards/v/VisionCharm.java index fea2422cbe..242851a45b 100644 --- a/Mage.Sets/src/mage/cards/v/VisionCharm.java +++ b/Mage.Sets/src/mage/cards/v/VisionCharm.java @@ -102,6 +102,8 @@ class VisionCharmEffect extends ContinuousEffectImpl { public VisionCharmEffect(final VisionCharmEffect effect) { super(effect); + targetLandType = effect.targetLandType; + targetBasicLandType = effect.targetBasicLandType; } @Override @@ -120,8 +122,13 @@ class VisionCharmEffect extends ContinuousEffectImpl { choice = new ChoiceBasicLandType(); controller.choose(outcome, choice, game); targetBasicLandType = choice.getChoice(); + if (targetLandType == null || targetBasicLandType == null) { + this.discard(); + return; + } } else { this.discard(); + return; } FilterPermanent filter = new FilterLandPermanent(); filter.add(new SubtypePredicate(SubType.byDescription(targetLandType))); diff --git a/Mage.Sets/src/mage/cards/w/WakeningSunsAvatar.java b/Mage.Sets/src/mage/cards/w/WakeningSunsAvatar.java new file mode 100644 index 0000000000..e1d40982e5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WakeningSunsAvatar.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.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.CastFromHandSourceCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.watchers.common.CastFromHandWatcher; + +/** + * + * @author TheElk801 + */ +public class WakeningSunsAvatar extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Dinosaur creatures"); + + static { + filter.add(Predicates.not(new SubtypePredicate(SubType.DINOSAUR))); + } + + public WakeningSunsAvatar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}{W}"); + + this.subtype.add("Dinosaur"); + this.subtype.add("Avatar"); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // When Wakening Sun's Avatar enters the battlefield, if you cast it from you hand, destroy all non-Dinosaur creatures. + this.addAbility(new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filter), false), + CastFromHandSourceCondition.instance, + "When {this} enters the battlefield, if you cast it from your hand, destroy all non-Dinosaur creatures."), + new CastFromHandWatcher()); + } + + public WakeningSunsAvatar(final WakeningSunsAvatar card) { + super(card); + } + + @Override + public WakeningSunsAvatar copy() { + return new WakeningSunsAvatar(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java b/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java index ca0b759851..1d87a743ab 100644 --- a/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java +++ b/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java @@ -27,7 +27,6 @@ */ package mage.cards.w; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; @@ -49,6 +48,8 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -72,7 +73,7 @@ public class WalkerOfSecretWays extends CardImpl { this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{1}{U}"))); // Whenever Walker of Secret Ways deals combat damage to a player, look at that player's hand. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new WalkerOfSecretWaysEffect(), true, true)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new WalkerOfSecretWaysEffect(), false, true)); // {1}{U}: Return target Ninja you control to its owner's hand. Activate this ability only during your turn. Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{1}{U}"), MyTurnCondition.instance); diff --git a/Mage.Sets/src/mage/cards/w/WantedScoundrels.java b/Mage.Sets/src/mage/cards/w/WantedScoundrels.java new file mode 100644 index 0000000000..e8034cebb6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WantedScoundrels.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.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class WantedScoundrels extends CardImpl { + + public WantedScoundrels(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // When Wanted Scoundrels dies, target opponent creates two colorless Treasure artifact tokens with "T, Sacrifice this artifact: Add one mana of any color to your mana pool." + Ability ability = new DiesTriggeredAbility(new CreateTokenTargetEffect(new TreasureToken(), 2), false); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public WantedScoundrels(final WantedScoundrels card) { + super(card); + } + + @Override + public WantedScoundrels copy() { + return new WantedScoundrels(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java b/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java new file mode 100644 index 0000000000..5a12627c58 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java @@ -0,0 +1,111 @@ +/* + * 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.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class WildgrowthWalker extends CardImpl { + + public WildgrowthWalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add("Elemental"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life. + Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance()); + Ability ability = new WildgrowthWalkerTriggeredAbility(effect); + effect = new GainLifeEffect(3); + ability.addEffect(effect); + this.addAbility(ability); + } + + public WildgrowthWalker(final WildgrowthWalker card) { + super(card); + } + + @Override + public WildgrowthWalker copy() { + return new WildgrowthWalker(this); + } +} + +class WildgrowthWalkerTriggeredAbility extends TriggeredAbilityImpl { + + WildgrowthWalkerTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + WildgrowthWalkerTriggeredAbility(final WildgrowthWalkerTriggeredAbility effect) { + super(effect); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.EXPLORED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null) { + return creature.getControllerId().equals(controllerId); + } + return false; + } + + @Override + public WildgrowthWalkerTriggeredAbility copy() { + return new WildgrowthWalkerTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever a creature you control explores, put a +1/+1 counter on {this} and you gain 3 life"; + } +} diff --git a/Mage.Sets/src/mage/cards/w/WilyGoblin.java b/Mage.Sets/src/mage/cards/w/WilyGoblin.java new file mode 100644 index 0000000000..9df791cb7a --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WilyGoblin.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.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author TheElk801 + */ +public class WilyGoblin extends CardImpl { + + public WilyGoblin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{R}"); + + this.subtype.add("Goblin"); + this.subtype.add("Pirate"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); + } + + public WilyGoblin(final WilyGoblin card) { + super(card); + } + + @Override + public WilyGoblin copy() { + return new WilyGoblin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Exodus.java b/Mage.Sets/src/mage/sets/Exodus.java index 0221bc232c..05b9ae6630 100644 --- a/Mage.Sets/src/mage/sets/Exodus.java +++ b/Mage.Sets/src/mage/sets/Exodus.java @@ -135,6 +135,7 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Rootwater Alligator", 122, Rarity.COMMON, mage.cards.r.RootwaterAlligator.class)); cards.add(new SetCardInfo("Rootwater Mystic", 44, Rarity.COMMON, mage.cards.r.RootwaterMystic.class)); cards.add(new SetCardInfo("Sabertooth Wyvern", 99, Rarity.UNCOMMON, mage.cards.s.SabertoothWyvern.class)); + cards.add(new SetCardInfo("ScareTactics", 73, Rarity.COMMON, mage.cards.s.ScareTactics.class)); cards.add(new SetCardInfo("School of Piranha", 45, Rarity.COMMON, mage.cards.s.SchoolOfPiranha.class)); cards.add(new SetCardInfo("Scrivener", 46, Rarity.UNCOMMON, mage.cards.s.Scrivener.class)); cards.add(new SetCardInfo("Seismic Assault", 101, Rarity.RARE, mage.cards.s.SeismicAssault.class)); diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f6ee6ca705..5ec8f519e2 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -31,43 +31,109 @@ public class Ixalan extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); + cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); + cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); + cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); + cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); + cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); + cards.add(new SetCardInfo("Call to the Feast", 219, Rarity.UNCOMMON, mage.cards.c.CallToTheFeast.class)); cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); + cards.add(new SetCardInfo("Castaway's Despair", 281, Rarity.COMMON, mage.cards.c.CastawaysDespair.class)); + cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); + cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); + cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); + cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); cards.add(new SetCardInfo("Deadeye Tormentor", 98, Rarity.COMMON, mage.cards.d.DeadeyeTormentor.class)); cards.add(new SetCardInfo("Deadeye Tracker", 99, Rarity.RARE, mage.cards.d.DeadeyeTracker.class)); + cards.add(new SetCardInfo("Deathless Ancient", 100, Rarity.UNCOMMON, mage.cards.d.DeathlessAncient.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); + cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); + cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); + cards.add(new SetCardInfo("Drover of the Mighty", 167, Rarity.UNCOMMON, mage.cards.d.DroverOfTheMighty.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); + cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); + cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Duskborne Skymarcher", 9, Rarity.UNCOMMON, mage.cards.d.DuskborneSkymarcher.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); + cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); + cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); + cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); + cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); + cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); + cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); + cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); + cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); + cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); + cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); + cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); - cards.add(new SetCardInfo("Kumena's Omenspeaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasOmenspeaker.class)); + cards.add(new SetCardInfo("Kinjalli's Sunwing", 19, Rarity.RARE, mage.cards.k.KinjallisSunwing.class)); + cards.add(new SetCardInfo("Kitesail Freebooter", 110, Rarity.UNCOMMON, mage.cards.k.KitesailFreebooter.class)); + cards.add(new SetCardInfo("Kopala, Warden of Waves", 61, Rarity.RARE, mage.cards.k.KopalaWardenOfWaves.class)); + cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); + cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); + cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); + cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); + cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); + cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); + cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); + cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); + cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); + cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); + cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); + cards.add(new SetCardInfo("Ranging Raptors", 201, Rarity.UNCOMMON, mage.cards.r.RangingRaptors.class)); + cards.add(new SetCardInfo("Raptor Hatchling", 149, Rarity.UNCOMMON, mage.cards.r.RaptorHatchling.class)); + cards.add(new SetCardInfo("Ravenous Daggertooth", 202, Rarity.COMMON, mage.cards.r.RavenousDaggertooth.class)); + cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); cards.add(new SetCardInfo("River's Rebuke", 71, Rarity.RARE, mage.cards.r.RiversRebuke.class)); cards.add(new SetCardInfo("Rootbound Crag", 256, Rarity.RARE, mage.cards.r.RootboundCrag.class)); cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); + cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); + cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); + cards.add(new SetCardInfo("Savage Stomp", 205, Rarity.UNCOMMON, mage.cards.s.SavageStomp.class)); + cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); + cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); + cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); + cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); + cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); + cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); + cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); + cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.RARE, mage.cards.s.SpellPierce.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); + cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); + cards.add(new SetCardInfo("Storm Fleet Aerialist", 63, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); + cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); + cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); + cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); + cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); + cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); + cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); cards.add(new SetCardInfo("Tishana's Wayfinder", 211, Rarity.COMMON, mage.cards.t.TishanasWayfinder.class)); cards.add(new SetCardInfo("Tishana, Voice of Thunder", 230, Rarity.MYTHIC, mage.cards.t.TishanaVoiceOfThunder.class)); cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); @@ -78,7 +144,12 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); + cards.add(new SetCardInfo("Wakening Sun's Avatar", 44, Rarity.MYTHIC, mage.cards.w.WakeningSunsAvatar.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); - cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); + cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); + cards.add(new SetCardInfo("Wanted Scoundrels", 131, Rarity.UNCOMMON, mage.cards.w.WantedScoundrels.class)); + cards.add(new SetCardInfo("Wildgrowth Walker", 216, Rarity.UNCOMMON, mage.cards.w.WildgrowthWalker.class)); + cards.add(new SetCardInfo("Wily Goblin", 174, Rarity.UNCOMMON, mage.cards.w.WilyGoblin.class)); + cards.add(new SetCardInfo("Woodland Stream", 284, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } } diff --git a/Mage.Sets/src/mage/sets/Legions.java b/Mage.Sets/src/mage/sets/Legions.java index 6f407f9535..21d1a61636 100644 --- a/Mage.Sets/src/mage/sets/Legions.java +++ b/Mage.Sets/src/mage/sets/Legions.java @@ -97,6 +97,7 @@ public class Legions extends ExpansionSet { cards.add(new SetCardInfo("Essence Sliver", 13, Rarity.RARE, mage.cards.e.EssenceSliver.class)); cards.add(new SetCardInfo("Feral Throwback", 126, Rarity.RARE, mage.cards.f.FeralThrowback.class)); cards.add(new SetCardInfo("Flamewave Invoker", 92, Rarity.COMMON, mage.cards.f.FlamewaveInvoker.class)); + cards.add(new SetCardInfo("Frenetic Raptor", 93, Rarity.UNCOMMON, mage.cards.f.FreneticRaptor.class)); cards.add(new SetCardInfo("Fugitive Wizard", 38, Rarity.COMMON, mage.cards.f.FugitiveWizard.class)); cards.add(new SetCardInfo("Gempalm Avenger", 14, Rarity.COMMON, mage.cards.g.GempalmAvenger.class)); cards.add(new SetCardInfo("Gempalm Incinerator", 94, Rarity.UNCOMMON, mage.cards.g.GempalmIncinerator.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java new file mode 100644 index 0000000000..3e6a254819 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java @@ -0,0 +1,174 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.continuous; + +import mage.cards.Card; +import mage.constants.PhaseStep; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class SubTypeChangingEffectsTest extends CardTestPlayerBase { + + @Test + public void testConspiracyGiveType() { + // As Conspiracy enters the battlefield, choose a creature type. + // Creature cards you own that aren't on the battlefield, creature spells you control, and creatures you control are the chosen type. + addCard(Zone.HAND, playerA, "Conspiracy", 1); // Enchantment {3}{B}{B} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conspiracy"); + setChoice(playerA, "Orc"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Conspiracy", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + silvercoatLion = getPermanent("Silvercoat Lion", playerB); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should not have CAT type", false, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + for (Card card : playerB.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAR type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + for (Card card : playerB.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + + } + for (Card card : playerB.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + + } + } + + } + + /** + * Conspiracy doesn't revert creature types of non-permanent cards when it + * leaves the battlefield + */ + @Test + public void testConspiracyIsRestCorrectly() { + // As Conspiracy enters the battlefield, choose a creature type. + // Creature cards you own that aren't on the battlefield, creature spells you control, and creatures you control are the chosen type. + addCard(Zone.HAND, playerA, "Conspiracy", 1); // Enchantment {3}{B}{B} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Disenchant", 1); // Instant + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conspiracy"); + setChoice(playerA, "Orc"); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Disenchant", "Conspiracy"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, "Conspiracy", 1); + assertGraveyardCount(playerB, "Disenchant", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + + } + + } +} diff --git a/Mage/src/main/java/mage/abilities/Gender.java b/Mage/src/main/java/mage/abilities/Gender.java index d7dd334967..be6f398006 100644 --- a/Mage/src/main/java/mage/abilities/Gender.java +++ b/Mage/src/main/java/mage/abilities/Gender.java @@ -4,7 +4,7 @@ package mage.abilities; * Created by IGOUDT on 5-3-2017. */ public enum Gender { - MALE("his", "him"), FEMALE("her", "her"); + MALE("his", "him"), FEMALE("her", "her"), NEUTRAL("its", "it"); String personalPronoun; String possesivePronoun; @@ -22,5 +22,4 @@ public enum Gender { return possesivePronoun; } - } diff --git a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java index 2445b391bb..1649cc3ab5 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java @@ -97,7 +97,7 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI @Override public String getRule() { - return "Whenever a " + filter.getMessage() + " attacks, " + super.getRule(); + return "Whenever a" + (filter.getMessage().startsWith("a") ? "n " : " ") + " attacks, " + super.getRule(); } } diff --git a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java index a7cb368a6c..5dc4dd0e8e 100644 --- a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java @@ -95,7 +95,7 @@ public class EntersBattlefieldAbility extends StaticAbility { return; } } - super.addEffect(effect); //To change body of generated methods, choose Tools | Templates. + super.addEffect(effect); } @Override @@ -108,6 +108,6 @@ public class EntersBattlefieldAbility extends StaticAbility { if (abilityRule != null && !abilityRule.isEmpty()) { return abilityRule; } - return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield " + super.getRule(); + return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield" + super.getRule(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/PutTokenOntoBattlefieldCopySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/CreateTokenCopySourceEffect.java similarity index 57% rename from Mage/src/main/java/mage/abilities/effects/PutTokenOntoBattlefieldCopySourceEffect.java rename to Mage/src/main/java/mage/abilities/effects/CreateTokenCopySourceEffect.java index 5fdba542a4..d0220524e7 100644 --- a/Mage/src/main/java/mage/abilities/effects/PutTokenOntoBattlefieldCopySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/CreateTokenCopySourceEffect.java @@ -1,7 +1,7 @@ package mage.abilities.effects; import mage.abilities.Ability; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -10,21 +10,21 @@ import mage.target.targetpointer.FixedTarget; /** * Created by glerman on 20/6/15. */ -public class PutTokenOntoBattlefieldCopySourceEffect extends OneShotEffect { +public class CreateTokenCopySourceEffect extends OneShotEffect { private final int number; - public PutTokenOntoBattlefieldCopySourceEffect() { + public CreateTokenCopySourceEffect() { this(1); } - public PutTokenOntoBattlefieldCopySourceEffect(int copies) { + public CreateTokenCopySourceEffect(int copies) { super(Outcome.PutCreatureInPlay); this.number = copies; staticText = "create a token that's a copy of {this}"; } - public PutTokenOntoBattlefieldCopySourceEffect(final PutTokenOntoBattlefieldCopySourceEffect effect) { + public CreateTokenCopySourceEffect(final CreateTokenCopySourceEffect effect) { super(effect); this.number = effect.number; } @@ -33,7 +33,7 @@ public class PutTokenOntoBattlefieldCopySourceEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false, number); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, number); effect.setTargetPointer(new FixedTarget(source.getSourceId())); return effect.apply(game, source); } @@ -41,7 +41,7 @@ public class PutTokenOntoBattlefieldCopySourceEffect extends OneShotEffect { } @Override - public PutTokenOntoBattlefieldCopySourceEffect copy() { - return new PutTokenOntoBattlefieldCopySourceEffect(this); + public CreateTokenCopySourceEffect copy() { + return new CreateTokenCopySourceEffect(this); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java similarity index 84% rename from Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java rename to Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index 9c3e4da898..b268294353 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -54,7 +54,7 @@ import mage.util.functions.EmptyApplyToPermanent; * * @author LevelX2 */ -public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { +public class CreateTokenCopyTargetEffect extends OneShotEffect { private final UUID playerId; private final CardType additionalCardType; @@ -74,12 +74,12 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { private boolean useLKI = false; private boolean isntLegendary = false; - public PutTokenOntoBattlefieldCopyTargetEffect(boolean useLKI) { + public CreateTokenCopyTargetEffect(boolean useLKI) { this(); this.useLKI = useLKI; } - public PutTokenOntoBattlefieldCopyTargetEffect() { + public CreateTokenCopyTargetEffect() { super(Outcome.PutCreatureInPlay); this.playerId = null; this.additionalCardType = null; @@ -95,15 +95,15 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { this.color = null; } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId) { + public CreateTokenCopyTargetEffect(UUID playerId) { this(playerId, null, false); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste) { this(playerId, additionalCardType, gainsHaste, 1); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number) { this(playerId, additionalCardType, gainsHaste, number, false, false); } @@ -117,15 +117,15 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { * @param tapped * @param attacking */ - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking) { this(playerId, additionalCardType, gainsHaste, number, tapped, attacking, null); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer) { this(playerId, additionalCardType, gainsHaste, number, tapped, attacking, attackedPlayer, Integer.MIN_VALUE, Integer.MIN_VALUE, false); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer, int power, int toughness, boolean gainsFlying) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer, int power, int toughness, boolean gainsFlying) { super(Outcome.PutCreatureInPlay); this.playerId = playerId; this.additionalCardType = additionalCardType; @@ -140,7 +140,7 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { this.gainsFlying = gainsFlying; } - public PutTokenOntoBattlefieldCopyTargetEffect(final PutTokenOntoBattlefieldCopyTargetEffect effect) { + public CreateTokenCopyTargetEffect(final CreateTokenCopyTargetEffect effect) { super(effect); this.playerId = effect.playerId; this.additionalCardType = effect.additionalCardType; @@ -258,8 +258,8 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { } @Override - public PutTokenOntoBattlefieldCopyTargetEffect copy() { - return new PutTokenOntoBattlefieldCopyTargetEffect(this); + public CreateTokenCopyTargetEffect copy() { + return new CreateTokenCopyTargetEffect(this); } @Override @@ -267,27 +267,29 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - StringBuilder sb = new StringBuilder(); - sb.append("Put "); + StringBuilder sb = new StringBuilder("create "); if (number == 1) { - sb.append("a token"); + sb.append("a "); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append("token"); } else { - sb.append(CardUtil.numberToText(number)).append(" tokens"); + sb.append(number); + sb.append(" "); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append("tokens"); } - sb.append(" onto the battlefield "); - if (tapped && !attacking) { - sb.append("tapped "); - } else if (!tapped && attacking) { - sb.append("attacking "); - } else if (tapped && attacking) { - sb.append("tapped and attacking "); - } - sb.append("that's a copy of target "); - if (mode.getTargets() != null) { - sb.append(mode.getTargets().get(0).getTargetName()); + if (attacking) { + sb.append(" that are"); + if (tapped) { + sb.append(" tapped and"); + } + sb.append(" attacking"); } return sb.toString(); - } public List getAddedPermanent() { diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java index 025cebb7ac..05712cd92e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java @@ -27,8 +27,6 @@ */ package mage.abilities.effects.common; -import java.util.ArrayList; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; @@ -43,6 +41,9 @@ import mage.game.permanent.token.Token; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -113,7 +114,7 @@ public class CreateTokenEffect extends OneShotEffect { public ArrayList getLastAddedTokenIds() { return lastAddedTokenIds; } - + public void exileTokensCreatedAtNextEndStep(Game game, Ability source) { for (UUID tokenId : this.getLastAddedTokenIds()) { Permanent tokenPermanent = game.getPermanent(tokenId); @@ -122,7 +123,7 @@ public class CreateTokenEffect extends OneShotEffect { exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game)); game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect), source); } - } + } } public void exileTokensCreatedAtEndOfCombat(Game game, Ability source) { @@ -133,9 +134,9 @@ public class CreateTokenEffect extends OneShotEffect { exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game)); game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source); } - } + } } - + private void setText() { StringBuilder sb = new StringBuilder("create "); if (amount.toString().equals("1")) { @@ -151,10 +152,15 @@ public class CreateTokenEffect extends OneShotEffect { } sb.append(token.getDescription()); if (token.getDescription().endsWith("token")) { - sb.append("s "); + sb.append("s"); + } + int tokenLocation = sb.indexOf("token "); + if (tokenLocation != -1) { + sb.replace(tokenLocation, tokenLocation + 6, "tokens "); } } if (attacking) { + sb.append(" that are"); if (tapped) { sb.append(" tapped and"); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java index 863528dbbe..418b9e7593 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java @@ -67,25 +67,45 @@ public class CreateTokenTargetEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - StringBuilder sb = new StringBuilder("put "); - sb.append(CardUtil.numberToText(amount.toString(), "a")); - sb.append(' ').append(token.getDescription()).append(" onto the battlefield"); - if (tapped) { - sb.append(" tapped"); + StringBuilder sb = new StringBuilder(); + sb.append("target ").append(mode.getTargets().get(0).getTargetName()); + sb.append(" creates "); + if (amount.toString().equals("1")) { + sb.append("a "); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append(token.getDescription()); + } else { + sb.append(CardUtil.numberToText(amount.toString())).append(' '); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append(token.getDescription()); + if (token.getDescription().endsWith("token")) { + sb.append("s "); + } + int tokenLocation = sb.indexOf("token "); + if (tokenLocation != -1) { + sb.replace(tokenLocation, tokenLocation + 6, "tokens "); + } } if (attacking) { + sb.append(" that are"); if (tapped) { - sb.append(" and"); + sb.append(" tapped and"); } sb.append(" attacking"); } String message = amount.getMessage(); if (!message.isEmpty()) { - sb.append(" for each "); + if (amount.toString().equals("X")) { + sb.append(", where X is "); + } else { + sb.append(" for each "); + } } sb.append(message); - sb.append(" under target ").append(mode.getTargets().get(0).getTargetName()); - sb.append("'s control"); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java index 476ae10141..3a5d55092a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java @@ -23,9 +23,12 @@ import mage.players.Player; */ public class ExileAndReturnTransformedSourceEffect extends OneShotEffect { - protected Effect additionalEffect; + public ExileAndReturnTransformedSourceEffect() { + this(Gender.NEUTRAL); + } + public ExileAndReturnTransformedSourceEffect(Gender gender) { this(gender, null); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java index aceb92f35a..3b80d45ba1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java @@ -90,7 +90,7 @@ public class PopulateEffect extends OneShotEffect { if (!game.isSimulation()) { game.informPlayers("Token selected for populate: " + tokenToCopy.getLogName()); } - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(target.getFirstTarget())); return effect.apply(game, source); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java index 6a6949d37e..dced11b2a7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java @@ -66,7 +66,12 @@ public class ReturnToHandChosenControlledPermanentEffect extends ReturnToHandCho protected String getText() { StringBuilder sb = new StringBuilder("return "); if (!filter.getMessage().startsWith("another")) { - sb.append(CardUtil.numberToText(number, "a")); + if(filter.getMessage().startsWith("a")){ + sb.append("an"); + } + else { + sb.append(CardUtil.numberToText(number, "a")); + } } sb.append(' ').append(filter.getMessage()); if (number > 1) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java index cc9600fb9c..6a5f2e3d90 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java @@ -74,9 +74,9 @@ public class AttacksIfAbleTargetEffect extends RequirementEffect { return staticText; } if (this.duration == Duration.EndOfTurn) { - return new StringBuilder("Target ").append(mode.getTargets().get(0).getTargetName()).append(" attacks this turn if able").toString(); + return "Target " + mode.getTargets().get(0).getTargetName() + " attacks this turn if able"; } else { - return new StringBuilder("Target ").append(mode.getTargets().get(0).getTargetName()).append(" attacks each turn if able").toString(); + return "Target " + mode.getTargets().get(0).getTargetName() + " attacks each turn if able"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java index 42907477df..314897ecba 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java @@ -40,15 +40,8 @@ import mage.game.permanent.Permanent; */ public class CantAttackYouEffect extends RestrictionEffect { - private boolean canAttackYouAnyway = false; - public CantAttackYouEffect(Duration duration) { - this(duration, false); - } - - public CantAttackYouEffect(Duration duration, boolean canAttackYouAnyway) { super(duration); - this.canAttackYouAnyway = canAttackYouAnyway; } public CantAttackYouEffect(final CantAttackYouEffect effect) { @@ -67,11 +60,6 @@ public class CantAttackYouEffect extends RestrictionEffect { @Override public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) { - for (UUID player : game.getOpponents(source.getId())) { - if (attacker.canAttack(player, game)) { - return false; - } - } - return !canAttackYouAnyway; + return !defenderId.equals(source.getControllerId()); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java index 8384f291b9..5b5a7b55dd 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java @@ -33,6 +33,8 @@ import mage.abilities.effects.OneShotEffect; import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.targetpointer.FixedTarget; /** @@ -63,12 +65,17 @@ public class GoadTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); - effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); - game.addEffect(effect, source); - effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); - effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); - game.addEffect(effect, source); + Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + if (targetCreature != null && controller != null) { + ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); + game.addEffect(effect, source); + effect = new CantAttackYouEffect(Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); + game.addEffect(effect, source); + game.informPlayers(controller.getLogName() + " is goating " + targetCreature.getLogName()); + } return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java index fafe47f266..f68d71d251 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java @@ -29,13 +29,16 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.SubTypeList; -import java.util.List; - /** * @author nantuko */ @@ -44,7 +47,14 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { private SubTypeList setSubtypes = new SubTypeList(); private final AttachmentType attachmentType; - public SetCardSubtypeAttachedEffect(SubType setSubtype, Duration duration, AttachmentType attachmentType) { + public SetCardSubtypeAttachedEffect(Duration duration, AttachmentType attachmentType, SubType... setSubtype) { + super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + this.setSubtypes.add(setSubtype); + this.attachmentType = attachmentType; + this.setText(); + } + + /*public SetCardSubtypeAttachedEffect(SubType setSubtype, Duration duration, AttachmentType attachmentType) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.setSubtypes.add(setSubtype); this.attachmentType = attachmentType; @@ -56,7 +66,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { this.setSubtypes.addAll(setSubtypes); this.attachmentType = attachmentType; setText(); - } + }*/ public SetCardSubtypeAttachedEffect(final SetCardSubtypeAttachedEffect effect) { super(effect); diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java index b161c9578b..e6ea352256 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java @@ -39,6 +39,7 @@ import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -75,6 +76,7 @@ public class ExploreSourceEffect extends OneShotEffect { if (player == null) { return false; } + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EXPLORED, source.getSourceId(), source.getSourceId(), source.getControllerId())); if (player.getLibrary().hasCards()) { Card card = player.getLibrary().getFromTop(game); Cards cards = new CardsImpl(); diff --git a/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java b/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java index d09b69ee59..79f0754e57 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java @@ -35,7 +35,7 @@ import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.constants.Outcome; import mage.constants.SetTargetPointer; import mage.game.Game; @@ -102,7 +102,7 @@ class MyriadEffect extends OneShotEffect { Player opponent = game.getPlayer(playerId); if (opponent != null && controller.chooseUse(Outcome.PutCreatureInPlay, "Put a copy of " + sourceObject.getIdName() + " onto battlefield attacking " + opponent.getName() + '?', source, game)) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(controller.getId(), null, false, 1, true, true, playerId); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(controller.getId(), null, false, 1, true, true, playerId); effect.setTargetPointer(new FixedTarget(sourceObject, game)); effect.apply(game, source); tokens.addAll(effect.getAddedPermanent()); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index cd6edde011..9c597260dc 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -1,396 +1,410 @@ package mage.constants; -import mage.util.SubTypeList; - import java.util.Arrays; import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; +import mage.util.SubTypeList; + public enum SubType { //205.3k Instants and sorceries share their lists of subtypes; these subtypes are called spell types. - ARCANE("Arcane", SubTypeSet.SpellType, false), - TRAP("Trap", SubTypeSet.SpellType, false), + ARCANE("Arcane", SubTypeSet.SpellType), + TRAP("Trap", SubTypeSet.SpellType), + // 205.3i: Lands have their own unique set of subtypes; these subtypes are called land types. // Of that list, Forest, Island, Mountain, Plains, and Swamp are the basic land types. - FOREST("Forest", SubTypeSet.BasicLandType, false), - ISLAND("Island", SubTypeSet.BasicLandType, false), - MOUNTAIN("Mountain", SubTypeSet.BasicLandType, false), - PLAINS("Plains", SubTypeSet.BasicLandType, false), - SWAMP("Swamp", SubTypeSet.BasicLandType, false), - DESERT("Desert", SubTypeSet.NonBasicLandType, false), - GATE("Gate", SubTypeSet.NonBasicLandType, false), - LAIR("Lair", SubTypeSet.NonBasicLandType, false), - LOCUS("Locus", SubTypeSet.NonBasicLandType, false), - URZAS("Urza's", SubTypeSet.NonBasicLandType, false), - MINE("Mine", SubTypeSet.NonBasicLandType, false), - POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType, false), - TOWER("Tower", SubTypeSet.NonBasicLandType, false), + FOREST("Forest", SubTypeSet.BasicLandType), + ISLAND("Island", SubTypeSet.BasicLandType), + MOUNTAIN("Mountain", SubTypeSet.BasicLandType), + PLAINS("Plains", SubTypeSet.BasicLandType), + SWAMP("Swamp", SubTypeSet.BasicLandType), + DESERT("Desert", SubTypeSet.NonBasicLandType), + GATE("Gate", SubTypeSet.NonBasicLandType), + LAIR("Lair", SubTypeSet.NonBasicLandType), + LOCUS("Locus", SubTypeSet.NonBasicLandType), + URZAS("Urza's", SubTypeSet.NonBasicLandType), + MINE("Mine", SubTypeSet.NonBasicLandType), + POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType), + TOWER("Tower", SubTypeSet.NonBasicLandType), + // 205.3h Enchantments have their own unique set of subtypes; these subtypes are called enchantment types. - AURA("Aura", SubTypeSet.EnchantmentType, false), - CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType, false), - CURSE("Curse", SubTypeSet.EnchantmentType, false), - SHRINE("Shrine", SubTypeSet.EnchantmentType, false), + AURA("Aura", SubTypeSet.EnchantmentType), + CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType), + CURSE("Curse", SubTypeSet.EnchantmentType), + SHRINE("Shrine", SubTypeSet.EnchantmentType), + // 205.3g: Artifacts have their own unique set of subtypes; these subtypes are called artifact types. - CLUE("Clue", SubTypeSet.ArtifactType, false), - CONTRAPTION("Contraption", SubTypeSet.ArtifactType, false), - EQUIPMENT("Equipment", SubTypeSet.ArtifactType, false), - FORTIFICATION("Fortification", SubTypeSet.ArtifactType, false), - TREASURE("Treasure", SubTypeSet.ArtifactType, false), - VEHICLE("Vehicle", SubTypeSet.ArtifactType, false), + CLUE("Clue", SubTypeSet.ArtifactType), + CONTRAPTION("Contraption", SubTypeSet.ArtifactType), + EQUIPMENT("Equipment", SubTypeSet.ArtifactType), + FORTIFICATION("Fortification", SubTypeSet.ArtifactType), + TREASURE("Treasure", SubTypeSet.ArtifactType), + VEHICLE("Vehicle", SubTypeSet.ArtifactType), + // 205.3m : Creatures and tribals share their lists of subtypes; these subtypes are called creature types. // A - ADVISOR("Advisor", SubTypeSet.CreatureType, false), - AETHERBORN("Aetherborn", SubTypeSet.CreatureType, false), - ALLY("Ally", SubTypeSet.CreatureType, false), - ANGEL("Angel", SubTypeSet.CreatureType, false), - ANTELOPE("Antelope", SubTypeSet.CreatureType, false), + ADVISOR("Advisor", SubTypeSet.CreatureType), + AETHERBORN("Aetherborn", SubTypeSet.CreatureType), + ALLY("Ally", SubTypeSet.CreatureType), + ANGEL("Angel", SubTypeSet.CreatureType), + ANTELOPE("Antelope", SubTypeSet.CreatureType), AQUALISH("Aqualish", SubTypeSet.CreatureType, true), // Star Wars - APE("Ape", SubTypeSet.CreatureType, false), + APE("Ape", SubTypeSet.CreatureType), ARCONA("Arcona", SubTypeSet.CreatureType, true), - ARCHER("Archer", SubTypeSet.CreatureType, false), - ARCHON("Archon", SubTypeSet.CreatureType, false), - ARTIFICER("Artificer", SubTypeSet.CreatureType, false), + ARCHER("Archer", SubTypeSet.CreatureType), + ARCHON("Archon", SubTypeSet.CreatureType), + ARTIFICER("Artificer", SubTypeSet.CreatureType), ARTIFICIER("Artificier", SubTypeSet.CreatureType, true), - ASSASSIN("Assassin", SubTypeSet.CreatureType, false), - ASSEMBLY_WORKER("Assembly-Worker", SubTypeSet.CreatureType, false), - ATOG("Atog", SubTypeSet.CreatureType, false), + ASSASSIN("Assassin", SubTypeSet.CreatureType), + ASSEMBLY_WORKER("Assembly-Worker", SubTypeSet.CreatureType), + ATOG("Atog", SubTypeSet.CreatureType), ATAT("AT-AT", SubTypeSet.CreatureType, true), - AUROCHS("Aurochs", SubTypeSet.CreatureType, false), + AUROCHS("Aurochs", SubTypeSet.CreatureType), AUTOBOT("Autobot", SubTypeSet.CreatureType, true), // H17, Grimlock - AVATAR("Avatar", SubTypeSet.CreatureType, false), + AVATAR("Avatar", SubTypeSet.CreatureType), // B - BADGER("Badger", SubTypeSet.CreatureType, false), - BARBARIAN("Barbarian", SubTypeSet.CreatureType, false), - BASILISK("Basilisk", SubTypeSet.CreatureType, false), - BAT("Bat", SubTypeSet.CreatureType, false), - BEAR("Bear", SubTypeSet.CreatureType, false), - BEAST("Beast", SubTypeSet.CreatureType, false), - BEEBLE("Beeble", SubTypeSet.CreatureType, false), - BERSERKER("Berserker", SubTypeSet.CreatureType, false), - BIRD("Bird", SubTypeSet.CreatureType, false), + BADGER("Badger", SubTypeSet.CreatureType), + BARBARIAN("Barbarian", SubTypeSet.CreatureType), + BASILISK("Basilisk", SubTypeSet.CreatureType), + BAT("Bat", SubTypeSet.CreatureType), + BEAR("Bear", SubTypeSet.CreatureType), + BEAST("Beast", SubTypeSet.CreatureType), + BEEBLE("Beeble", SubTypeSet.CreatureType), + BERSERKER("Berserker", SubTypeSet.CreatureType), + BIRD("Bird", SubTypeSet.CreatureType), BITH("Bith", SubTypeSet.CreatureType, true), // Star Wars - BLINKMOTH("Blinkmoth", SubTypeSet.CreatureType, false), - BOAR("Boar", SubTypeSet.CreatureType, false), - BRINGER("Bringer", SubTypeSet.CreatureType, false), - BRUSHWAGG("Brushwagg", SubTypeSet.CreatureType, false), + BLINKMOTH("Blinkmoth", SubTypeSet.CreatureType), + BOAR("Boar", SubTypeSet.CreatureType), + BRINGER("Bringer", SubTypeSet.CreatureType), + BRUSHWAGG("Brushwagg", SubTypeSet.CreatureType), // C CALAMARI("Calamari", SubTypeSet.CreatureType, true), // Star Wars - CAMARID("Camarid", SubTypeSet.CreatureType, false), - CAMEL("Camel", SubTypeSet.CreatureType, false), - CARIBOU("Caribou", SubTypeSet.CreatureType, false), - CARRIER("Carrier", SubTypeSet.CreatureType, false), - CAT("Cat", SubTypeSet.CreatureType, false), - CENTAUR("Centaur", SubTypeSet.CreatureType, false), + CAMARID("Camarid", SubTypeSet.CreatureType), + CAMEL("Camel", SubTypeSet.CreatureType), + CARIBOU("Caribou", SubTypeSet.CreatureType), + CARRIER("Carrier", SubTypeSet.CreatureType), + CAT("Cat", SubTypeSet.CreatureType), + CENTAUR("Centaur", SubTypeSet.CreatureType), CEREAN("Cerean", SubTypeSet.CreatureType, true), // Star Wars - CEPHALID("Cephalid", SubTypeSet.CreatureType, false), - CHIMERA("Chimera", SubTypeSet.CreatureType, false), + CEPHALID("Cephalid", SubTypeSet.CreatureType), + CHIMERA("Chimera", SubTypeSet.CreatureType), CHISS("Chiss", SubTypeSet.CreatureType, true), - CITIZEN("Citizen", SubTypeSet.CreatureType, false), - CLERIC("Cleric", SubTypeSet.CreatureType, false), - COCKATRICE("Cockatrice", SubTypeSet.CreatureType, false), - CONSTRUCT("Construct", SubTypeSet.CreatureType, false), - COWARD("Coward", SubTypeSet.CreatureType, false), - CRAB("Crab", SubTypeSet.CreatureType, false), - CROCODILE("Crocodile", SubTypeSet.CreatureType, false), + CITIZEN("Citizen", SubTypeSet.CreatureType), + CLERIC("Cleric", SubTypeSet.CreatureType), + COCKATRICE("Cockatrice", SubTypeSet.CreatureType), + CONSTRUCT("Construct", SubTypeSet.CreatureType), + COWARD("Coward", SubTypeSet.CreatureType), + CRAB("Crab", SubTypeSet.CreatureType), + CROCODILE("Crocodile", SubTypeSet.CreatureType), CYBORG("Cyborg", SubTypeSet.CreatureType, true), // Star Wars - CYCLOPS("Cyclops", SubTypeSet.CreatureType, false), + CYCLOPS("Cyclops", SubTypeSet.CreatureType), // D DATHOMIRIAN("Dathomirian", SubTypeSet.CreatureType, true), // Star Wars - DAUTHI("Dauthi", SubTypeSet.CreatureType, false), - DEMON("Demon", SubTypeSet.CreatureType, false), - DESERTER("Deserter", SubTypeSet.CreatureType, false), - DEVIL("Devil", SubTypeSet.CreatureType, false), - DINOSAUR("Dinosaur", SubTypeSet.CreatureType, false), // With Ixalan now being spoiled, need this to be selectable - DJINN("Djinn", SubTypeSet.CreatureType, false), - DRAGON("Dragon", SubTypeSet.CreatureType, false), - DRAKE("Drake", SubTypeSet.CreatureType, false), - DREADNOUGHT("Dreadnought", SubTypeSet.CreatureType, false), - DRONE("Drone", SubTypeSet.CreatureType, false), - DRUID("Druid", SubTypeSet.CreatureType, false), + DAUTHI("Dauthi", SubTypeSet.CreatureType), + DEMON("Demon", SubTypeSet.CreatureType), + DESERTER("Deserter", SubTypeSet.CreatureType), + DEVIL("Devil", SubTypeSet.CreatureType), + DINOSAUR("Dinosaur", SubTypeSet.CreatureType), // With Ixalan now being spoiled, need this to be selectable + DJINN("Djinn", SubTypeSet.CreatureType), + DRAGON("Dragon", SubTypeSet.CreatureType), + DRAKE("Drake", SubTypeSet.CreatureType), + DREADNOUGHT("Dreadnought", SubTypeSet.CreatureType), + DRONE("Drone", SubTypeSet.CreatureType), + DRUID("Druid", SubTypeSet.CreatureType), DROID("Droid", SubTypeSet.CreatureType, true), // Star Wars - DRYAD("Dryad", SubTypeSet.CreatureType, false), - DWARF("Dwarf", SubTypeSet.CreatureType, false), + DRYAD("Dryad", SubTypeSet.CreatureType), + DWARF("Dwarf", SubTypeSet.CreatureType), // E - EFREET("Efreet", SubTypeSet.CreatureType, false), - ELDER("Elder", SubTypeSet.CreatureType, false), - ELDRAZI("Eldrazi", SubTypeSet.CreatureType, false), - ELEMENTAL("Elemental", SubTypeSet.CreatureType, false), - ELEPHANT("Elephant", SubTypeSet.CreatureType, false), - ELF("Elf", SubTypeSet.CreatureType, false), - ELK("Elk", SubTypeSet.CreatureType, false), - EYE("Eye", SubTypeSet.CreatureType, false), + EFREET("Efreet", SubTypeSet.CreatureType), + ELDER("Elder", SubTypeSet.CreatureType), + ELDRAZI("Eldrazi", SubTypeSet.CreatureType), + ELEMENTAL("Elemental", SubTypeSet.CreatureType), + ELEPHANT("Elephant", SubTypeSet.CreatureType), + ELF("Elf", SubTypeSet.CreatureType), + ELK("Elk", SubTypeSet.CreatureType), + EYE("Eye", SubTypeSet.CreatureType), EWOK("Ewok", SubTypeSet.CreatureType, true), // Star Wars // F - FAERIE("Faerie", SubTypeSet.CreatureType, false), - FERRET("Ferret", SubTypeSet.CreatureType, false), - FISH("Fish", SubTypeSet.CreatureType, false), - FLAGBEARER("Flagbearer", SubTypeSet.CreatureType, false), - FOX("Fox", SubTypeSet.CreatureType, false), - FROG("Frog", SubTypeSet.CreatureType, false), - FUNGUS("Fungus", SubTypeSet.CreatureType, false), + FAERIE("Faerie", SubTypeSet.CreatureType), + FERRET("Ferret", SubTypeSet.CreatureType), + FISH("Fish", SubTypeSet.CreatureType), + FLAGBEARER("Flagbearer", SubTypeSet.CreatureType), + FOX("Fox", SubTypeSet.CreatureType), + FROG("Frog", SubTypeSet.CreatureType), + FUNGUS("Fungus", SubTypeSet.CreatureType), // G GAMORREAN("Gamorrean", SubTypeSet.CreatureType, true), // Star Wars GAND("Gand", SubTypeSet.CreatureType, true), // Star Wars - GARGOYLE("Gargoyle", SubTypeSet.CreatureType, false), - GERM("Germ", SubTypeSet.CreatureType, false), - GIANT("Giant", SubTypeSet.CreatureType, false), - GNOME("Gnome", SubTypeSet.CreatureType, false), - GOLEM("Golem", SubTypeSet.CreatureType, false), - GOAT("Goat", SubTypeSet.CreatureType, false), - GOBLIN("Goblin", SubTypeSet.CreatureType, false), - GOD("God", SubTypeSet.CreatureType, false), - GORGON("Gorgon", SubTypeSet.CreatureType, false), - GRAVEBORN("Graveborn", SubTypeSet.CreatureType, false), - GREMLIN("Gremlin", SubTypeSet.CreatureType, false), - GRIFFIN("Griffin", SubTypeSet.CreatureType, false), + GARGOYLE("Gargoyle", SubTypeSet.CreatureType), + GERM("Germ", SubTypeSet.CreatureType), + GIANT("Giant", SubTypeSet.CreatureType), + GNOME("Gnome", SubTypeSet.CreatureType), + GOLEM("Golem", SubTypeSet.CreatureType), + GOAT("Goat", SubTypeSet.CreatureType), + GOBLIN("Goblin", SubTypeSet.CreatureType), + GOD("God", SubTypeSet.CreatureType), + GORGON("Gorgon", SubTypeSet.CreatureType), + GRAVEBORN("Graveborn", SubTypeSet.CreatureType), + GREMLIN("Gremlin", SubTypeSet.CreatureType), + GRIFFIN("Griffin", SubTypeSet.CreatureType), GUNGAN("Gungan", SubTypeSet.CreatureType, true), // Star Wars // H - HAG("Hag", SubTypeSet.CreatureType, false), - HARPY("Harpy", SubTypeSet.CreatureType, false), - HELLION("Hellion", SubTypeSet.CreatureType, false), - HIPPO("Hippo", SubTypeSet.CreatureType, false), - HIPPOGRIFF("Hippogriff", SubTypeSet.CreatureType, false), - HOMARID("Homarid", SubTypeSet.CreatureType, false), - HOMUNCULUS("Homunculus", SubTypeSet.CreatureType, false), - HORROR("Horror", SubTypeSet.CreatureType, false), - HORSE("Horse", SubTypeSet.CreatureType, false), - HOUND("Hound", SubTypeSet.CreatureType, false), - HUMAN("Human", SubTypeSet.CreatureType, false), - HUNTER("Hunter", SubTypeSet.CreatureType, false), + HAG("Hag", SubTypeSet.CreatureType), + HARPY("Harpy", SubTypeSet.CreatureType), + HELLION("Hellion", SubTypeSet.CreatureType), + HIPPO("Hippo", SubTypeSet.CreatureType), + HIPPOGRIFF("Hippogriff", SubTypeSet.CreatureType), + HOMARID("Homarid", SubTypeSet.CreatureType), + HOMUNCULUS("Homunculus", SubTypeSet.CreatureType), + HORROR("Horror", SubTypeSet.CreatureType), + HORSE("Horse", SubTypeSet.CreatureType), + HOUND("Hound", SubTypeSet.CreatureType), + HUMAN("Human", SubTypeSet.CreatureType), + HUNTER("Hunter", SubTypeSet.CreatureType), HUTT("Hutt", SubTypeSet.CreatureType, true), // Star Wars - HYDRA("Hydra", SubTypeSet.CreatureType, false), - HYENA("Hyena", SubTypeSet.CreatureType, false), + HYDRA("Hydra", SubTypeSet.CreatureType), + HYENA("Hyena", SubTypeSet.CreatureType), // I - ILLUSION("Illusion", SubTypeSet.CreatureType, false), - IMP("Imp", SubTypeSet.CreatureType, false), - INCARNATION("Incarnation", SubTypeSet.CreatureType, false), - INSECT("Insect", SubTypeSet.CreatureType, false), + ILLUSION("Illusion", SubTypeSet.CreatureType), + IMP("Imp", SubTypeSet.CreatureType), + INCARNATION("Incarnation", SubTypeSet.CreatureType), + INSECT("Insect", SubTypeSet.CreatureType), ITHORIAN("Ithorian", SubTypeSet.CreatureType, true), // Star Wars // J - JACKAL("Jackal", SubTypeSet.CreatureType, false), + JACKAL("Jackal", SubTypeSet.CreatureType), JAWA("Jawa", SubTypeSet.CreatureType, true), JEDI("Jedi", SubTypeSet.CreatureType, true), // Star Wars - JELLYFISH("Jellyfish", SubTypeSet.CreatureType, false), - JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType, false), + JELLYFISH("Jellyfish", SubTypeSet.CreatureType), + JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType), // K KALEESH("Kaleesh", SubTypeSet.CreatureType, true), // Star Wars - KAVU("Kavu", SubTypeSet.CreatureType, false), + KAVU("Kavu", SubTypeSet.CreatureType), KELDOR("KelDor", SubTypeSet.CreatureType, true), - KIRIN("Kirin", SubTypeSet.CreatureType, false), - KITHKIN("Kithkin", SubTypeSet.CreatureType, false), - KNIGHT("Knight", SubTypeSet.CreatureType, false), - KOBOLD("Kobold", SubTypeSet.CreatureType, false), + KIRIN("Kirin", SubTypeSet.CreatureType), + KITHKIN("Kithkin", SubTypeSet.CreatureType), + KNIGHT("Knight", SubTypeSet.CreatureType), + KOBOLD("Kobold", SubTypeSet.CreatureType), KOORIVAR("Koorivar", SubTypeSet.CreatureType, true), - KOR("Kor", SubTypeSet.CreatureType, false), - KRAKEN("Kraken", SubTypeSet.CreatureType, false), + KOR("Kor", SubTypeSet.CreatureType), + KRAKEN("Kraken", SubTypeSet.CreatureType), // L - LAMIA("Lamia", SubTypeSet.CreatureType, false), - LAMMASU("Lammasu", SubTypeSet.CreatureType, false), - LEECH("Leech", SubTypeSet.CreatureType, false), - LEVIATHAN("Leviathan", SubTypeSet.CreatureType, false), - LHURGOYF("Lhurgoyf", SubTypeSet.CreatureType, false), - LICID("Licid", SubTypeSet.CreatureType, false), - LIZARD("Lizard", SubTypeSet.CreatureType, false), + LAMIA("Lamia", SubTypeSet.CreatureType), + LAMMASU("Lammasu", SubTypeSet.CreatureType), + LEECH("Leech", SubTypeSet.CreatureType), + LEVIATHAN("Leviathan", SubTypeSet.CreatureType), + LHURGOYF("Lhurgoyf", SubTypeSet.CreatureType), + LICID("Licid", SubTypeSet.CreatureType), + LIZARD("Lizard", SubTypeSet.CreatureType), // M MANTELLIAN("Mantellian", SubTypeSet.CreatureType, true), // Star Wars - MANTICORE("Manticore", SubTypeSet.CreatureType, false), - MASTICORE("Masticore", SubTypeSet.CreatureType, false), - MERCENARY("Mercenary", SubTypeSet.CreatureType, false), - MERFOLK("Merfolk", SubTypeSet.CreatureType, false), - METATHRAN("Metathran", SubTypeSet.CreatureType, false), - MINION("Minion", SubTypeSet.CreatureType, false), - MINOTAUR("Minotaur", SubTypeSet.CreatureType, false), + MANTICORE("Manticore", SubTypeSet.CreatureType), + MASTICORE("Masticore", SubTypeSet.CreatureType), + MERCENARY("Mercenary", SubTypeSet.CreatureType), + MERFOLK("Merfolk", SubTypeSet.CreatureType), + METATHRAN("Metathran", SubTypeSet.CreatureType), + MINION("Minion", SubTypeSet.CreatureType), + MINOTAUR("Minotaur", SubTypeSet.CreatureType), MIRIALAN("Mirialan", SubTypeSet.CreatureType, true), // Star Wars - MOLE("Mole", SubTypeSet.CreatureType, false), - MONGER("Monger", SubTypeSet.CreatureType, false), - MONGOOSE("Mongoose", SubTypeSet.CreatureType, false), - MONK("Monk", SubTypeSet.CreatureType, false), - MONKEY("Monkey", SubTypeSet.CreatureType, false), - MOONFOLK("Moonfolk", SubTypeSet.CreatureType, false), - MUTANT("Mutant", SubTypeSet.CreatureType, false), - MYR("Myr", SubTypeSet.CreatureType, false), - MYSTIC("Mystic", SubTypeSet.CreatureType, false), + MOLE("Mole", SubTypeSet.CreatureType), + MONGER("Monger", SubTypeSet.CreatureType), + MONGOOSE("Mongoose", SubTypeSet.CreatureType), + MONK("Monk", SubTypeSet.CreatureType), + MONKEY("Monkey", SubTypeSet.CreatureType), + MOONFOLK("Moonfolk", SubTypeSet.CreatureType), + MUTANT("Mutant", SubTypeSet.CreatureType), + MYR("Myr", SubTypeSet.CreatureType), + MYSTIC("Mystic", SubTypeSet.CreatureType), // N - NAGA("Naga", SubTypeSet.CreatureType, false), - NAUTILUS("Nautilus", SubTypeSet.CreatureType, false), + NAGA("Naga", SubTypeSet.CreatureType), + NAUTILUS("Nautilus", SubTypeSet.CreatureType), NAUTOLAN("Nautolan", SubTypeSet.CreatureType, true), // Star Wars NEIMOIDIAN("Neimoidian", SubTypeSet.CreatureType, true), // Star Wars - NEPHILIM("Nephilim", SubTypeSet.CreatureType, false), - NIGHTMARE("Nightmare", SubTypeSet.CreatureType, false), - NIGHTSTALKER("Nightstalker", SubTypeSet.CreatureType, false), - NINJA("Ninja", SubTypeSet.CreatureType, false), - NOGGLE("Noggle", SubTypeSet.CreatureType, false), - NOMAD("Nomad", SubTypeSet.CreatureType, false), - NYMPH("Nymph", SubTypeSet.CreatureType, false), + NEPHILIM("Nephilim", SubTypeSet.CreatureType), + NIGHTMARE("Nightmare", SubTypeSet.CreatureType), + NIGHTSTALKER("Nightstalker", SubTypeSet.CreatureType), + NINJA("Ninja", SubTypeSet.CreatureType), + NOGGLE("Noggle", SubTypeSet.CreatureType), + NOMAD("Nomad", SubTypeSet.CreatureType), + NYMPH("Nymph", SubTypeSet.CreatureType), // O - OCTOPUS("Octopus", SubTypeSet.CreatureType, false), - OGRE("Ogre", SubTypeSet.CreatureType, false), - OOZE("Ooze", SubTypeSet.CreatureType, false), - ORB("Orb", SubTypeSet.CreatureType, false), - ORC("Orc", SubTypeSet.CreatureType, false), - ORGG("Orgg", SubTypeSet.CreatureType, false), + OCTOPUS("Octopus", SubTypeSet.CreatureType), + OGRE("Ogre", SubTypeSet.CreatureType), + OOZE("Ooze", SubTypeSet.CreatureType), + ORB("Orb", SubTypeSet.CreatureType), + ORC("Orc", SubTypeSet.CreatureType), + ORGG("Orgg", SubTypeSet.CreatureType), ORTOLAN("Ortolan", SubTypeSet.CreatureType, true), - OUPHE("Ouphe", SubTypeSet.CreatureType, false), - OX("Ox", SubTypeSet.CreatureType, false), - OYSTER("Oyster", SubTypeSet.CreatureType, false), + OUPHE("Ouphe", SubTypeSet.CreatureType), + OX("Ox", SubTypeSet.CreatureType), + OYSTER("Oyster", SubTypeSet.CreatureType), // P - PEGASUS("Pegasus", SubTypeSet.CreatureType, false), - PENTAVITE("Pentavite", SubTypeSet.CreatureType, false), - PEST("Pest", SubTypeSet.CreatureType, false), - PHELDDAGRIF("Phelddagrif", SubTypeSet.CreatureType, false), - PHOENIX("Phoenix", SubTypeSet.CreatureType, false), - PILOT("Pilot", SubTypeSet.CreatureType, false), - PINCHER("Pincher", SubTypeSet.CreatureType, false), - PIRATE("Pirate", SubTypeSet.CreatureType, false), - PLANT("Plant", SubTypeSet.CreatureType, false), - PRAETOR("Praetor", SubTypeSet.CreatureType, false), - PRISM("Prism", SubTypeSet.CreatureType, false), - PROCESSOR("Processor", SubTypeSet.CreatureType, false), + PEGASUS("Pegasus", SubTypeSet.CreatureType), + PENTAVITE("Pentavite", SubTypeSet.CreatureType), + PEST("Pest", SubTypeSet.CreatureType), + PHELDDAGRIF("Phelddagrif", SubTypeSet.CreatureType), + PHOENIX("Phoenix", SubTypeSet.CreatureType), + PILOT("Pilot", SubTypeSet.CreatureType), + PINCHER("Pincher", SubTypeSet.CreatureType), + PIRATE("Pirate", SubTypeSet.CreatureType), + PLANT("Plant", SubTypeSet.CreatureType), + PRAETOR("Praetor", SubTypeSet.CreatureType), + PRISM("Prism", SubTypeSet.CreatureType), + PROCESSOR("Processor", SubTypeSet.CreatureType), PUREBLOOD("Pureblood", SubTypeSet.CreatureType, true), // Q QUARREN("Quarren", SubTypeSet.CreatureType, true), // Star Wars // R - RABBIT("Rabbit", SubTypeSet.CreatureType, false), - RAT("Rat", SubTypeSet.CreatureType, false), - REBEL("Rebel", SubTypeSet.CreatureType, false), - REFLECTION("Reflection", SubTypeSet.CreatureType, false), - RHINO("Rhino", SubTypeSet.CreatureType, false), - RIGGER("Rigger", SubTypeSet.CreatureType, false), + RABBIT("Rabbit", SubTypeSet.CreatureType), + RAT("Rat", SubTypeSet.CreatureType), + REBEL("Rebel", SubTypeSet.CreatureType), + REFLECTION("Reflection", SubTypeSet.CreatureType), + RHINO("Rhino", SubTypeSet.CreatureType), + RIGGER("Rigger", SubTypeSet.CreatureType), RODIAN("Rodian", SubTypeSet.CreatureType, true), // Star Wars - ROGUE("Rogue", SubTypeSet.CreatureType, false), + ROGUE("Rogue", SubTypeSet.CreatureType), // S - SABLE("Sable", SubTypeSet.CreatureType, false), - SALAMANDER("Salamander", SubTypeSet.CreatureType, false), - SAMURAI("Samurai", SubTypeSet.CreatureType, false), - SAND("Sand", SubTypeSet.CreatureType, false), - SAPROLING("Saproling", SubTypeSet.CreatureType, false), - SATYR("Satyr", SubTypeSet.CreatureType, false), - SCARECROW("Scarecrow", SubTypeSet.CreatureType, false), - SCION("Scion", SubTypeSet.CreatureType, false), - SCORPION("Scorpion", SubTypeSet.CreatureType, false), - SCOUT("Scout", SubTypeSet.CreatureType, false), - SERF("Serf", SubTypeSet.CreatureType, false), - SERPENT("Serpent", SubTypeSet.CreatureType, false), - SERVO("Servo", SubTypeSet.CreatureType, false), - SHADE("Shade", SubTypeSet.CreatureType, false), - SHAMAN("Shaman", SubTypeSet.CreatureType, false), - SHAPESHIFTER("Shapeshifter", SubTypeSet.CreatureType, false), - SHEEP("Sheep", SubTypeSet.CreatureType, false), - SIREN("Siren", SubTypeSet.CreatureType, false), - SITH("Sith", SubTypeSet.CreatureType, false), - SKELETON("Skeleton", SubTypeSet.CreatureType, false), - SLITH("Slith", SubTypeSet.CreatureType, false), - SLIVER("Sliver", SubTypeSet.CreatureType, false), - SLUG("Slug", SubTypeSet.CreatureType, false), - SNAKE("Snake", SubTypeSet.CreatureType, false), - SOLDIER("Soldier", SubTypeSet.CreatureType, false), - SOLTARI("Soltari", SubTypeSet.CreatureType, false), - SPAWN("Spawn", SubTypeSet.CreatureType, false), - SPECTER("Specter", SubTypeSet.CreatureType, false), - SPELLSHAPER("Spellshaper", SubTypeSet.CreatureType, false), - SPHINX("Sphinx", SubTypeSet.CreatureType, false), - SPIDER("Spider", SubTypeSet.CreatureType, false), - SPIKE("Spike", SubTypeSet.CreatureType, false), - SPIRIT("Spirit", SubTypeSet.CreatureType, false), - SPLITTER("Splitter", SubTypeSet.CreatureType, false), - SPONGE("Sponge", SubTypeSet.CreatureType, false), - SQUID("Squid", SubTypeSet.CreatureType, false), - SQUIRREL("Squirrel", SubTypeSet.CreatureType, false), - STARFISH("Starfish", SubTypeSet.CreatureType, false), + SABLE("Sable", SubTypeSet.CreatureType), + SALAMANDER("Salamander", SubTypeSet.CreatureType), + SAMURAI("Samurai", SubTypeSet.CreatureType), + SAND("Sand", SubTypeSet.CreatureType), + SAPROLING("Saproling", SubTypeSet.CreatureType), + SATYR("Satyr", SubTypeSet.CreatureType), + SCARECROW("Scarecrow", SubTypeSet.CreatureType), + SCION("Scion", SubTypeSet.CreatureType), + SCORPION("Scorpion", SubTypeSet.CreatureType), + SCOUT("Scout", SubTypeSet.CreatureType), + SERF("Serf", SubTypeSet.CreatureType), + SERPENT("Serpent", SubTypeSet.CreatureType), + SERVO("Servo", SubTypeSet.CreatureType), + SHADE("Shade", SubTypeSet.CreatureType), + SHAMAN("Shaman", SubTypeSet.CreatureType), + SHAPESHIFTER("Shapeshifter", SubTypeSet.CreatureType), + SHEEP("Sheep", SubTypeSet.CreatureType), + SIREN("Siren", SubTypeSet.CreatureType), + SITH("Sith", SubTypeSet.CreatureType), + SKELETON("Skeleton", SubTypeSet.CreatureType), + SLITH("Slith", SubTypeSet.CreatureType), + SLIVER("Sliver", SubTypeSet.CreatureType), + SLUG("Slug", SubTypeSet.CreatureType), + SNAKE("Snake", SubTypeSet.CreatureType), + SOLDIER("Soldier", SubTypeSet.CreatureType), + SOLTARI("Soltari", SubTypeSet.CreatureType), + SPAWN("Spawn", SubTypeSet.CreatureType), + SPECTER("Specter", SubTypeSet.CreatureType), + SPELLSHAPER("Spellshaper", SubTypeSet.CreatureType), + SPHINX("Sphinx", SubTypeSet.CreatureType), + SPIDER("Spider", SubTypeSet.CreatureType), + SPIKE("Spike", SubTypeSet.CreatureType), + SPIRIT("Spirit", SubTypeSet.CreatureType), + SPLITTER("Splitter", SubTypeSet.CreatureType), + SPONGE("Sponge", SubTypeSet.CreatureType), + SQUID("Squid", SubTypeSet.CreatureType), + SQUIRREL("Squirrel", SubTypeSet.CreatureType), + STARFISH("Starfish", SubTypeSet.CreatureType), STARSHIP("Starship", SubTypeSet.CreatureType, true), // Star Wars SULLUSTAN("Sullustan", SubTypeSet.CreatureType, true), // Star Wars - SURRAKAR("Surrakar", SubTypeSet.CreatureType, false), - SURVIVOR("Survivor", SubTypeSet.CreatureType, false), + SURRAKAR("Surrakar", SubTypeSet.CreatureType), + SURVIVOR("Survivor", SubTypeSet.CreatureType), // T - TETRAVITE("Tetravite", SubTypeSet.CreatureType, false), - THALAKOS("Thalakos", SubTypeSet.CreatureType, false), - THOPTER("Thopter", SubTypeSet.CreatureType, false), + TETRAVITE("Tetravite", SubTypeSet.CreatureType), + THALAKOS("Thalakos", SubTypeSet.CreatureType), + THOPTER("Thopter", SubTypeSet.CreatureType), TRANDOSHAN("Trandoshan", SubTypeSet.CreatureType, true), // Star Wars - THRULL("Thrull", SubTypeSet.CreatureType, false), - TREEFOLK("Treefolk", SubTypeSet.CreatureType, false), - TRISKELAVITE("Triskelavite", SubTypeSet.CreatureType, false), - TROLL("Troll", SubTypeSet.CreatureType, false), - TURTLE("Turtle", SubTypeSet.CreatureType, false), + THRULL("Thrull", SubTypeSet.CreatureType), + TREEFOLK("Treefolk", SubTypeSet.CreatureType), + TRISKELAVITE("Triskelavite", SubTypeSet.CreatureType), + TROLL("Troll", SubTypeSet.CreatureType), + TURTLE("Turtle", SubTypeSet.CreatureType), TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars // U UGNAUGHT("Ugnaught", SubTypeSet.CreatureType, true), - UNICORN("Unicorn", SubTypeSet.CreatureType, false), + UNICORN("Unicorn", SubTypeSet.CreatureType), //V - VAMPIRE("Vampire", SubTypeSet.CreatureType, false), - VEDALKEN("Vedalken", SubTypeSet.CreatureType, false), - VIASHINO("Viashino", SubTypeSet.CreatureType, false), - VOLVER("Volver", SubTypeSet.CreatureType, false), + VAMPIRE("Vampire", SubTypeSet.CreatureType), + VEDALKEN("Vedalken", SubTypeSet.CreatureType), + VIASHINO("Viashino", SubTypeSet.CreatureType), + VOLVER("Volver", SubTypeSet.CreatureType), //W - WALL("Wall", SubTypeSet.CreatureType, false), - WARRIOR("Warrior", SubTypeSet.CreatureType, false), + WALL("Wall", SubTypeSet.CreatureType), + WARRIOR("Warrior", SubTypeSet.CreatureType), WEEQUAY("Weequay", SubTypeSet.CreatureType, true), - WEIRD("Weird", SubTypeSet.CreatureType, false), - WEREWOLF("Werewolf", SubTypeSet.CreatureType, false), - WHALE("Whale", SubTypeSet.CreatureType, false), - WIZARD("Wizard", SubTypeSet.CreatureType, false), - WOLF("Wolf", SubTypeSet.CreatureType, false), - WOLVERINE("Wolverine", SubTypeSet.CreatureType, false), - WOMBAT("Wombat", SubTypeSet.CreatureType, false), + WEIRD("Weird", SubTypeSet.CreatureType), + WEREWOLF("Werewolf", SubTypeSet.CreatureType), + WHALE("Whale", SubTypeSet.CreatureType), + WIZARD("Wizard", SubTypeSet.CreatureType), + WOLF("Wolf", SubTypeSet.CreatureType), + WOLVERINE("Wolverine", SubTypeSet.CreatureType), + WOMBAT("Wombat", SubTypeSet.CreatureType), WOOKIEE("Wookiee", SubTypeSet.CreatureType, true), // Star Wars - WORM("Worm", SubTypeSet.CreatureType, false), - WRAITH("Wraith", SubTypeSet.CreatureType, false), - WURM("Wurm", SubTypeSet.CreatureType, false), + WORM("Worm", SubTypeSet.CreatureType), + WRAITH("Wraith", SubTypeSet.CreatureType), + WURM("Wurm", SubTypeSet.CreatureType), // Y - YETI("Yeti", SubTypeSet.CreatureType, false), + YETI("Yeti", SubTypeSet.CreatureType), // Z ZABRAK("Zabrak", SubTypeSet.CreatureType, true), // Star Wars - ZOMBIE("Zombie", SubTypeSet.CreatureType, false), - ZUBERA("Zubera", SubTypeSet.CreatureType, false), + ZOMBIE("Zombie", SubTypeSet.CreatureType), + ZUBERA("Zubera", SubTypeSet.CreatureType), // Planeswalker - AJANI("Ajani", SubTypeSet.PlaneswalkerType, false), - ARLINN("Arlinn", SubTypeSet.PlaneswalkerType, false), - ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType, false), + AJANI("Ajani", SubTypeSet.PlaneswalkerType), + ARLINN("Arlinn", SubTypeSet.PlaneswalkerType), + ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType), AURRA("Aurra", SubTypeSet.PlaneswalkerType, true), // Star Wars - BOLAS("Bolas", SubTypeSet.PlaneswalkerType, false), - CHANDRA("Chandra", SubTypeSet.PlaneswalkerType, false), - DACK("Dack", SubTypeSet.PlaneswalkerType, false), - DARETTI("Daretti", SubTypeSet.PlaneswalkerType, false), - DOMRI("Domri", SubTypeSet.PlaneswalkerType, false), + BOLAS("Bolas", SubTypeSet.PlaneswalkerType), + CHANDRA("Chandra", SubTypeSet.PlaneswalkerType), + DACK("Dack", SubTypeSet.PlaneswalkerType), + DARETTI("Daretti", SubTypeSet.PlaneswalkerType), + DOMRI("Domri", SubTypeSet.PlaneswalkerType), DOOKU("Dooku", SubTypeSet.PlaneswalkerType, true), // Star Wars - DOVIN("Dovin", SubTypeSet.PlaneswalkerType, false), - ELSPETH("Elspeth", SubTypeSet.PlaneswalkerType, false), - FREYALISE("Freyalise", SubTypeSet.PlaneswalkerType, false), - GARRUK("Garruk", SubTypeSet.PlaneswalkerType, false), - GIDEON("Gideon", SubTypeSet.PlaneswalkerType, false), - HUATLI("Huatli", SubTypeSet.PlaneswalkerType, false), - JACE("Jace", SubTypeSet.PlaneswalkerType, false), - KARN("Karn", SubTypeSet.PlaneswalkerType, false), - KAYA("Kaya", SubTypeSet.PlaneswalkerType, false), - KIORA("Kiora", SubTypeSet.PlaneswalkerType, false), - KOTH("Koth", SubTypeSet.PlaneswalkerType, false), - LILIANA("Liliana", SubTypeSet.PlaneswalkerType, false), - NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType, false), - NARSET("Narset", SubTypeSet.PlaneswalkerType, false), - NISSA("Nissa", SubTypeSet.PlaneswalkerType, false), - NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType, false), + DOVIN("Dovin", SubTypeSet.PlaneswalkerType), + ELSPETH("Elspeth", SubTypeSet.PlaneswalkerType), + FREYALISE("Freyalise", SubTypeSet.PlaneswalkerType), + GARRUK("Garruk", SubTypeSet.PlaneswalkerType), + GIDEON("Gideon", SubTypeSet.PlaneswalkerType), + HUATLI("Huatli", SubTypeSet.PlaneswalkerType), + JACE("Jace", SubTypeSet.PlaneswalkerType), + KARN("Karn", SubTypeSet.PlaneswalkerType), + KAYA("Kaya", SubTypeSet.PlaneswalkerType), + KIORA("Kiora", SubTypeSet.PlaneswalkerType), + KOTH("Koth", SubTypeSet.PlaneswalkerType), + LILIANA("Liliana", SubTypeSet.PlaneswalkerType), + NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType), + NARSET("Narset", SubTypeSet.PlaneswalkerType), + NISSA("Nissa", SubTypeSet.PlaneswalkerType), + NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType), OBI_WAN("Obi-Wan", SubTypeSet.PlaneswalkerType, true), // Star Wars - RAL("Ral", SubTypeSet.PlaneswalkerType, false), - SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType, false), - SAMUT("Samut", SubTypeSet.PlaneswalkerType, false), - SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType, false), + RAL("Ral", SubTypeSet.PlaneswalkerType), + SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType), + SAMUT("Samut", SubTypeSet.PlaneswalkerType), + SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType), SIDIOUS("Sidious", SubTypeSet.PlaneswalkerType, true), // Star Wars - SORIN("Sorin", SubTypeSet.PlaneswalkerType, false), - TAMIYO("Tamiyo", SubTypeSet.PlaneswalkerType, false), - TEFERI("Teferi", SubTypeSet.PlaneswalkerType, false), - TEZZERET("Tezzeret", SubTypeSet.PlaneswalkerType, false), - TIBALT("Tibalt", SubTypeSet.PlaneswalkerType, false), - UGIN("Ugin", SubTypeSet.PlaneswalkerType, false), - VENSER("Venser", SubTypeSet.PlaneswalkerType, false), - VRASKA("Vraska", SubTypeSet.PlaneswalkerType, false), - XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType, false), + SORIN("Sorin", SubTypeSet.PlaneswalkerType), + TAMIYO("Tamiyo", SubTypeSet.PlaneswalkerType), + TEFERI("Teferi", SubTypeSet.PlaneswalkerType), + TEZZERET("Tezzeret", SubTypeSet.PlaneswalkerType), + TIBALT("Tibalt", SubTypeSet.PlaneswalkerType), + UGIN("Ugin", SubTypeSet.PlaneswalkerType), + VENSER("Venser", SubTypeSet.PlaneswalkerType), + VRASKA("Vraska", SubTypeSet.PlaneswalkerType), + XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType), YODA("Yoda", SubTypeSet.PlaneswalkerType, true); // Star Wars private final SubTypeSet subTypeSet; + SubType(String description, SubTypeSet subTypeSet) { + this(description, subTypeSet, false); + } + + SubType(String description, SubTypeSet subTypeSet, boolean customSet) { + this.description = description; + this.subTypeSet = subTypeSet; + this.customSet = customSet; + } + public String getDescription() { return description; } @@ -404,12 +418,6 @@ public enum SubType { return description; } - SubType(String description, SubTypeSet subTypeSet, boolean customSet) { - this.description = description; - this.subTypeSet = subTypeSet; - this.customSet = customSet; - } - public static SubType byDescription(String subType) { for (SubType s : values()) { if (s.getDescription().equals(subType)) { @@ -434,7 +442,10 @@ public enum SubType { } public static Set getBasicLands(boolean customSet) { - return Arrays.stream(values()).filter(s -> s.customSet == customSet).filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType).collect(Collectors.toSet()); + return Arrays.stream(values()) + .filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType) + .filter(s -> s.customSet == customSet) + .collect(Collectors.toSet()); } public static SubTypeList getLandTypes(boolean customSet) { diff --git a/Mage/src/main/java/mage/game/CardAttribute.java b/Mage/src/main/java/mage/game/CardAttribute.java index 5aa24b9e5f..7a5908c5f7 100644 --- a/Mage/src/main/java/mage/game/CardAttribute.java +++ b/Mage/src/main/java/mage/game/CardAttribute.java @@ -5,42 +5,43 @@ */ package mage.game; +import java.io.Serializable; import mage.ObjectColor; import mage.cards.Card; import mage.util.SubTypeList; -import java.io.Serializable; - /** - * This class saves changed attributes of cards (e.g. in graveyard, exile or player hands or libraries). - * + * This class saves changed attributes of cards (e.g. in graveyard, exile or + * player hands or libraries). + * * @author LevelX2 */ -public class CardAttribute implements Serializable { - +public class CardAttribute implements Serializable { + protected ObjectColor color; protected SubTypeList subtype; public CardAttribute(Card card) { color = card.getColor(null).copy(); - subtype = card.getSubtype(null); + subtype = new SubTypeList(); + subtype.addAll(subtype); } public CardAttribute(CardAttribute cardAttribute) { this.color = cardAttribute.color; this.subtype = cardAttribute.subtype; } - + public CardAttribute copy() { return new CardAttribute(this); } - + public ObjectColor getColor() { - return color; + return color; } - + public SubTypeList getSubtype() { return subtype; } - + } diff --git a/Mage/src/main/java/mage/game/draft/DraftImpl.java b/Mage/src/main/java/mage/game/draft/DraftImpl.java index 702ae547fe..409bc796f0 100644 --- a/Mage/src/main/java/mage/game/draft/DraftImpl.java +++ b/Mage/src/main/java/mage/game/draft/DraftImpl.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,14 +20,14 @@ * 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.game.draft; +import java.util.*; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.game.draft.DraftOptions.TimingOption; @@ -36,8 +36,6 @@ import mage.game.events.TableEvent.EventType; import mage.players.Player; import mage.players.PlayerList; -import java.util.*; - /** * * @author BetaSteward_at_googlemail.com @@ -89,9 +87,9 @@ public abstract class DraftImpl implements Draft { DraftPlayer newDraftPlayer = new DraftPlayer(newPlayer); DraftPlayer oldDraftPlayer = players.get(oldPlayer.getId()); newDraftPlayer.setBooster(oldDraftPlayer.getBooster()); - Map newPlayers = new LinkedHashMap<>(); + Map newPlayers = new LinkedHashMap<>(); synchronized (players) { - for(Map.Entry entry :players.entrySet()) { + for (Map.Entry entry : players.entrySet()) { if (entry.getKey().equals(oldPlayer.getId())) { newPlayers.put(newPlayer.getId(), newDraftPlayer); } else { @@ -99,7 +97,7 @@ public abstract class DraftImpl implements Draft { } } players.clear(); - for (Map.Entry entry: newPlayers.entrySet()) { + for (Map.Entry entry : newPlayers.entrySet()) { players.put(entry.getKey(), entry.getValue()); } } @@ -109,7 +107,7 @@ public abstract class DraftImpl implements Draft { currentId = newPlayer.getId(); } table.clear(); - for(UUID playerId : players.keySet()) { + for (UUID playerId : players.keySet()) { table.add(playerId); } @@ -117,7 +115,9 @@ public abstract class DraftImpl implements Draft { } if (oldDraftPlayer.isPicking()) { newDraftPlayer.setPicking(); - newDraftPlayer.getPlayer().pickCard(newDraftPlayer.getBooster(), newDraftPlayer.getDeck(), this); + if (!newDraftPlayer.getBooster().isEmpty()) { + newDraftPlayer.getPlayer().pickCard(newDraftPlayer.getBooster(), newDraftPlayer.getDeck(), this); + } } return true; } @@ -143,7 +143,7 @@ public abstract class DraftImpl implements Draft { /** * Number of boosters that each player gets in this draft - * + * * @return */ @Override @@ -151,7 +151,6 @@ public abstract class DraftImpl implements Draft { return numberBoosters; } - @Override public List getSets() { return sets; @@ -219,10 +218,9 @@ public abstract class DraftImpl implements Draft { } } - protected void openBooster() { if (boosterNum < numberBoosters) { - for (DraftPlayer player: players.values()) { + for (DraftPlayer player : players.values()) { if (draftCube != null) { player.setBooster(draftCube.createBooster()); } else { @@ -237,25 +235,26 @@ public abstract class DraftImpl implements Draft { protected boolean pickCards() { cardNum++; - for (DraftPlayer player: players.values()) { + for (DraftPlayer player : players.values()) { if (player.getBooster().isEmpty()) { return false; } player.setPicking(); player.getPlayer().pickCard(player.getBooster(), player.getDeck(), this); } - synchronized(this) { + synchronized (this) { while (!donePicking()) { try { this.wait(); - } catch (InterruptedException ex) { } + } catch (InterruptedException ex) { + } } } return true; } protected boolean donePicking() { - if(isAbort()) { + if (isAbort()) { return true; } return players.values() @@ -304,14 +303,14 @@ public abstract class DraftImpl implements Draft { public boolean addPick(UUID playerId, UUID cardId, Set hiddenCards) { DraftPlayer player = players.get(playerId); if (player.isPicking()) { - for (Card card: player.booster) { + for (Card card : player.booster) { if (card.getId().equals(cardId)) { player.addPick(card, hiddenCards); player.booster.remove(card); break; } } - synchronized(this) { + synchronized (this) { this.notifyAll(); } } @@ -341,7 +340,7 @@ public abstract class DraftImpl implements Draft { @Override public void resetBufferedCards() { Set setsDone = new HashSet<>(); - for(ExpansionSet set: sets) { + for (ExpansionSet set : sets) { if (!setsDone.contains(set)) { set.removeSavedCards(); setsDone.add(set); @@ -350,5 +349,4 @@ public abstract class DraftImpl implements Draft { } - } diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index 5033931abc..b6b65c4847 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -91,6 +91,7 @@ public class GameEvent implements Serializable { EMPTY_DRAW, DRAW_CARDS, // applies to an instruction to draw more than one card before any replacement effects apply to individual cards drawn DRAW_CARD, DREW_CARD, + EXPLORED, MIRACLE_CARD_REVEALED, MADNESS_CARD_EXILED, INVESTIGATED, diff --git a/Mage/src/main/java/mage/game/permanent/token/DinosaurToken.java b/Mage/src/main/java/mage/game/permanent/token/DinosaurToken.java new file mode 100644 index 0000000000..8ba4b59073 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/DinosaurToken.java @@ -0,0 +1,50 @@ +/* +* 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.game.permanent.token; + +import mage.constants.CardType; +import mage.MageInt; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.SubType; + +/** + * + * @author TheElk801 + */ +public class DinosaurToken extends Token { + + public DinosaurToken() { + super("Dinosaur", "3/3 green Dinosaur creature token with trample"); + cardType.add(CardType.CREATURE); + color.setGreen(true); + subtype.add(SubType.DINOSAUR); + power = new MageInt(3); + toughness = new MageInt(3); + addAbility(TrampleAbility.getInstance()); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/IxalanVampireToken.java b/Mage/src/main/java/mage/game/permanent/token/IxalanVampireToken.java new file mode 100644 index 0000000000..acaa977a89 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/IxalanVampireToken.java @@ -0,0 +1,49 @@ +/* +* 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.game.permanent.token; + +import mage.constants.CardType; +import mage.MageInt; +import mage.abilities.keyword.LifelinkAbility; + +/** + * + * @author TheElk801 + */ +public class IxalanVampireToken extends Token { + + public IxalanVampireToken() { + super("Vampire", "1/1 white Vampire creature token with lifelink"); + cardType.add(CardType.CREATURE); + color.setWhite(true); + subtype.add("Vampire"); + power = new MageInt(1); + toughness = new MageInt(1); + addAbility(LifelinkAbility.getInstance()); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/MerfolkHexproofToken.java b/Mage/src/main/java/mage/game/permanent/token/MerfolkHexproofToken.java new file mode 100644 index 0000000000..84503c437e --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/MerfolkHexproofToken.java @@ -0,0 +1,32 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.HexproofAbility; +import mage.constants.CardType; + +/** + * + * @author TacomenX + */ + +public class MerfolkHexproofToken extends Token { + + + + public MerfolkHexproofToken() { + super("Merfolk", "1/1 blue Merfolk creature token with hexproof"); + this.cardType.add(CardType.CREATURE); + this.subtype.add("Merfolk"); + this.color = ObjectColor.BLUE; + this.power = new MageInt(1); + this.toughness = new MageInt(1); + this.addAbility(HexproofAbility.getInstance()); + } + +} \ No newline at end of file diff --git a/Mage/src/main/java/mage/game/permanent/token/PirateToken.java b/Mage/src/main/java/mage/game/permanent/token/PirateToken.java new file mode 100644 index 0000000000..fe4d04270f --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/PirateToken.java @@ -0,0 +1,50 @@ +/* +* 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.game.permanent.token; + +import mage.constants.CardType; +import mage.MageInt; +import mage.abilities.keyword.MenaceAbility; +import mage.constants.SubType; + +/** + * + * @author TheElk801 + */ +public class PirateToken extends Token { + + public PirateToken() { + super("Pirate", "2/2 black Pirate creature token with menace"); + cardType.add(CardType.CREATURE); + color.setBlack(true); + subtype.add(SubType.PIRATE); + power = new MageInt(2); + toughness = new MageInt(2); + addAbility(new MenaceAbility()); + } +} diff --git a/Mage/src/main/java/mage/util/SubTypeList.java b/Mage/src/main/java/mage/util/SubTypeList.java index 71d920983d..8f90b17a8b 100644 --- a/Mage/src/main/java/mage/util/SubTypeList.java +++ b/Mage/src/main/java/mage/util/SubTypeList.java @@ -1,20 +1,27 @@ package mage.util; -import mage.constants.SubType; - import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import mage.constants.SubType; + public class SubTypeList extends ArrayList { + @Deprecated public boolean addAll(List subtypes) { - return addAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + return addAll(subtypes.stream() + .map(SubType::byDescription) + .collect(Collectors.toList())); } + @Deprecated public boolean removeAll(List subtypes){ - return removeAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + return removeAll(subtypes.stream() + .map(SubType::byDescription) + .collect(Collectors.toList())); } @@ -22,10 +29,17 @@ public class SubTypeList extends ArrayList { return Collections.addAll(this, subTypes); } + public boolean removeAll(SubType... subTypes) { + return super.removeAll(Arrays.stream(subTypes) + .collect(Collectors.toList())); + } + + @Deprecated public boolean add(String s) { return add(SubType.byDescription(s)); } + @Deprecated public boolean contains(String s) { return contains(SubType.byDescription(s)); } diff --git a/Utils/cardClass.tmpl b/Utils/cardClass.tmpl index e5afa68f0a..587020011c 100644 --- a/Utils/cardClass.tmpl +++ b/Utils/cardClass.tmpl @@ -34,6 +34,9 @@ if ($power || $power eq 0) { }else { $OUT .= "\nimport mage.MageInt;" } +if ($hasSubTypes eq 'true') { + $OUT .="\nimport mage.constants.SubType;" +} } =][=$abilitiesImports=] import mage.cards.CardImpl; diff --git a/Utils/gen-card.pl b/Utils/gen-card.pl index 9f011e081f..7a2646f1cb 100755 --- a/Utils/gen-card.pl +++ b/Utils/gen-card.pl @@ -186,6 +186,8 @@ $vars{'toughness'} = $card[7]; my @types; $vars{'planeswalker'} = 'false'; $vars{'subType'} = ''; +$vars{'hasSubTypes'} = 'false'; +$vars{'hasSuperTypes'} = 'false'; my $cardAbilities = $card[8]; my $type = $card[5]; while ($type =~ m/([a-zA-Z]+)( )*/g) { @@ -197,10 +199,13 @@ while ($type =~ m/([a-zA-Z]+)( )*/g) { } } else { if (@types) { - $vars{'subType'} .= "\n this.subtype.add(\"$1\");"; + my $st = uc($1); + $vars{'subType'} .= "\n this.subtype.add(SubType.$st);"; + $vars{'hasSubTypes'} = 'true'; } else { my $st = uc($1); - $vars{'subType'} .= "\n addSuperType(SuperType.$st);"; + $vars{'subType'} .= "\n this.addSuperType(SuperType.$st);"; + $vars{'hasSuperTypes'} = 'true'; } } } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 43b5c776ea..5471170848 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -11196,7 +11196,7 @@ Daru Sanctifier|Legions|9|C|{3}{W}|Creature - Human Cleric|1|4|Morph {1}{W} Y Clickslither|Legions|90|R|{1}{R}{R}{R}|Creature - Insect|3|3|Haste$Sacrifice a Goblin: Clickslither gets +2/+2 and gains trample until end of turn.| Crested Craghorn|Legions|91|C|{4}{R}|Creature - Goat Beast|4|1|Haste$Provoke (When this attacks, you may have target creature defending player controls untap and block it if able.)| Flamewave Invoker|Legions|92|C|{2}{R}|Creature - Goblin Mutant|2|2|{7}{R}: Flamewave Invoker deals 5 damage to target player.| -Frenetic Raptor|Legions|93|U|{5}{R}|Creature - Lizard Beast|6|6|Beasts can't block.| +Frenetic Raptor|Legions|93|U|{5}{R}|Creature - Dinosaur Beast|6|6|Beasts can't block.| Gempalm Incinerator|Legions|94|U|{2}{R}|Creature - Goblin|2|1|Cycling {1}{R} ({1}{R}, Discard this card: Draw a card.)$When you cycle Gempalm Incinerator, you may have it deal X damage to target creature, where X is the number of Goblins on the battlefield.| Goblin Assassin|Legions|95|U|{3}{R}{R}|Creature - Goblin Assassin|2|2|Whenever Goblin Assassin or another Goblin enters the battlefield, each player flips a coin. Each player whose coin comes up tails sacrifices a creature.| Goblin Clearcutter|Legions|96|U|{3}{R}|Creature - Goblin|3|3|{tap}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G} to your mana pool.| @@ -32331,68 +32331,106 @@ Cinder Barrens|Hour of Devastation|209|C||Land|||Cinder Barrens enters the battl Ashes of the Abhorrent|Ixalan|2|R|{1}{W}|Enchantment|||Players can't cast spells from graveyards or activate abilities from graveyards.$Whenever a creature dies, you gain 1 life.| Bellowing Aegisaur|Ixalan|4|U|{5}{W}|Creature - Dinosaur|3|5|Enrage - Whenever Bellowing Aegisaur is dealt damage, put a +1/+1 counter on each other creature you control.| Bishop of Rebirth|Ixalan|5|R|Creature - Vampire Cleric|3|4|Vigilance$Whenever Bishop of Rebirth attacks, you may return target creature card with converted mana cost 3 or less from your graveyard to the battlefield.| +Duskborne Skymarcher|Ixalan|9|U|{W}|Creature - Vampire Cleric|1|1|Flying${W}, {T}: Target attacking vampire gets +1/+1 until end of turn.| Goring Ceratops|Ixalan|13|R|Creature - Dinosaur|3|3|Double strike$Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn.| +Ixalan's Binding|Ixalan|17|U|{3}{W}|Enchantment|||When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield.$Your opponents can't cast spells with the same name as the exiled card.| Kinjalli's Sunwing|Ixalan|19|R|{2}{W}|Creature - Dinosaur|2|3|Flying$Creatures your opponents control enter the battlefield tapped.| Mavren Fein, Dusk Apostle|Ixalan|24|R|{2}{W}|Legendary Creature - Vampire Cleric|2|2|Whenever one or more nontoken Vampires you control attack, create a 1/1 white Vampire creature token with lifelink.| Priest of the Wakening Sun|Ixalan|27|R|{W}|Creature - Human Cleric|1|1|At the beginning of your upkeep, you may reveal a Dinosaur card from your hand. If you do, you gain 2 life.${3}{W}{W}, Sacrifice Priest of the Wakening Sun: Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle your library.| Sanguine Sacrament|Ixalan|33|R|{X}{W}{W}|Instant|||You gain twice X life. Put Sanguine Sacrament on the bottom of its owner's library.| Settle the Wreckage|Ixalan|34|R|{2}{W}{W}|Instant|||Exile all attacking creatures target player controls. That player may search his or her library for that many basic land cards, put those cards onto the battlefield tapped, then shuffle his or her library.| Tocatli Honor Guard|Ixalan|42|R|{1}{W}|Creature - Human Soldier|1|3|Creatures entering the battlefield don't cause abilities to trigger.| +Wakening Sun's Avatar|Ixalan|44|M|{5}{W}{W}{W}|Creature - Dinosaur Avatar|7|7|When Wakening Sun's Avatar enters the battlefield, if you cast if from you hand, destroy all non-Dinosaur creatures.| Arcane Adaptation|Ixalan|46|R|{2}{U}|Enchantment|||As Arcane Adaptation enters the battlefield, choose a creature type.$Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.| Daring Saboteur|Ixalan|49|R|{1}{U}|Creature - Human Pirate|2|1|{2}{U}: Daring Saboteur can't be blocked this turn.$Whenever Daring Saboteur deals combat damage to a player, you may draw a card. If you do, discard a card.| +Deadeye Quartermaster|Ixalan|50|U|{3}{U}|Creature - Human Pirate|2|2|When Deadeye Quartermaster enters the battlefield, you may search your library for an Equipment or a Vehicle card and put it into your hand. If you do, shuffle your library.| Deeproot Waters|Ixalan|51|U|{2}{U}|Enchantment|||Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof.| Dreamcaller Siren|Ixalan|54|R|{2}{U}{U}|Creature - Siren Pirate|3|3|Flash$Flying$Dreamcaller Siren can only block creatures with flying.$When Dreamcaller Siren enters the battlefield, if you control another Pirate, tap up to two nonland permanents.| Entrancing Melody|Ixalan|55|R|{X}{U}{U}|Instant|||Gain control of target creature with converted mana cost X.| +Favorable Winds|Ixalan|56|U|{1}{U}|Enchantment|||Creatures you control with flying get +1/+1.| Herald of Secret Streams|Ixalan|59|R|{3}{U}|Creature - Merfolk Warrior|2|3|Creatures you control with +1/+1 counters on them can't be blocked.| +Headwater Sentries|Ixalan|58|C|{3}{U}|Creature - Merfolk Warrior|2|5|| Jace, Cunning Castaway|Ixalan|60|M|{1}{U}{U}|Legendary Planeswalker - Jace|||+1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card.$-2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it."$-5: Create two tokens that are copies of Jace, Cunning Castaway, except they're not legendary.| Kopala, Warden of Waves|Ixalan|61|R|{1}{U}{U}|Legendary Creature - Merfolk Wizard|2|2|Spells your opponents cast that target a Merfolk you control cost {2} more to cast.$Abilities your opponents activate that target a Merfolk you control cost {2} more to activate.| +Storm Fleet Aerialist|Ixalan|63|U|{1}{U}|Creature - Human Pirate|1|2|Flying$Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.| +Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven cards.| +Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| +Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| +Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| +Arguel's Blood Fast|Ixalan|90|R|{1}{B}|Legendary Enchantment|||{1}{B}, Pay 2 life: Draw a card.$At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast.| +Temple of Aclazotz|Ixalan|90|R||Legendary Land|||{T}: Add {B} to your mana pool${T}, Sacrifice a creature: You gain life equal to the sacrificed creature’s toughness.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| Deadeye Tracker|Ixalan|99|R|{B}|Creature - Human Pirate|1|1|{1}{B}, {T}: Exile two target cards from an opponent's graveyard. Deadeye Tracker explores.| Deathless Ancient|Ixalan|100|U|{4}{B}{B}|Creature - Vampire Knight|4|4|Flying$Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand.| +Duress|Ixalan|105|C|{B}|Sorcery|||Target opponent reveals his or her hand. You choose a noncreature, nonland card from it. That player discards that card.| Fathom Fleet Captain|Ixalan|106|R|{1}{B}|Creature - Human Pirate|2|1|Menace$Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace.| +Kitesail Freebooter|Ixalan|110|U|{1}{B}|Creature - Human Pirate|1|2|Flying$When Kitesail Freebooter enters the battlefield, target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield.| Queen's Bay Soldier|Ixalan|115|C|{1}{B}|Creature - Vampire Soldier|2|2|| Revel in Riches|Ixalan|117|R|{4}{B}|Enchantment|||Whenever a creature an opponent controls dies, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$At the beginning of your upkeep, if you control ten or more Treasures, you win the game.| Ruin Raider|Ixalan|118|R|{2}{B}|Creature - Orc Pirate|3|2|Raid — At the beginning of your end step, if you attacked with a creature this turn, reveal the top card of your library and put that card into your hand. You lose life equal to the card's converted mana cost.| +Sanctum Seeker|Ixalan|120|R|{2}{B}{B}|Creature - Vampire Knight|3|4|Whenever a Vampire you control attacks, each opponent loses 1 life and you gain 1 life.| Vraska's Contempt|Ixalan|129|R|{2}{B}{B}|Instant|||Exile target creature or planeswalker. You gain 2 life.| Walk the Plank|Ixalan|130|U|{B}{B}|Sorcery|||Destroy target non-Merfolk creature.| +Wanted Scoundrels|Ixalan|131|U|{1}{B}|Creature - Human Pirate|4|3|When Wanted Scoundrels dies, target opponent creates two colorless Treasure artifact tokens with "T, Sacrifice this artifact: Add one mana of any color to your mana pool."| Angrath's Marauders|Ixalan|132|R|{5}{R}{R}|Creature - Human Pirate|4|4|If a source you control would deal damage to a permanent or player, it deals double that damage to that permanent or player instead.| Burning Sun's Avatar|Ixalan|135|R|{3}{R}{R}{R}|Creature - Dinosaur Avatar|6|6|When Burning Sun's Avatar enters the battlefield, it deals 3 damage to target opponent and 3 damage to up to one target creature.| Captain Lannery Storm|Ixalan|136|R|{2}{R}|Legendary Creature - Human Pirate|2|2|Haste$Whenever Captain lannery Storm attacks, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$Whenever you sacrifice a Treasure, Captain Lannery Storm gets +1/+0 until end of turn.| +Lightning Strike|Ixalan|149|U|{1}{R}|Instant|||Lightning Strike deals 3 damage to target creature or player.| +Raptor Hatchling|Ixalan|149|U|{1}{R}|Creature - Dinosaur|1|1|Enrage - Whenever Raptor Hatchling is dealt damage, create a 3/3 green Dinosaur creature token with trample.| Rowdy Crew|Ixalan|159|M|{2}{R}{R}|Creature - Human Pirate|3|3|Trample$When Rowdy Crew enters the battlefield, draw three cards, then discard two cards at random. If two cards that share a card type are discarded this way, put two +1/+1 counters on Rowdy Crew.| Star of Extinction|Ixalan|161|M|{5}{R}{R}|Sorcery|||Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker.| +Storm Fleet Arsonist|Ixalan|162|U|{4}{R}|Creature - Orc Pirate|4|4|Raid - When Storm Fleet Arsonist enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent.| Sun-Crowned Hunters|Ixalan|164|C|{4}{R}{R}|Creature - Dinosaur|5|4|Enrage — Whenever Sun-Crowned Hunters is dealt damage, it deals 3 damage to target opponent.| Sunbird's Invocation|Ixalan|165|R|{5}{R}|Enchantment|||Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order.| +Drover of the Mighty|Ixalan|167|U|{1}{G}|Creature - Human Druid|1|1|Drover of the Mighty gets +2/+2 as long as you control a Dinosaur.${T}: Add one mana of any color to your mana pool.| Tilonalli's Skinshifter|Ixalan|170|R|{2}{R}|Creature - Human Shaman|0|1|Whenever Tilonalli's Skinshifter attacks, it becomes a copy of another target nonlegendary attacking creature until end of turn.| Unfriendly Fire|Ixalan|172|C|{4}{R}|Instant|||Unfriendly Fire deals 4 damage to target creature or player.| +Wily Goblin|Ixalan|174|U|{R}{R}|Creature - Goblin Pirate|1|1|When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can't be countered.$Trample, hexproof| Deathgorge Scavenger|Ixalan|???|R|???|Creature - Dinosaur|3|2|Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you may gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn.| Deeproot Champion|Ixalan|185|R|{1}{G}|Creature - Merfolk Shaman|1|1|Whenever you cast a noncreature spell, put a +1/+1 counter on Deeproot Champion.| Emperor's Vanguard|Ixalan|189|R|{3}{G}|Creature - Human Scout|4|3|Whenever Emperor's Vanguard deals combat damage to a player, it explores.| -Kumena's Omenspeaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Omenspeaker gets +1/+1 as long as you control another Merfolk or Island.| +Kumena's Speaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Speaker gets +1/+1 as long as you control another Merfolk or an Island.| Old-Growth Dryads|Ixalan|199|R|{G}|Creature - Dryad|3|3|When Old-Growth Dryads enters the battlefield, each opponent may search his or her library for a basic land card, put it onto the battlefield tapped, then shuffle his or her library.| +Ranging Raptors|Ixalan|201|U|{2}{G}|Creature - Dinosaur|2|3|Enrage - Whenever Ranging Raptors is dealt damage, you may search your library for a basic land card, put it onto the battlefield, then shuffle your library.| +Ravenous Daggertooth|Ixalan|202|C|{2}{G}|Creature - Dinosaur|3|2|Enrage - Whenever Ravenous Daggertooth is dealt damage, you gain 2 life.| Ripjaw Raptor|Ixalan|203|R|{2}{G}{G}|Creature - Dinosaur|4|5|Enrage — Whenever Ripjaw Raptor is dealt damage, draw a card.| +Savage Stomp|Ixalan|205|U|{2}{G}|Sorcery|||Savage Stomp cost {2} less to cast if it targets a Dinosaur you control.$Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.| Shapers' Sanctuary|Ixalan|206|R|{G}|Enchantment|||Whenever a creature you control becomes the target of a spell or ability an opponent controls, you may draw a card.| +Slice in Twain|Ixalan|207|U|{2}{G}{G}|Instant|||Destroy target artifact or enchantment.$Draw a card.| Tishana's Wayfinder|Ixalan|211|C|{2}{G}|Creature - Merfolk Scout|2|2|When Tishana's Wayfinder enters the battlefield, it explores.| Verdant Sun's Avatar|Ixalan|213|R|{5}{G}{G}|Creature - Dinosaur Avatar|5|5|When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness.| Waker of the Wilds|Ixalan|215|R|{2}{G}{G}|Creature - Merfolk Shaman|3|3|{X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste. It's still a land.| +Wildgrowth Walker|Ixalan|216|U|{1}{G}|Creature - Elemental|1|3|Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life.| Admiral Beckett Brass|Ixalan|217|M|{1}{U}{B}{R}|Legendary Creature - Human Pirate|3|3|Other Pirates you control get +1/+1.$At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt damage by three or more Pirates this turn.| -Militant Dinosaur|Ixalan|218|U|{5}{G}{W}|Creature - Dinosaur|4|6|Each creature you control assigns combats damage equal to its toughness rather than its power.| -Invite the Party|Ixalan|219|U|{2}{W}{B}|Sorcery|||Create three 1/1 white Vampire creature tokens with lifelink.| +Belligerent Brontodon|Ixalan|218|U|{5}{G}{W}|Creature - Dinosaur|4|6|Each creature you control assigns combats damage equal to its toughness rather than its power.| +Call to the Feast|Ixalan|219|U|{2}{W}{B}|Sorcery|||Create three 1/1 white Vampire creature tokens with lifelink.| Deadeye Plunderers|Ixalan|220|U|{3}{U}{B}|Creature - Human Pirate|3|3|Deadeye Plunderers gets +1/+1 for each artifact you control.${2}{U}{B}: Create a colorless artifact token named Treasure with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Dire Fleet Captain|Ixalan|221|U|{B}{R}|Creature - Orc Pirate|2|2|Whenever Dire Fleet Captain attacks, it gets +1/+1 until end of turn for each other attacking Pirate.| Gishath, Sun's Avatar|Ixalan|222|M|{5}{R}{G}{W}|Legendary Creature - Dinosaur Avatar|7|6|Trample, vigilance, haste$Whenever Gishath, Sun's Avatar deals combat damage to a player, reveal that many cards from the top of your library. Put any number of Dinosaur creature cards from among them onto the battlefield and the rest on the bottom of your library in a random order.| Hostage Taker|Ixalan|223|R|{2}{U}{B}|Creature - Human Pirate|2|3|When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell.| +Huatli, Warrior Poet|Ixalan|224|M|{3}{R}{W}|Legendary Planeswalker - Huatli|||+2: You gain life equal to the greatest power among creatures you control.$0: Create a 3/3 green Dinosaur creature token with trample.$-X: Huatli, Warrior Poet deals X damage divided as you choose among any number of target creatures. Creatures dealt damage this way can't block this turn.| Marauding Looter|Ixalan|225|U|{2}{U}{R}|Creature - Human Pirate|4|3|Raid - At the beginning of your end step, if you attacked with a creature this turn, you may draw a card. If you do, discard a card.| -Infuriated Gladiodon|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Infuriated Gladiodon enters the battlefield, it deals 1 damage to each other creature.| +Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature.| +Regisaur Alpha|Ixalan|227|R|{3}{R}{G}|Creature - Dinosaur|4|4|Other Dinosaurs you control have haste.$When Regisaur Alpha enters the battlefield, create a 3/3 green Dinosaur creature token with trample.| +Shapers of Nature|Ixalan|228|U|{1}{G}{U}|Creature - Merfolk Shaman|3|3|{3}{G}: Put a +1/+1 counter on target creature.${2}{U}, Remove a +1/+1 counter from a creature you control: Draw a card.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| -Twilight Legion Battleship|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| -Pillar of Genesis|Ixalan|241|U|{2}|Artifact|||As Pillar of Genesis enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| +Conqueror's Galleon|Ixalan|234|R|{4}|Artifact - Vehicle|2|10|When Conqueror's Galleon attacks, exile it at the end of combat, then return it to the battlefield transformed under your control.$Crew 4| +Conqueror's Foothold|Ixalan|234|R||Land|||{T}: Add {C} to your mana pool.${2}, {T}: Draw a card, then discard a card.${4}, {T}: Draw a card.${6}, {T}: Return target card from your graveyard to your hand.| +Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| +Pillar of Origins|Ixalan|241|U|{2}|Artifact|||As Pillar of Origins enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| +Pirate's Cutlass|Ixalan|242|C|{3}|Artifact - Equipment|||When Pirate's Cutlass enters the battlefield, attach it to target Pirate you control.$Equipped creature gets +2/+1.$Equip 2| +Primal Amulet|Ixalan|243|R|{4}|Artifact|||Instant and sorcery spells you cast cost {1} less to cast.$Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it.| +Primal Wellspring|Ixalan|243|R||Land|||Add one mana of any color to your mana pool. When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy.| +Sentinel Totem|Ixalan|245|U|{1}|Artifact|||When Sentinel Totem enters the battlefield, scry 1.${T}, Exile Sentinel Totem: Exile all cards from all graveyards.| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| -Sorcerous Spyglass|Ixalan|248|R|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| +Sorcerous Spyglass|Ixalan|248|R|{2}|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| +Thaumatic Compass|Ixalan|249|R|{2}|Artifact|||{3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.$At the beginning of your end step, if you control seven or more lands, transform Thaumatic Compass.| +Spires of Orazca|Ixalan|249|R||Land|||{T}: Add {C} to your mana pool.${T}: Untap target attacking creature an opponent controls and remove it from combat.| Treasure Cove|Ixalan|250|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice a Treasure: Draw a card.| Treasure Map|Ixalan|250|R|{2}|Artifact|||{1}, {T}: Scry 1. Put a landmark counter on Treasure Map. Then if there are three or more landmark counters on it, remove those counters, transform Treasure Map, and create three colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Vanquisher's Banner|Ixalan|251|R|{5}|Artifact|||As Vanquisher's Banner enters the battlefield, choose a creature type.$Creatures you control of the chosen type get +1/+1.$Whenever you cast a creature spell of the chosen type, draw a card.| @@ -32403,7 +32441,15 @@ Rootbound Crag|Ixalan|256|R||Land|||Rootbound Crag enters the battlefield tapped Sunpetal Grove|Ixalan|257|R||Land|||Sunpetal Grove enters the battlefield tapped unless you control a Forest or a Plains.${T}: Add {G} or {W} to your mana pool.| Unclaimed Territory|Ixalan|258|U||Land|||As Unclaimed Territory enters the battlefield, choose a creature type.${T}: Add {C} to your mana pool.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell of the chosen type.| Jace, Ingenious Mind-Mage|Ixalan|280|M|{4}{U}{U}|Legendary Planeswalker - Jace|||[+1]: Draw a card.$[+1]: Untap all creatures you control.$[-9]: Gain control of up to three target creatures.| +Castaway's Despair|Ixalan|281|C|{3}{U}|Enchantment - Aura|||Enchant creature$When Castaway's Despair enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during its controller's untap step.| +Grasping Current|Ixalan|282|R|{4}{U}|Sorcery|||Return up to two target creature's to their owner's hand.$Search your library and/or graveyard for a card named Jace, Ingenious Mind-Mage, reveal it, then put it into your hand. If you searched your library this way, shuffle it.| +Jace's Sentinel|Ixalan|283|U|{1}{U}|Creature - Merfolk Warrior|1|3|As long as you control a Jace planeswalker, Jace's Sentinel gets +1/+0 and can't be blocked.| +Woodland Stream|Ixalan|284|C||Land|||Woodland Stream enters the battlefield tapped.${T}: Add {G} or {U} to your mana pool.| Huatli, Dinosaur Knight|Ixalan|285|M|{4}{R}{W}|Legendary Planeswalker - Huatli|||[+2]: Put two +1/+1 counters on up to one target Dinosaur you control.$[-3]: Target Dinosaur you control deals damage equal to its power to target creature you don't control.$[-7]: Dinosaurs you control get +4/+4 until end of turn.| +Huatli's Snubhorn|Ixalan|286|C|{1}{W}|Creature - Dinosaur|2|2|Vigilance| +Huatli's Spurring|Ixalan|287|U|{R}|Instant|||Target creature gets +2/+0 until end of turn. If you control a Huatli planeswalker, that creature gets +4/+0 until end of turn instead.| +Sun-Blessed Mount|Ixalan|288|R|{3}{R}{W}|Creature - Dinosaur|4|4|When Sun-Blessed Mount enters the battlefield, you may search your library and/or graveyard for a card named Huatli, Dinosaur Knight, reveal it, then put it into your hand. If you searched your library this way, shuffle it.| +Stone Quarry|Ixalan|289|C||Land|||Stone Quarry enters the battlefield tapped.${T}: Add {R} or {W} to your mana pool.| Sword of Dungeons and Dragons|Unstable|1|M|{3}|Artifact - Equipment|||Equipped creature gets +2/+2 and has protection from Rogues and from Clerics.$Whenever equipped creature deals combat damage to a player, create a 4/4 gold Dragon creature token with flying and roll a d20. If you roll a 20, repeat this process.$Equip {2}| Jhoira of the Ghitu|Duel Decks: Mind vs. Might|1|M|{1}{U}{R}|Legendary Creature - Human Wizard|2|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.| Beacon of Tomorrows|Duel Decks: Mind vs. Might|2|R|{6}{U}{U}|Sorcery|||Target player takes an extra turn after this one. Shuffle Beacon of Tomorrows into its owner's library.| diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index b1ce026994..f5b538022d 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -204,3 +204,4 @@ Weatherlight|WTH| Worldwake|WWK| Ixalan|XLN| Zendikar|ZEN| +Star Wars|SWS|