1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-01 19:07:57 -09:00

Implemented Alliances cards ()

* Implemented Alliances cards ()

* Fixed Storm Elemental

* Fixed Sworn Defender
This commit is contained in:
L_J 2018-12-28 05:53:10 +01:00 committed by Jeff Wadsworth
parent ff11727596
commit d0fbe6d35c
11 changed files with 1129 additions and 0 deletions

View file

@ -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));
}
}

View file

@ -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 dont 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 dont 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);
}
}

View file

@ -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 Gusthas 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 Gusthas Scepter, put all cards exiled with Gusthas Scepter into their owners 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);
}
}

View file

@ -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;
}
}

View file

@ -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 turns 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;
}
}

View file

@ -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.";
}
}

View file

@ -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;
}
}

View file

@ -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 Defenders power becomes the toughness of target creature blocking or being blocked by Sworn Defender minus 1 until end of turn, and Sworn Defenders 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;
}
}

View file

@ -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));

View file

@ -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),

View file

@ -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);
}
}