mirror of
https://github.com/correl/mage.git
synced 2025-04-01 19:07:57 -09:00
Implemented Alliances cards (#5470)
* Implemented Alliances cards (#84) * Fixed Storm Elemental * Fixed Sworn Defender
This commit is contained in:
parent
ff11727596
commit
d0fbe6d35c
11 changed files with 1129 additions and 0 deletions
Mage.Sets/src/mage
cards
f
g
p
s
sets
Mage/src/main/java/mage
56
Mage.Sets/src/mage/cards/f/FyndhornDruid.java
Normal file
56
Mage.Sets/src/mage/cards/f/FyndhornDruid.java
Normal 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));
|
||||
}
|
||||
}
|
154
Mage.Sets/src/mage/cards/g/GargantuanGorilla.java
Normal file
154
Mage.Sets/src/mage/cards/g/GargantuanGorilla.java
Normal 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 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);
|
||||
}
|
||||
}
|
286
Mage.Sets/src/mage/cards/g/GusthasScepter.java
Normal file
286
Mage.Sets/src/mage/cards/g/GusthasScepter.java
Normal 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 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);
|
||||
}
|
||||
}
|
116
Mage.Sets/src/mage/cards/p/PhyrexianPortal.java
Normal file
116
Mage.Sets/src/mage/cards/p/PhyrexianPortal.java
Normal 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;
|
||||
}
|
||||
}
|
102
Mage.Sets/src/mage/cards/s/ScarabOfTheUnseen.java
Normal file
102
Mage.Sets/src/mage/cards/s/ScarabOfTheUnseen.java
Normal 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 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;
|
||||
}
|
||||
}
|
125
Mage.Sets/src/mage/cards/s/SplinteringWind.java
Normal file
125
Mage.Sets/src/mage/cards/s/SplinteringWind.java
Normal 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.";
|
||||
}
|
||||
}
|
155
Mage.Sets/src/mage/cards/s/StormElemental.java
Normal file
155
Mage.Sets/src/mage/cards/s/StormElemental.java
Normal 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;
|
||||
}
|
||||
}
|
90
Mage.Sets/src/mage/cards/s/SwornDefender.java
Normal file
90
Mage.Sets/src/mage/cards/s/SwornDefender.java
Normal 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 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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue