diff --git a/Mage.Sets/src/mage/cards/f/FyndhornDruid.java b/Mage.Sets/src/mage/cards/f/FyndhornDruid.java new file mode 100644 index 0000000000..78c6ef165e --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FyndhornDruid.java @@ -0,0 +1,56 @@ + +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.watchers.common.WasBlockedThisTurnWatcher; + +/** + * + * @author L_J + */ +public final class FyndhornDruid extends CardImpl { + + public FyndhornDruid(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Fyndhorn Druid dies, if it was blocked this turn, you gain 4 life. + this.addAbility(new ConditionalInterveningIfTriggeredAbility(new DiesTriggeredAbility(new GainLifeEffect(4)), new SourceWasBlockedThisTurnCondition(), + "When {this} dies, if it was blocked this turn, you gain 4 life."), new WasBlockedThisTurnWatcher()); + } + + public FyndhornDruid(final FyndhornDruid card) { + super(card); + } + + @Override + public FyndhornDruid copy() { + return new FyndhornDruid(this); + } +} + +class SourceWasBlockedThisTurnCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + WasBlockedThisTurnWatcher watcher = (WasBlockedThisTurnWatcher) game.getState().getWatchers().get(WasBlockedThisTurnWatcher.class.getSimpleName()); + return sourcePermanent != null && watcher.getWasBlockedThisTurnCreatures().contains(new MageObjectReference(sourcePermanent, game)); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GargantuanGorilla.java b/Mage.Sets/src/mage/cards/g/GargantuanGorilla.java new file mode 100644 index 0000000000..d7a31647a1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GargantuanGorilla.java @@ -0,0 +1,154 @@ + +package mage.cards.g; + +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.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public final class GargantuanGorilla extends CardImpl { + + public GargantuanGorilla(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}{G}"); + this.subtype.add(SubType.APE); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // At the beginning of your upkeep, you may sacrifice a Forest. If you sacrifice a snow Forest this way, Gargantuan Gorilla gains trample until end of turn. If you don’t sacrifice a Forest, sacrifice Gargantuan Gorilla and it deals 7 damage to you. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new GargantuanGorillaSacrificeEffect(), TargetController.YOU, false)); + + // {T}: Gargantuan Gorilla deals damage equal to its power to another target creature. That creature deals damage equal to its power to Gargantuan Gorilla. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GargantuanGorillaFightEffect(), new TapSourceCost()); + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new AnotherPredicate()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public GargantuanGorilla(final GargantuanGorilla card) { + super(card); + } + + @Override + public GargantuanGorilla copy() { + return new GargantuanGorilla(this); + } +} + +class GargantuanGorillaSacrificeEffect extends OneShotEffect { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Forest"); + private static final FilterPermanent filterSnow = new FilterPermanent("snow permanent"); + static { + filter.add(new SubtypePredicate(SubType.FOREST)); + filterSnow.add(new SupertypePredicate(SuperType.SNOW)); + } + + public GargantuanGorillaSacrificeEffect() { + super(Outcome.Sacrifice); + staticText = "you may sacrifice a Forest. If you sacrifice a snow Forest this way, {this} gains trample until end of turn. If you don’t sacrifice a Forest, sacrifice {this} and it deals 7 damage to you."; + } + + public GargantuanGorillaSacrificeEffect(final GargantuanGorillaSacrificeEffect effect) { + super(effect); + } + + @Override + public GargantuanGorillaSacrificeEffect copy() { + return new GargantuanGorillaSacrificeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && sourcePermanent != null) { + TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + SacrificeTargetCost cost = new SacrificeTargetCost(target); + if (!controller.chooseUse(Outcome.Benefit, "Do you wish to sacrifice a Forest?", source, game) + || !cost.canPay(source, source.getSourceId(), source.getControllerId(), game) + || !cost.pay(source, game, source.getSourceId(), source.getControllerId(), true)) { + sourcePermanent.sacrifice(source.getSourceId(), game); + controller.damage(7, sourcePermanent.getId(), game, false, true); + } else if (cost.isPaid()) { + for (Permanent permanent : cost.getPermanents()) { + if (filterSnow.match(permanent, game)) { + game.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), source); + break; + } + } + } + return true; + } + return false; + } +} + +class GargantuanGorillaFightEffect extends OneShotEffect { + + public GargantuanGorillaFightEffect() { + super(Outcome.Damage); + this.staticText = "{this} deals damage equal to its power to another target creature. That creature deals damage equal to its power to {this}"; + } + + public GargantuanGorillaFightEffect(final GargantuanGorillaFightEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null) { + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + Permanent creature1 = game.getPermanent(getTargetPointer().getFirst(game, source)); + // 20110930 - 701.10 + if (creature1 != null && sourcePermanent != null) { + if (creature1.isCreature() && sourcePermanent.isCreature()) { + sourcePermanent.damage(creature1.getPower().getValue(), creature1.getId(), game, false, true); + creature1.damage(sourcePermanent.getPower().getValue(), sourcePermanent.getId(), game, false, true); + return true; + } + } + if (!game.isSimulation()) { + game.informPlayers(sourceObject.getLogName() + ": Fighting effect has been fizzled."); + } + } + return false; + } + + @Override + public GargantuanGorillaFightEffect copy() { + return new GargantuanGorillaFightEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GusthasScepter.java b/Mage.Sets/src/mage/cards/g/GusthasScepter.java new file mode 100644 index 0000000000..44446a65d0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GusthasScepter.java @@ -0,0 +1,286 @@ + +package mage.cards.g; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.AsThoughEffectType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.ExileZone; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInExile; +import mage.target.common.TargetCardInHand; +import mage.util.CardUtil; + +/** + * + * @author LevelX2, jeffwadsworth & L_J + */ +public final class GusthasScepter extends CardImpl { + + public GusthasScepter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{0}"); + + // {T}: Exile a card from your hand face down. You may look at it for as long as it remains exiled. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GusthasScepterExileEffect(), new TapSourceCost())); + + // {T}: Return a card you own exiled with Gustha’s Scepter to your hand. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new TapSourceCost()); + ability.addTarget(new TargetCardInGusthasScepterExile(this.getId())); + this.addAbility(ability); + + // When you lose control of Gustha’s Scepter, put all cards exiled with Gustha’s Scepter into their owner’s graveyard. + this.addAbility(new GusthasScepterLoseControlAbility()); + + } + + public GusthasScepter(final GusthasScepter card) { + super(card); + } + + @Override + public GusthasScepter copy() { + return new GusthasScepter(this); + } +} + +class GusthasScepterExileEffect extends OneShotEffect { + + public GusthasScepterExileEffect() { + super(Outcome.DrawCard); + staticText = "Exile a card from your hand face down. You may look at it for as long as it remains exiled"; + } + + public GusthasScepterExileEffect(final GusthasScepterExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Target target = new TargetCardInHand(new FilterCard("card to exile")); + if (controller.chooseTarget(outcome, target, source, game)) { + Card card = game.getCard(target.getFirstTarget()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (card != null && sourceObject != null) { + if (card.moveToExile(CardUtil.getCardExileZoneId(game, source), new StringBuilder(sourceObject.getIdName()).toString(), source.getSourceId(), game)) { + card.setFaceDown(true, game); + game.addEffect(new GusthasScepterLookAtCardEffect(card.getId()), source); + return true; + } + } + } + } + return false; + } + + @Override + public GusthasScepterExileEffect copy() { + return new GusthasScepterExileEffect(this); + } +} + +class TargetCardInGusthasScepterExile extends TargetCardInExile { + + public TargetCardInGusthasScepterExile(UUID cardId) { + super(1, 1, new FilterCard("card exiled with Gustha's Scepter"), null); + } + + public TargetCardInGusthasScepterExile(final TargetCardInGusthasScepterExile target) { + super(target); + } + + @Override + public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { + Set<UUID> possibleTargets = new HashSet<>(); + Card sourceCard = game.getCard(sourceId); + if (sourceCard != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, sourceId); + ExileZone exile = game.getExile().getExileZone(exileId); + if (exile != null && !exile.isEmpty()) { + possibleTargets.addAll(exile); + } + } + return possibleTargets; + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + Card sourceCard = game.getCard(sourceId); + if (sourceCard != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, sourceId); + ExileZone exile = game.getExile().getExileZone(exileId); + if (exile != null && !exile.isEmpty()) { + return true; + } + } + return false; + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + Card card = game.getCard(id); + if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { + ExileZone exile = null; + Card sourceCard = game.getCard(source.getSourceId()); + if (sourceCard != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + exile = game.getExile().getExileZone(exileId); + } + if (exile != null && exile.contains(id)) { + return filter.match(card, source.getControllerId(), game); + } + } + return false; + } + + @Override + public TargetCardInGusthasScepterExile copy() { + return new TargetCardInGusthasScepterExile(this); + } +} + +class GusthasScepterLookAtCardEffect extends AsThoughEffectImpl { + + private final UUID cardId; + + public GusthasScepterLookAtCardEffect(UUID cardId) { + super(AsThoughEffectType.LOOK_AT_FACE_DOWN, Duration.EndOfGame, Outcome.Benefit); + this.cardId = cardId; + staticText = "You may look at it for as long as it remains exiled"; + } + + public GusthasScepterLookAtCardEffect(final GusthasScepterLookAtCardEffect effect) { + super(effect); + this.cardId = effect.cardId; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public GusthasScepterLookAtCardEffect copy() { + return new GusthasScepterLookAtCardEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (objectId.equals(cardId) && affectedControllerId.equals(source.getControllerId())) { + MageObject sourceObject = source.getSourceObject(game); + UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); + if (exileId != null && sourceObject != null) { + ExileZone exileZone = game.getExile().getExileZone(exileId); + if (exileZone != null && exileZone.contains(cardId)) { + Player controller = game.getPlayer(source.getControllerId()); + Card card = game.getCard(cardId); + if (controller != null && card != null && game.getState().getZone(cardId) == Zone.EXILED) { + return true; + } + } else { + discard(); + } + } + } + return false; + } +} + +class GusthasScepterLoseControlAbility extends DelayedTriggeredAbility { + + public GusthasScepterLoseControlAbility() { + super(new GusthasScepterPutExiledCardsInOwnersGraveyard(), Duration.EndOfGame, false); + } + + public GusthasScepterLoseControlAbility(final GusthasScepterLoseControlAbility ability) { + super(ability); + } + + @Override + public GusthasScepterLoseControlAbility copy() { + return new GusthasScepterLoseControlAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.LOST_CONTROL + || event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.LOST_CONTROL) { + return event.getPlayerId().equals(controllerId) + && event.getTargetId().equals(this.getSourceId()); + } + else if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { + if (event.getTargetId().equals(this.getSourceId())) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD) { + for (Effect effect : getEffects()) { + effect.setValue("permanentLeftBattlefield", ((ZoneChangeEvent) event).getTarget()); + } + return true; + } + } + } + return false; + } + + @Override + public String getRule() { + return "When you lose control of {this}, put all cards exiled with {this} into their owner's graveyard."; + } +} + +class GusthasScepterPutExiledCardsInOwnersGraveyard extends OneShotEffect { + + public GusthasScepterPutExiledCardsInOwnersGraveyard() { + super(Outcome.Neutral); + staticText = " put all cards exiled with {this} into their owner's graveyard"; + } + + public GusthasScepterPutExiledCardsInOwnersGraveyard(final GusthasScepterPutExiledCardsInOwnersGraveyard 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) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Set<Card> cardsInExile = game.getExile().getExileZone(exileId).getCards(game); + controller.moveCardsToGraveyardWithInfo(cardsInExile, source, game, Zone.EXILED); + return true; + } + return false; + } + + @Override + public GusthasScepterPutExiledCardsInOwnersGraveyard copy() { + return new GusthasScepterPutExiledCardsInOwnersGraveyard(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianPortal.java b/Mage.Sets/src/mage/cards/p/PhyrexianPortal.java new file mode 100644 index 0000000000..c31886dd5b --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PhyrexianPortal.java @@ -0,0 +1,116 @@ + +package mage.cards.p; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +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.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author L_J + */ +public final class PhyrexianPortal extends CardImpl { + + public PhyrexianPortal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + + // {3}: If your library has ten or more cards in it, target opponent looks at the top ten cards of your library and separates them into two face-down piles. Exile one of those piles. Search the other pile for a card, put it into your hand, then shuffle the rest of that pile into your library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PhyrexianPortalEffect(), new ManaCostsImpl("{3}")); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public PhyrexianPortal(final PhyrexianPortal card) { + super(card); + } + + @Override + public PhyrexianPortal copy() { + return new PhyrexianPortal(this); + } +} + +class PhyrexianPortalEffect extends OneShotEffect { + + public PhyrexianPortalEffect() { + super(Outcome.Benefit); + this.staticText = "If your library has ten or more cards in it, target opponent looks at the top ten cards of your library and separates them into two face-down piles. Exile one of those piles. Search the other pile for a card, put it into your hand, then shuffle the rest of that pile into your library"; + } + + public PhyrexianPortalEffect(final PhyrexianPortalEffect effect) { + super(effect); + } + + @Override + public PhyrexianPortalEffect copy() { + return new PhyrexianPortalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(source.getFirstTarget()); + if (controller != null && opponent != null) { + if (controller.getLibrary().size() >= 10) { + Cards cards = new CardsImpl(); + cards.addAll(controller.getLibrary().getTopCards(game, 10)); + + TargetCard target = new TargetCard(0, cards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile")); + List<Card> pile1 = new ArrayList<>(); + if (opponent.choose(Outcome.Neutral, cards, target, game)) { + List<UUID> targets = target.getTargets(); + for (UUID targetId : targets) { + Card card = cards.get(targetId, game); + if (card != null) { + pile1.add(card); + cards.remove(card); + } + } + } + List<Card> pile2 = new ArrayList<>(); + pile2.addAll(cards.getCards(game)); + + game.informPlayers(opponent.getLogName() + " separated the top 10 cards of " + controller.getLogName() + "'s library into two face-down piles (" + + pile1.size() + " cards and " + pile2.size() + " cards)"); + // it's not viable to turn cards face down here for choosePile (since they're still library cards), this is a workaround + boolean choice = controller.chooseUse(outcome, "Choose pile to search for a card (the other will be exiled):", + source.getSourceObject(game).getLogName(), "Pile 1 (" + pile1.size() + " cards)", "Pile 2 (" + pile2.size() + " cards)", source, game); + + game.informPlayers(controller.getLogName() + " chooses to search the " + (choice ? "first" : "second") + " pile"); + Cards pileToExile = new CardsImpl(); + pileToExile.addAll(choice ? pile2 : pile1); + controller.moveCardsToExile(pileToExile.getCards(game), source, game, true, null, ""); + Cards chosenPile = new CardsImpl(); + chosenPile.addAll(choice ? pile1 : pile2); + + TargetCard target2 = new TargetCard(Zone.HAND, new FilterCard("card to put into your hand")); + if (controller.choose(outcome, chosenPile, target2, game)) { + Card card = chosenPile.get(target2.getFirstTarget(), game); + if (card != null) { + controller.moveCards(card, Zone.HAND, source, game); + } + } + controller.shuffleLibrary(source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/ScarabOfTheUnseen.java b/Mage.Sets/src/mage/cards/s/ScarabOfTheUnseen.java new file mode 100644 index 0000000000..7215fdc44f --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScarabOfTheUnseen.java @@ -0,0 +1,102 @@ + +package mage.cards.s; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +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.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.other.OwnerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; + +/** + * + * @author L_J + */ +public final class ScarabOfTheUnseen extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("permanent you own"); + static { + filter.add(new OwnerPredicate(TargetController.YOU)); + } + + public ScarabOfTheUnseen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + + // {T}, Sacrifice Scarab of the Unseen: Return all Auras attached to target permanent you own to their owners’ hands. Draw a card at the beginning of the next turn’s upkeep. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScarabOfTheUnseenEffect(), new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetPermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false)); + this.addAbility(ability); + } + + public ScarabOfTheUnseen(final ScarabOfTheUnseen card) { + super(card); + } + + @Override + public ScarabOfTheUnseen copy() { + return new ScarabOfTheUnseen(this); + } +} + +class ScarabOfTheUnseenEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterPermanent(); + static { + filter.add(new SubtypePredicate(SubType.AURA)); + } + + public ScarabOfTheUnseenEffect() { + super(Outcome.ReturnToHand); + this.staticText = "Return all Auras attached to target permanent you own to their owners’ hands"; + } + + public ScarabOfTheUnseenEffect(final ScarabOfTheUnseenEffect effect) { + super(effect); + } + + @Override + public ScarabOfTheUnseenEffect copy() { + return new ScarabOfTheUnseenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + if (controller != null && targetPermanent != null) { + if (!targetPermanent.getAttachments().isEmpty()) { + List<UUID> attachments = new ArrayList<>(); + attachments.addAll(targetPermanent.getAttachments()); + for (UUID attachedId : attachments) { + Permanent attachedPerm = game.getPermanent(attachedId); + if (attachedPerm != null && filter.match(attachedPerm, game)) { + controller.moveCards(attachedPerm, Zone.HAND, source, game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SplinteringWind.java b/Mage.Sets/src/mage/cards/s/SplinteringWind.java new file mode 100644 index 0000000000..e2b6571d51 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SplinteringWind.java @@ -0,0 +1,125 @@ + +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.effects.common.DamageControllerEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SplinterToken; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public final class SplinteringWind extends CardImpl { + + public SplinteringWind(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}"); + + // {2}{G}: Splintering Wind deals 1 damage to target creature. Create a 1/1 green Splinter creature token. It has flying and “Cumulative upkeep {G}.” When it leaves the battlefield, it deals 1 damage to you and each creature you control. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{2}{G}")); + ability.addEffect(new SplinteringWindCreateTokenEffect()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public SplinteringWind(final SplinteringWind card) { + super(card); + } + + @Override + public SplinteringWind copy() { + return new SplinteringWind(this); + } +} + +class SplinteringWindCreateTokenEffect extends OneShotEffect { + + public SplinteringWindCreateTokenEffect() { + super(Outcome.PutCreatureInPlay); + staticText = "create a 1/1 green Splinter creature token. It has flying and “Cumulative upkeep {G}.” When it leaves the battlefield, it deals 1 damage to you and each creature you control"; + } + + public SplinteringWindCreateTokenEffect(final SplinteringWindCreateTokenEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player sourceController = game.getPlayer(source.getControllerId()); + Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourceController != null && sourceObject != null) { + CreateTokenEffect effect = new CreateTokenEffect(new SplinterToken()); + effect.apply(game, source); + game.getState().setValue(source.getSourceId() + "_token", effect.getLastAddedTokenIds()); + for (UUID addedTokenId : effect.getLastAddedTokenIds()) { + game.addDelayedTriggeredAbility(new SplinteringWindDelayedTriggeredAbility(addedTokenId), source); + } + return true; + } + return false; + } + + @Override + public SplinteringWindCreateTokenEffect copy() { + return new SplinteringWindCreateTokenEffect(this); + } +} + +class SplinteringWindDelayedTriggeredAbility extends DelayedTriggeredAbility { + + private UUID tokenId; + + SplinteringWindDelayedTriggeredAbility(UUID tokenId) { + super(new DamageControllerEffect(1), Duration.OneUse); + this.addEffect(new DamageAllEffect(1, new FilterControlledCreaturePermanent())); + this.tokenId = tokenId; + } + + SplinteringWindDelayedTriggeredAbility(final SplinteringWindDelayedTriggeredAbility ability) { + super(ability); + this.tokenId = ability.tokenId; + } + + @Override + public SplinteringWindDelayedTriggeredAbility copy() { + return new SplinteringWindDelayedTriggeredAbility(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(tokenId)) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "When it leaves the battlefield, it deals 1 damage to you and each creature you control."; + } +} diff --git a/Mage.Sets/src/mage/cards/s/StormElemental.java b/Mage.Sets/src/mage/cards/s/StormElemental.java new file mode 100644 index 0000000000..77d417757f --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormElemental.java @@ -0,0 +1,155 @@ + +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterLandCard; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 & L_J + */ +public final class StormElemental extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with flying"); + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public StormElemental(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}"); + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // {U}, Exile the top card of your library: Tap target creature with flying. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new ManaCostsImpl("{U}")); + ability.addCost(new ExileTopCardLibraryCost()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + + // {U}, Exile the top card of your library: If the exiled card is a snow land, Storm Elemental gets +1/+1 until end of turn. + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StormElementalEffect(), new ManaCostsImpl("{U}")); + ability2.addCost(new ExileTopCardLibraryCost()); + this.addAbility(ability2); + } + + public StormElemental(final StormElemental card) { + super(card); + } + + @Override + public StormElemental copy() { + return new StormElemental(this); + } +} + +class StormElementalEffect extends OneShotEffect { + + private static final FilterLandCard filter = new FilterLandCard("snow land"); + static { + filter.add(new SupertypePredicate(SuperType.SNOW)); + } + + public StormElementalEffect() { + super(Outcome.BoostCreature); + this.staticText = "If the exiled card is a snow land, {this} gets +1/+1 until end of turn"; + } + + public StormElementalEffect(final StormElementalEffect effect) { + super(effect); + } + + @Override + public StormElementalEffect copy() { + return new StormElementalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Card card = null; + for (Cost cost : source.getCosts()) { + if (cost instanceof ExileTopCardLibraryCost) { + card = ((ExileTopCardLibraryCost) cost).getCard(); + } + } + if (card != null) { + if (filter.match(card, game)) { + game.addEffect(new BoostSourceEffect(1, 1, Duration.EndOfTurn), source); + } + } + return true; + } + return false; + } +} + +class ExileTopCardLibraryCost extends CostImpl { + + Card card; + + public ExileTopCardLibraryCost() { + this.text = "Exile the top card of your library"; + } + + public ExileTopCardLibraryCost(final ExileTopCardLibraryCost cost) { + super(cost); + this.card = cost.getCard(); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { + Player controller = game.getPlayer(controllerId); + if (controller != null) { + card = controller.getLibrary().getFromTop(game); + if (card != null) { + paid = controller.moveCards(card, Zone.EXILED, ability, game); + } + } + return paid; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + Player controller = game.getPlayer(controllerId); + if (controller != null) { + return controller.getLibrary().hasCards(); + } + return false; + } + + @Override + public ExileTopCardLibraryCost copy() { + return new ExileTopCardLibraryCost(this); + } + + public Card getCard() { + return card; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SwornDefender.java b/Mage.Sets/src/mage/cards/s/SwornDefender.java new file mode 100644 index 0000000000..b46b26f1bf --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SwornDefender.java @@ -0,0 +1,90 @@ + +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.BlockedByIdPredicate; +import mage.filter.predicate.permanent.BlockingAttackerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 & L_J + */ +public final class SwornDefender extends CardImpl { + + public SwornDefender(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature blocking or blocked by SwornDefender"); + filter.add(Predicates.or(new BlockedByIdPredicate(this.getId()), + new BlockingAttackerIdPredicate(this.getId()))); + // {1}: Sworn Defender’s power becomes the toughness of target creature blocking or being blocked by Sworn Defender minus 1 until end of turn, and Sworn Defender’s toughness becomes 1 plus the power of that creature until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SwornDefenderEffect(), new GenericManaCost(1)); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + + } + + public SwornDefender(final SwornDefender card) { + super(card); + } + + @Override + public SwornDefender copy() { + return new SwornDefender(this); + } +} + +class SwornDefenderEffect extends OneShotEffect { + + public SwornDefenderEffect() { + super(Outcome.Detriment); + this.staticText = "{this}'s power becomes the toughness of target creature blocking or being blocked by {this} minus 1 until end of turn, and {this}’s toughness becomes 1 plus the power of that creature until end of turn"; + } + + public SwornDefenderEffect(final SwornDefenderEffect effect) { + super(effect); + } + + @Override + public SwornDefenderEffect copy() { + return new SwornDefenderEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent targetPermanent = game.getPermanentOrLKIBattlefield(targetPointer.getFirst(game, source)); + if (controller != null && targetPermanent != null) { + int newPower = CardUtil.subtractWithOverflowCheck(targetPermanent.getToughness().getValue(), 1); + int newToughness = CardUtil.addWithOverflowCheck(targetPermanent.getPower().getValue(), 1); + game.addEffect(new SetPowerToughnessSourceEffect(newPower, newToughness, Duration.EndOfTurn, SubLayer.SetPT_7b), source); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 7df01628f9..1b4af9a608 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -74,6 +74,9 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Force of Will", 28, Rarity.UNCOMMON, mage.cards.f.ForceOfWill.class)); cards.add(new SetCardInfo("Foresight", "29a", Rarity.COMMON, mage.cards.f.Foresight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Foresight", "29b", Rarity.COMMON, mage.cards.f.Foresight.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fyndhorn Druid", "90a", Rarity.COMMON, mage.cards.f.FyndhornDruid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fyndhorn Druid", "90b", Rarity.COMMON, mage.cards.f.FyndhornDruid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Gargantuan Gorilla", 91, Rarity.RARE, mage.cards.g.GargantuanGorilla.class)); cards.add(new SetCardInfo("Gorilla Berserkers", "93a", Rarity.COMMON, mage.cards.g.GorillaBerserkers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gorilla Berserkers", "93b", Rarity.COMMON, mage.cards.g.GorillaBerserkers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gorilla Chieftain", "94a", Rarity.COMMON, mage.cards.g.GorillaChieftain.class, NON_FULL_USE_VARIOUS)); @@ -84,6 +87,7 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Gorilla War Cry", "73b", Rarity.COMMON, mage.cards.g.GorillaWarCry.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Guerrilla Tactics", "74a", Rarity.COMMON, mage.cards.g.GuerrillaTactics.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Guerrilla Tactics", "74b", Rarity.COMMON, mage.cards.g.GuerrillaTactics.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Gustha's Scepter", 120, Rarity.RARE, mage.cards.g.GusthasScepter.class)); cards.add(new SetCardInfo("Hail Storm", 95, Rarity.UNCOMMON, mage.cards.h.HailStorm.class)); cards.add(new SetCardInfo("Heart of Yavimaya", 138, Rarity.RARE, mage.cards.h.HeartOfYavimaya.class)); cards.add(new SetCardInfo("Helm of Obedience", 121, Rarity.RARE, mage.cards.h.HelmOfObedience.class)); @@ -127,6 +131,7 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Phyrexian Boon", "58a", Rarity.COMMON, mage.cards.p.PhyrexianBoon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian Boon", "58b", Rarity.COMMON, mage.cards.p.PhyrexianBoon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian Devourer", 125, Rarity.RARE, mage.cards.p.PhyrexianDevourer.class)); + cards.add(new SetCardInfo("Phyrexian Portal", 126, Rarity.RARE, mage.cards.p.PhyrexianPortal.class)); cards.add(new SetCardInfo("Phyrexian War Beast", "127a", Rarity.COMMON, mage.cards.p.PhyrexianWarBeast.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian War Beast", "127b", Rarity.COMMON, mage.cards.p.PhyrexianWarBeast.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Pillage", 76, Rarity.UNCOMMON, mage.cards.p.Pillage.class)); @@ -139,6 +144,7 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Royal Decree", 14, Rarity.RARE, mage.cards.r.RoyalDecree.class)); cards.add(new SetCardInfo("Royal Herbalist", "15a", Rarity.COMMON, mage.cards.r.RoyalHerbalist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Royal Herbalist", "15b", Rarity.COMMON, mage.cards.r.RoyalHerbalist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Scarab of the Unseen", 128, Rarity.UNCOMMON, mage.cards.s.ScarabOfTheUnseen.class)); cards.add(new SetCardInfo("School of the Unseen", 141, Rarity.UNCOMMON, mage.cards.s.SchoolOfTheUnseen.class)); cards.add(new SetCardInfo("Seasoned Tactician", 17, Rarity.UNCOMMON, mage.cards.s.SeasonedTactician.class)); cards.add(new SetCardInfo("Sheltered Valley", 142, Rarity.RARE, mage.cards.s.ShelteredValley.class)); @@ -156,11 +162,13 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Soldevi Steam Beast", "133b", Rarity.COMMON, mage.cards.s.SoldeviSteamBeast.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Soldier of Fortune", 80, Rarity.UNCOMMON, mage.cards.s.SoldierOfFortune.class)); cards.add(new SetCardInfo("Spiny Starfish", 35, Rarity.UNCOMMON, mage.cards.s.SpinyStarfish.class)); + cards.add(new SetCardInfo("Splintering Wind", 99, Rarity.RARE, mage.cards.s.SplinteringWind.class)); cards.add(new SetCardInfo("Stench of Decay", "61a", Rarity.COMMON, mage.cards.s.StenchOfDecay.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Stench of Decay", "61b", Rarity.COMMON, mage.cards.s.StenchOfDecay.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Storm Cauldron", 134, Rarity.RARE, mage.cards.s.StormCauldron.class)); cards.add(new SetCardInfo("Storm Crow", "36a", Rarity.COMMON, mage.cards.s.StormCrow.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Storm Crow", "36b", Rarity.COMMON, mage.cards.s.StormCrow.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Storm Elemental", 37, Rarity.UNCOMMON, mage.cards.s.StormElemental.class)); cards.add(new SetCardInfo("Storm Shaman", "81a", Rarity.COMMON, mage.cards.s.StormShaman.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Storm Shaman", "81b", Rarity.COMMON, mage.cards.s.StormShaman.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Stromgald Spy", 62, Rarity.UNCOMMON, mage.cards.s.StromgaldSpy.class)); @@ -168,6 +176,7 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Sustaining Spirit", 18, Rarity.RARE, mage.cards.s.SustainingSpirit.class)); cards.add(new SetCardInfo("Swamp Mosquito", "63a", Rarity.COMMON, mage.cards.s.SwampMosquito.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp Mosquito", "63b", Rarity.COMMON, mage.cards.s.SwampMosquito.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sworn Defender", 19, Rarity.RARE, mage.cards.s.SwornDefender.class)); cards.add(new SetCardInfo("Thawing Glaciers", 144, Rarity.RARE, mage.cards.t.ThawingGlaciers.class)); cards.add(new SetCardInfo("Thought Lash", 39, Rarity.RARE, mage.cards.t.ThoughtLash.class)); cards.add(new SetCardInfo("Tidal Control", 40, Rarity.RARE, mage.cards.t.TidalControl.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 5f61eef8ec..10f045b8d0 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -313,6 +313,7 @@ public enum SubType { SPIDER("Spider", SubTypeSet.CreatureType), SPIKE("Spike", SubTypeSet.CreatureType), SPIRIT("Spirit", SubTypeSet.CreatureType), + SPLINTER("Splinter", SubTypeSet.CreatureType), SPLITTER("Splitter", SubTypeSet.CreatureType), SPONGE("Sponge", SubTypeSet.CreatureType), SQUID("Squid", SubTypeSet.CreatureType), diff --git a/Mage/src/main/java/mage/game/permanent/token/SplinterToken.java b/Mage/src/main/java/mage/game/permanent/token/SplinterToken.java new file mode 100644 index 0000000000..bc5bfdcbca --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/SplinterToken.java @@ -0,0 +1,35 @@ + +package mage.game.permanent.token; + +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.MageInt; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.abilities.keyword.FlyingAbility; + +/** + * + * @author L_J + */ +public final class SplinterToken extends TokenImpl { + + public SplinterToken() { + super("Splinter", "1/1 green Splinter creature token"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.SPLINTER); + color.setGreen(true); + power = new MageInt(1); + toughness = new MageInt(1); + this.addAbility(FlyingAbility.getInstance()); + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{G}"))); + } + + public SplinterToken(final SplinterToken token) { + super(token); + } + + public SplinterToken copy() { + return new SplinterToken(this); + } +}