diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java index eb6c238415..e0f4575817 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java @@ -230,7 +230,7 @@ public enum GrabbagImageSource implements CardImageSource { singleLinks.put("SWS/Mountain-c", "wqXTdsC.jpg"); singleLinks.put("SWS/Mountain-d", "9oBNCHk.jpg"); singleLinks.put("SWS/N-1 Starfighter", "UH3qd7x.jpg"); - singleLinks.put("SWS/Nebulon-B Frigate", "IwEpVkz.jpg"); + singleLinks.put("SWS/Nebulon-B Frigate", "F0yIR08.jpg"); singleLinks.put("SWS/Neophyte Hateflayer", "Has2AIW.jpg"); singleLinks.put("SWS/Nerf Herder", "VUX0LHV.jpg"); singleLinks.put("SWS/Nexu Stalker", "E1xxHe1.jpg"); @@ -415,6 +415,40 @@ public enum GrabbagImageSource implements CardImageSource { singleLinks.put("SWS/Tobias Beckett", "hzm6ilE.jpg"); singleLinks.put("SWS/Underground Forum", "FH2pRfU.jpg"); singleLinks.put("SWS/Chewbacca, the Beast", "Zb5TitZ.jpg"); + singleLinks.put("SWS/A Jedi's Fervor", "5MjPOpE.jpg"); + singleLinks.put("SWS/Allegiant General Pryde", "Ucithhc.jpg"); + singleLinks.put("SWS/Balance", "EMdbTBj.jpg"); + singleLinks.put("SWS/Band Together", "xc9dQaZ.jpg"); + singleLinks.put("SWS/Ben Solo", "4GXbkI3.jpg"); + singleLinks.put("SWS/Betray", "SjyF6Nq.jpg"); + singleLinks.put("SWS/Brave the Elements", "z2etu3V.jpg"); + singleLinks.put("SWS/Culling Dais", "NHRMrmo.jpg"); + singleLinks.put("SWS/Droidsmith", "HYyiEI7.jpg"); + singleLinks.put("SWS/Dyad Force Transfer", "dmyQ7Jm.jpg"); + singleLinks.put("SWS/Festival of the Ancestors", "JUPnIEr.jpg"); + singleLinks.put("SWS/First Order Jet Trooper", "wVqmWMK.jpg"); + singleLinks.put("SWS/Force Lift", "46eGWAq.jpg"); + singleLinks.put("SWS/General Organa", "YSv61yR.jpg"); + singleLinks.put("SWS/Hidden Base", "M6BR6aH.jpg"); + singleLinks.put("SWS/Hold Captive", "3dR542o.jpg"); + singleLinks.put("SWS/Holochess", "lPS1mR6.jpg"); + singleLinks.put("SWS/Knights of Ren", "vdXyRpy.jpg"); + singleLinks.put("SWS/Lightspeed Skipping", "VRquVqA.jpg"); + singleLinks.put("SWS/Luke's Lightsaber", "Ty3j9y3.jpg"); + singleLinks.put("SWS/Mimic Vat", "9bAK1LC.jpg"); + singleLinks.put("SWS/Orbak", "8RvSbhX.jpg"); + singleLinks.put("SWS/Propaganda", "TBNlxqj.jpg"); + singleLinks.put("SWS/Rey Skywalker", "dOyjNXc.jpg"); + singleLinks.put("SWS/Rey's Lightsaber", "eMzKXAP.jpg"); + singleLinks.put("SWS/Sith Eternal Lightning", "oaFkj3N.jpg"); + singleLinks.put("SWS/Sith Wayfinder", "AznLRt0.jpg"); + singleLinks.put("SWS/Swamp-e", "LrbqB3U.jpg"); + singleLinks.put("SWS/Training Droid", "JCY9KOM.jpg"); + singleLinks.put("SWS/Unpleasant Discovery", "lDKoeAu.jpg"); + singleLinks.put("SWS/Vexis", "cNQX9Ue.jpg"); + singleLinks.put("SWS/War Room", "pqQ9kzt.jpg"); + singleLinks.put("SWS/Xyston Star Destroyer", "oqbHtUC.jpg"); + singleLinks.put("SWS/Zorii Bliss", "vOyNE39.jpg"); // Emblems singleLinks.put("SWS/Emblem Obi-Wan Kenobi", "Qyc10aT.png"); @@ -488,7 +522,7 @@ public enum GrabbagImageSource implements CardImageSource { if (!httpImageUrl.startsWith("/MTG")) { try { TimeUnit.SECONDS.sleep(2); - } catch (InterruptedException ex) { + } catch (InterruptedException ignored) { } } } diff --git a/Mage.Sets/src/mage/cards/a/AJedisFervor.java b/Mage.Sets/src/mage/cards/a/AJedisFervor.java new file mode 100644 index 0000000000..05430c7b72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AJedisFervor.java @@ -0,0 +1,100 @@ +package mage.cards.a; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.target.TargetPermanent; +import mage.watchers.common.SpellsCastWatcher; + +import java.util.*; + +/** + * @author: Merlingilb + */ +public final class AJedisFervor extends CardImpl { + public AJedisFervor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Creatures you control gain indestructible until end of turn. + this.getSpellAbility().addEffect(new GainAbilityControlledEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURES) + ); + + // If an opponent cast a black spell this turn, that player sacrifices a creature or planeswalker. + this.getSpellAbility().addEffect(new AJedisFervorEffect()); + this.getSpellAbility().addWatcher(new SpellsCastWatcher()); + } + + private AJedisFervor(final AJedisFervor card) { + super(card); + } + + @Override + public AJedisFervor copy() { + return new AJedisFervor(this); + } +} + +class AJedisFervorEffect extends OneShotEffect { + public AJedisFervorEffect() { + super(Outcome.Sacrifice); + staticText = "If an opponent cast a black spell this turn, that player sacrifices a creature or planeswalker."; + } + + public AJedisFervorEffect(final AJedisFervorEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + Set opponents = game.getOpponents(source.getControllerId()); + Set opponentsBlack = new HashSet<>(); + List perms = new ArrayList<>(); + //get opponents that cast a black spell this turn + if (watcher != null) { + for (UUID opponentId : opponents) { + List spells = watcher.getSpellsCastThisTurn(opponentId); + if (spells != null) { + for (Spell spell : spells) { + if (spell.getColor(game).isBlack()) { + opponentsBlack.add(opponentId); + } + } + } + } + } + //get that opponents to pick a creature or planeswalker + for (UUID opponentId : opponentsBlack) { + TargetPermanent target = new TargetPermanent(1, 1, + StaticFilters.FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER, false); + game.getPlayer(opponentId).chooseTarget(Outcome.Sacrifice, target, source, game); + perms.addAll(target.getTargets()); + } + //sacrifices the picked cards + for (UUID permID : perms) { + Permanent permanent = game.getPermanent(permID); + if (permanent != null) { + permanent.sacrifice(source, game); + } + } + return true; + } + + @Override + public AJedisFervorEffect copy() { + return new AJedisFervorEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/a/AllegiantGeneralPryde.java b/Mage.Sets/src/mage/cards/a/AllegiantGeneralPryde.java new file mode 100644 index 0000000000..e2a21b6efb --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AllegiantGeneralPryde.java @@ -0,0 +1,65 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class AllegiantGeneralPryde extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Trooper creatures"); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + filter.add(SubType.TROOPER.getPredicate()); + } + + public AllegiantGeneralPryde(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.TROOPER); + this.subtype.add(SubType.ADVISOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Trooper creatures you control have "When this creature enters the battlefield, you may sacrifice a creature. If you do, draw two cards and lose 2 life." + SacrificeEffect sacrifceEffect = new SacrificeEffect( + StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED, 1, ""); + EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(sacrifceEffect, true, true); + ability.setTriggerPhrase("When this creature enters the battlefield, "); + ability.addTarget(new TargetControlledCreaturePermanent(1)); + DrawCardSourceControllerEffect drawCardSourceControllerEffect = new DrawCardSourceControllerEffect(2); + drawCardSourceControllerEffect.setText("If you do, draw two cards"); + ability.addEffect(drawCardSourceControllerEffect); + LoseLifeSourceControllerEffect loseLifeSourceControllerEffect = new LoseLifeSourceControllerEffect(2); + loseLifeSourceControllerEffect.setText("and lose 2 life."); + ability.addEffect(loseLifeSourceControllerEffect); + //EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(2), true); + GainAbilityControlledEffect effect = new GainAbilityControlledEffect( + ability, Duration.WhileOnBattlefield, filter); + this.addAbility(new SimpleStaticAbility(effect)); + } + + public AllegiantGeneralPryde(final AllegiantGeneralPryde card) { + super(card); + } + + @Override + public Card copy() { + return new AllegiantGeneralPryde(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BenSolo.java b/Mage.Sets/src/mage/cards/b/BenSolo.java new file mode 100644 index 0000000000..35ffa9a4d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BenSolo.java @@ -0,0 +1,150 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.DamagedEvent; +import mage.game.events.DamagedPermanentBatchEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetPlayerOrPlaneswalker; + +import java.util.Set; +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class BenSolo extends CardImpl { + public BenSolo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R/W}{W}"); + this.addSuperType(SuperType.LEGENDARY); + this.addSubType(SubType.HUMAN); + this.addSubType(SubType.KNIGHT); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + //Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + //Whenever Ben Solo is dealt damage, it deals that much damage to target player or planeswalker. + this.addAbility(new BenSoloTriggeredAbility()); + } + + public BenSolo(final BenSolo card) { + super(card); + } + + @Override + public Card copy() { + return new BenSolo(this); + } +} + +class BenSoloTriggeredAbility extends TriggeredAbilityImpl { + + UUID benSoloID; + + BenSoloTriggeredAbility() { + super(Zone.BATTLEFIELD, new BenSoloEffect(), false); + this.addTarget(new TargetPlayerOrPlaneswalker()); + benSoloID = this.getSourceId(); + } + + private BenSoloTriggeredAbility(final BenSoloTriggeredAbility ability) { + super(ability); + benSoloID = ability.benSoloID; + } + + @Override + public BenSoloTriggeredAbility copy() { + return new BenSoloTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PERMANENT_BATCH; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (benSoloID == null) { + benSoloID = this.getSourceId(); + if (benSoloID == null) { + return false; + } + } + + int damage = 0; + DamagedPermanentBatchEvent dEvent = (DamagedPermanentBatchEvent) event; + Set set = dEvent.getEvents(); + for (DamagedEvent damagedEvent : set) { + UUID targetID = damagedEvent.getTargetId(); + if (targetID == null) { + continue; + } + + if (targetID == benSoloID) { + damage += damagedEvent.getAmount(); + } + } + + if (damage > 0) { + this.getEffects().setValue("damage", damage); + this.getEffects().setValue("benSoloID", benSoloID); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever Ben Solo is dealt damage, it deals that much damage to target player or planeswalker."; + } +} + +class BenSoloEffect extends OneShotEffect { + + BenSoloEffect() { + super(Outcome.Benefit); + } + + private BenSoloEffect(final BenSoloEffect effect) { + super(effect); + } + + @Override + public BenSoloEffect copy() { + return new BenSoloEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Integer damage = (Integer)getValue("damage"); + UUID benSoloID = (UUID)getValue("benSoloID"); + + if (benSoloID == null || damage == null || damage < 1) { + return false; + } + + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null) { + permanent.damage(damage, benSoloID, source, game); + return true; + } + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + player.damage(damage, benSoloID, source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/b/Betray.java b/Mage.Sets/src/mage/cards/b/Betray.java new file mode 100644 index 0000000000..fc566e1141 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Betray.java @@ -0,0 +1,66 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class Betray extends CardImpl { + public Betray(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); + + //Target creature an opponent controls deals damage to its controller equal to that creature's power. + this.getSpellAbility().addEffect(new BetrayEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(1, 1, + StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE, false)); + } + + public Betray(final Betray card) { + super(card); + } + + @Override + public Card copy() { + return new Betray(this); + } +} + +class BetrayEffect extends OneShotEffect { + + BetrayEffect() { + super(Outcome.Benefit); + staticText = "Target creature an opponent controls deals damage to its controller equal to that creature's power."; + } + + private BetrayEffect(final BetrayEffect effect) { + super(effect); + } + + @Override + public BetrayEffect copy() { + return new BetrayEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent == null) { + return false; + } + Player player = game.getPlayer(permanent.getControllerId()); + return player.damage(permanent.getPower().getValue(), permanent.getId(), source, game) > 0; + } +} diff --git a/Mage.Sets/src/mage/cards/d/Droidsmith.java b/Mage.Sets/src/mage/cards/d/Droidsmith.java new file mode 100644 index 0000000000..f5ecb475a3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Droidsmith.java @@ -0,0 +1,59 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.CompoundCondition; +import mage.abilities.condition.common.SourceTappedCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.keyword.CantBeBlockedSourceAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class Droidsmith extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + static { + filter.add(SubType.DROID.getPredicate()); + } + public Droidsmith(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}"); + this.addSubType(SubType.ANGEL); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + //Droidsmith can't be blocked. + this.addAbility(new CantBeBlockedSourceAbility()); + + //Droid creatures you control get +1/+0 as long as Droidsmith is tapped. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, filter), + new CompoundCondition(SourceTappedCondition.TAPPED), + "Droid creatures you control get +1/+0 as long as Droidsmith is tapped." + ))); + //Droid creatures you control get +0/+1 as long as Droidsmith is untapped. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostControlledEffect(0, 1, Duration.WhileOnBattlefield, filter), + new CompoundCondition(SourceTappedCondition.UNTAPPED), + "Droid creatures you control get +0/+1 as long as Droidsmith is untapped." + ))); + } + + public Droidsmith(final Droidsmith card) { + super(card); + } + + @Override + public Droidsmith copy() { + return new Droidsmith(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DyadForceTransfer.java b/Mage.Sets/src/mage/cards/d/DyadForceTransfer.java new file mode 100644 index 0000000000..86f180ae05 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DyadForceTransfer.java @@ -0,0 +1,35 @@ +package mage.cards.d; + +import mage.abilities.effects.common.continuous.GainControlAndUntapTargetEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +import java.util.UUID; + +public class DyadForceTransfer extends CardImpl { + public DyadForceTransfer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + //Gain control of target noncreature permanent until end of turn. Untap it. + this.getSpellAbility().addEffect(new GainControlAndUntapTargetEffect(Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetPermanent(1, 1, + StaticFilters.FILTER_PERMANENT_NON_CREATURE)); + + //Scry 3. + this.getSpellAbility().addEffect(new ScryEffect(3, true)); + } + + public DyadForceTransfer(final DyadForceTransfer card) { + super(card); + } + + @Override + public DyadForceTransfer copy() { + return new DyadForceTransfer(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FestivalOfTheAncestors.java b/Mage.Sets/src/mage/cards/f/FestivalOfTheAncestors.java new file mode 100644 index 0000000000..e6a7d3d5e9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FestivalOfTheAncestors.java @@ -0,0 +1,28 @@ +package mage.cards.f; + +import mage.abilities.effects.common.GainLifeTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +import java.util.UUID; + +public class FestivalOfTheAncestors extends CardImpl { + public FestivalOfTheAncestors(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}"); + + //Target player gains 5 life. + this.getSpellAbility().addEffect(new GainLifeTargetEffect(5)); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public FestivalOfTheAncestors(final FestivalOfTheAncestors card) { + super(card); + } + + @Override + public FestivalOfTheAncestors copy() { + return new FestivalOfTheAncestors(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FirstOrderJetTrooper.java b/Mage.Sets/src/mage/cards/f/FirstOrderJetTrooper.java new file mode 100644 index 0000000000..4e7874d275 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FirstOrderJetTrooper.java @@ -0,0 +1,50 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class FirstOrderJetTrooper extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + static { + filter.add(TargetController.YOU.getControllerPredicate()); + filter.add(SubType.TROOPER.getPredicate()); + } + public FirstOrderJetTrooper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}"); + this.addSubType(SubType.TROOPER); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + //Trooper creatures you control have haste and first strike. + Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect(HasteAbility.getInstance(), + Duration.WhileOnBattlefield, filter).setText("Trooper creatures you control have haste and first strike.")); + ability.addEffect(new GainAbilityControlledEffect(FirstStrikeAbility.getInstance(), + Duration.WhileOnBattlefield, filter).setText("")); + this.addAbility(ability); + } + + public FirstOrderJetTrooper(final FirstOrderJetTrooper card) { + super(card); + } + + @Override + public FirstOrderJetTrooper copy() { + return new FirstOrderJetTrooper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/ForceLift.java b/Mage.Sets/src/mage/cards/f/ForceLift.java new file mode 100644 index 0000000000..a89faaebd3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/ForceLift.java @@ -0,0 +1,119 @@ +package mage.cards.f; + +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class ForceLift extends CardImpl { + public ForceLift(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W/U}"); + + //Exile target creature. Return that creature to the battlefield under its owner's control at the beginning of the next end step. + this.getSpellAbility().addEffect(new ForceLiftEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + //Scry 1. + this.getSpellAbility().addEffect(new ScryEffect(1)); + } + + public ForceLift(final ForceLift card) { + super(card); + } + + @Override + public ForceLift copy() { + return new ForceLift(this); + } +} + +class ForceLiftEffect extends OneShotEffect { + + private static final String effectText = "Exile target creature. Return that creature to the battlefield under its owner's control at the beginning of the next end step."; + + ForceLiftEffect() { + super(Outcome.Benefit); + staticText = effectText; + } + + ForceLiftEffect(ForceLiftEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null) { + if (permanent.moveToExile(source.getSourceId(), "Force Lift", source, game)) { + ExileZone exile = game.getExile().getExileZone(source.getSourceId()); + // only if permanent is in exile (tokens would be stop to exist) + if (exile != null && !exile.isEmpty()) { + Card card = game.getCard(permanent.getId()); + if (card != null) { + //create delayed triggered ability + game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility( + new ForceLiftReturnFromExileEffect(new MageObjectReference(card, game))), source); + } + } + return true; + } + } + return false; + } + + @Override + public ForceLiftEffect copy() { + return new ForceLiftEffect(this); + } + +} + +class ForceLiftReturnFromExileEffect extends OneShotEffect { + + MageObjectReference objectToReturn; + + public ForceLiftReturnFromExileEffect(MageObjectReference objectToReturn) { + super(Outcome.PutCardInPlay); + this.objectToReturn = objectToReturn; + staticText = "return that card to the battlefield under its owner's control"; + } + + public ForceLiftReturnFromExileEffect(final ForceLiftReturnFromExileEffect effect) { + super(effect); + this.objectToReturn = effect.objectToReturn; + } + + @Override + public ForceLiftReturnFromExileEffect copy() { + return new ForceLiftReturnFromExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(objectToReturn.getSourceId()); + if (card != null && objectToReturn.refersTo(card, game)) { + Player owner = game.getPlayer(card.getOwnerId()); + if (owner != null) { + owner.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); + } + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GeneralOrgana.java b/Mage.Sets/src/mage/cards/g/GeneralOrgana.java new file mode 100644 index 0000000000..0e300d73d6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GeneralOrgana.java @@ -0,0 +1,51 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.decorator.ConditionalCostModificationEffect; +import mage.abilities.effects.common.cost.SpellsCostIncreasingAllEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.filter.FilterCard; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class GeneralOrgana extends CardImpl { + public GeneralOrgana(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}"); + this.addSuperType(SuperType.LEGENDARY); + this.addSubType(SubType.HUMAN); + this.addSubType(SubType.REBEL); + this.addSubType(SubType.ADVISOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + //Spells your opponents cast on your turn cost {2} more to cast. + this.addAbility(new SimpleStaticAbility(new ConditionalCostModificationEffect( + new SpellsCostIncreasingAllEffect(2, new FilterCard(), + TargetController.OPPONENT), + MyTurnCondition.instance, "Spells your opponents cast on your turn cost {2} more to cast."))); + + //When General Organa leaves the battlefield, scry 2. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new ScryEffect(2), false)); + } + + public GeneralOrgana(final GeneralOrgana card) { + super(card); + } + + @Override + public GeneralOrgana copy() { + return new GeneralOrgana(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HiddenBase.java b/Mage.Sets/src/mage/cards/h/HiddenBase.java new file mode 100644 index 0000000000..63841ce84c --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HiddenBase.java @@ -0,0 +1,50 @@ +package mage.cards.h; + +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class HiddenBase extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Starship creature"); + + static { + filter.add(SubType.STARSHIP.getPredicate()); + } + + public HiddenBase(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + //{T}: Add {C}. + this.addAbility(new ColorlessManaAbility()); + + //{T}: Target starship creature gains haste until end of turn. + SimpleActivatedAbility simpleActivatedAbility = new SimpleActivatedAbility( + new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new TapSourceCost()); + simpleActivatedAbility.addTarget(new TargetPermanent(filter)); + this.addAbility(simpleActivatedAbility); + } + + public HiddenBase(final HiddenBase card) { + super(card); + } + + @Override + public HiddenBase copy() { + return new HiddenBase(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HoldCaptive.java b/Mage.Sets/src/mage/cards/h/HoldCaptive.java new file mode 100644 index 0000000000..c523058afc --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HoldCaptive.java @@ -0,0 +1,43 @@ +package mage.cards.h; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.combat.CantBlockAttackActivateAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class HoldCaptive extends CardImpl { + public HoldCaptive(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{B}"); + this.addSubType(SubType.AURA); + + //Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget); + this.addAbility(ability); + + //Enchanted creature can't attack or block, and its activated abilities can't be activited. + this.addAbility(new SimpleStaticAbility(new CantBlockAttackActivateAttachedEffect())); + } + + public HoldCaptive(final HoldCaptive card) { + super(card); + } + + @Override + public HoldCaptive copy() { + return new HoldCaptive(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/Holochess.java b/Mage.Sets/src/mage/cards/h/Holochess.java new file mode 100644 index 0000000000..860c34661d --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/Holochess.java @@ -0,0 +1,92 @@ +package mage.cards.h; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CounterUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetSpell; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +import java.util.List; +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class Holochess extends CardImpl { + public Holochess(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); + + //Choose a number between 0 and 3. If the chosen number is less than the number of creatures an opponent controls, + //draw X cards where X is the chosen number. Otherwise, counter target spell unless its controller pays {X}. + this.getSpellAbility().addEffect(new HolochessEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + } + + public Holochess(Holochess card) { + super(card); + } + + @Override + public Holochess copy() { + return new Holochess(this); + } +} + +class HolochessEffect extends OneShotEffect { + + HolochessEffect() { + super(Outcome.Benefit); + staticText = "Choose a number between 0 and 3. If the chosen number is less than the number of creatures an " + + "opponent controls, draw X cards where X is the chosen number. Otherwise, counter target spell " + + "unless its controller pays {X}."; + } + + private HolochessEffect(final HolochessEffect effect) { + super(effect); + } + + @Override + public HolochessEffect copy() { + return new HolochessEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(source.getFirstTarget()); + if (player == null || opponent == null) { + return false; + } + int chosenNumber = player.getAmount(0, 3, "Choose a number between 0 and 3", game); + List creaturesControlledByOpponent = game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_PERMANENT_CREATURES, opponent.getId(), game); + if (chosenNumber < creaturesControlledByOpponent.size()) { + player.drawCards(chosenNumber, source, game); + } + else { + if (game.getStack().isEmpty()) { + return false; + } + CounterUnlessPaysEffect counterUnlessPaysEffect = new CounterUnlessPaysEffect( + new GenericManaCost(chosenNumber)); + TargetSpell targetSpell = new TargetSpell(); + player.chooseTarget(Outcome.Benefit, targetSpell, source, game); + if (targetSpell.getFirstTarget() == null) { + return false; + } + counterUnlessPaysEffect.setTargetPointer(new FixedTarget(targetSpell.getFirstTarget())); + return counterUnlessPaysEffect.apply(game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/k/KnightsOfRen.java b/Mage.Sets/src/mage/cards/k/KnightsOfRen.java new file mode 100644 index 0000000000..e429c24aeb --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KnightsOfRen.java @@ -0,0 +1,60 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.HateCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.SacrificeAllEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.StaticFilters; +import mage.watchers.common.LifeLossOtherFromCombatWatcher; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class KnightsOfRen extends CardImpl { + public KnightsOfRen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); + this.addSuperType(SuperType.LEGENDARY); + this.addSubType(SubType.HUMAN); + this.addSubType(SubType.SITH); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + //Menace + this.addAbility(new MenaceAbility()); + + //Hate — Whenever Knights of Ren enters the battlefield or attacks, if an opponent lost life from a source other + //than combat damage this turn, you may have each player sacrifice a creature. + Ability abilityEnterBattlefield = new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility( + new SacrificeAllEffect(1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), true), + HateCondition.instance, + "Hate — When {this} enters the battlefield, if an opponent lost life from a source other than combat damage this turn, you may have each player sacrifice a creature"); + Ability abilityAttacks = new ConditionalInterveningIfTriggeredAbility( + new AttacksTriggeredAbility( + new SacrificeAllEffect(1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), true), + HateCondition.instance, + "Hate — When {this} attacks, if an opponent lost life from a source other than combat damage this turn, you may have each player sacrifice a creature"); + this.addAbility(abilityEnterBattlefield, new LifeLossOtherFromCombatWatcher()); + this.addAbility(abilityAttacks, new LifeLossOtherFromCombatWatcher()); + } + + public KnightsOfRen(final KnightsOfRen card) { + super(card); + } + + @Override + public KnightsOfRen copy() { + return new KnightsOfRen(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LightspeedSkipping.java b/Mage.Sets/src/mage/cards/l/LightspeedSkipping.java new file mode 100644 index 0000000000..f1b4fe6c31 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LightspeedSkipping.java @@ -0,0 +1,42 @@ +package mage.cards.l; + +import mage.abilities.Mode; +import mage.abilities.effects.common.RemoveFromCombatTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetAttackingOrBlockingCreature; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class LightspeedSkipping extends CardImpl { + public LightspeedSkipping(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + //Choose one -- + //* Target creature gains hexproof until end of turn. + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HexproofAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + //* Remove target creature from combat. + Mode mode = new Mode(new RemoveFromCombatTargetEffect()); + mode.addTarget(new TargetAttackingOrBlockingCreature()); + this.getSpellAbility().addMode(mode); + } + + public LightspeedSkipping(final LightspeedSkipping card) { + super(card); + } + + @Override + public LightspeedSkipping copy() { + return new LightspeedSkipping(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LukesLightsaber.java b/Mage.Sets/src/mage/cards/l/LukesLightsaber.java new file mode 100644 index 0000000000..b7ca14dcc7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LukesLightsaber.java @@ -0,0 +1,57 @@ +package mage.cards.l; + +import mage.ObjectColor; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.GainLifeTargetEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.target.TargetPlayer; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class LukesLightsaber extends CardImpl { + public LukesLightsaber(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.addSuperType(SuperType.LEGENDARY); + this.addSubType(SubType.EQUIPMENT); + + //Equipped creature gets +2/+0 and has first strike and protection from black. + this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 0))); + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and has first strike"))); + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.BLACK), AttachmentType.EQUIPMENT + ).setText("and protection from black"))); + + //Whenever equipped creature deals combat damage to a player, target player gains 2 life. + DealsCombatDamageToAPlayerTriggeredAbility dealsCombatDamageToAPlayerTriggeredAbility = + new DealsCombatDamageToAPlayerTriggeredAbility(new GainLifeTargetEffect(2), false); + dealsCombatDamageToAPlayerTriggeredAbility.addTarget(new TargetPlayer()); + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + dealsCombatDamageToAPlayerTriggeredAbility, AttachmentType.EQUIPMENT))); + + //Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2), false)); + } + + public LukesLightsaber(final LukesLightsaber card) { + super(card); + } + + @Override + public LukesLightsaber copy() { + return new LukesLightsaber(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/Orbak.java b/Mage.Sets/src/mage/cards/o/Orbak.java new file mode 100644 index 0000000000..ab7b0537ea --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/Orbak.java @@ -0,0 +1,34 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.abilities.keyword.MonstrosityAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class Orbak extends CardImpl { + public Orbak(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.addSubType(SubType.BEAST); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + //{4}{W}: Monstrosity 3 + this.addAbility(new MonstrosityAbility("{4}{W}", 3)); + } + + public Orbak(final Orbak card) { + super(card); + } + + @Override + public Orbak copy() { + return new Orbak(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/ReySkywalker.java b/Mage.Sets/src/mage/cards/r/ReySkywalker.java new file mode 100644 index 0000000000..4cbf932aff --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/ReySkywalker.java @@ -0,0 +1,57 @@ +package mage.cards.r; + +import mage.abilities.LoyaltyAbility; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class ReySkywalker extends CardImpl { + public ReySkywalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{U}"); + this.addSuperType(SuperType.LEGENDARY); + this.addSubType(SubType.REY); + + this.setStartingLoyalty(2); + + //+2: Untap target permanent. Scry 1. + LoyaltyAbility loyaltyAbilityP2 = new LoyaltyAbility(new UntapTargetEffect(), +2); + loyaltyAbilityP2.addTarget(new TargetPermanent()); + loyaltyAbilityP2.addEffect(new ScryEffect(1)); + this.addAbility(loyaltyAbilityP2); + + //+1: Tap target creature. That creature doesn't untap during controller's next untap step. Scry 1. + LoyaltyAbility loyaltyAbilityP1 = new LoyaltyAbility(new TapTargetEffect(), +1); + loyaltyAbilityP1.addEffect(new DontUntapInControllersNextUntapStepTargetEffect()); + loyaltyAbilityP1.addTarget(new TargetCreaturePermanent()); + loyaltyAbilityP1.addEffect(new ScryEffect(1)); + this.addAbility(loyaltyAbilityP1); + + //0: Draw a card. Scry 1. + LoyaltyAbility loyaltyAbility0 = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 0); + loyaltyAbility0.addEffect(new ScryEffect(1)); + this.addAbility(loyaltyAbility0); + } + + public ReySkywalker(final ReySkywalker card) { + super(card); + } + + @Override + public ReySkywalker copy() { + return new ReySkywalker(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/ReysLightsaber.java b/Mage.Sets/src/mage/cards/r/ReysLightsaber.java new file mode 100644 index 0000000000..ee7823f5e2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/ReysLightsaber.java @@ -0,0 +1,56 @@ +package mage.cards.r; + +import mage.ObjectColor; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEndOfTurnEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.target.TargetPlayer; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class ReysLightsaber extends CardImpl { + public ReysLightsaber(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.addSuperType(SuperType.LEGENDARY); + this.addSubType(SubType.EQUIPMENT); + + //Equipped creature gets +2/+0 and has first strike and protection from red. + this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 0))); + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has first strike"))); + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + ProtectionAbility.from(ObjectColor.RED), AttachmentType.EQUIPMENT).setText("and protection from red"))); + + //Whenever equipped creature deals combat damage to a player, target player exiles the top card of their library. + //That player may play that card until next turn. + DealsCombatDamageToAPlayerTriggeredAbility dealsCombatDamageToAPlayerTriggeredAbility = + new DealsCombatDamageToAPlayerTriggeredAbility( + new ExileTopXMayPlayUntilEndOfTurnEffect(1, false), false); + dealsCombatDamageToAPlayerTriggeredAbility.addTarget(new TargetPlayer()); + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + dealsCombatDamageToAPlayerTriggeredAbility, AttachmentType.EQUIPMENT))); + + //Equip {2} + this.addAbility(new EquipAbility(2, false)); + } + + public ReysLightsaber(final ReysLightsaber card) { + super(card); + } + + @Override + public ReysLightsaber copy() { + return new ReysLightsaber(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SithEternalLightning.java b/Mage.Sets/src/mage/cards/s/SithEternalLightning.java new file mode 100644 index 0000000000..0a640ba620 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SithEternalLightning.java @@ -0,0 +1,84 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.CantBeCounteredSourceAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +import java.util.List; +import java.util.Set; +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class SithEternalLightning extends CardImpl { + public SithEternalLightning(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}"); + + //This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); + + //Tap all creatures your opponents control. Those creatures don't untap during their controller's next untap step. + this.getSpellAbility().addEffect(new SithEternalLightningEffect()); + + //Scry 4. + this.getSpellAbility().addEffect(new ScryEffect(4)); + } + + public SithEternalLightning(final SithEternalLightning card) { + super(card); + } + + @Override + public SithEternalLightning copy() { + return new SithEternalLightning(this); + } +} + +class SithEternalLightningEffect extends OneShotEffect { + + public SithEternalLightningEffect() { + super(Outcome.Benefit); + this.staticText = "Tap all creatures your opponents control. Those creatures don't untap during their controller's next untap step."; + } + + public SithEternalLightningEffect(final SithEternalLightningEffect effect) { + super(effect); + } + + @Override + public SithEternalLightningEffect copy() { + return new SithEternalLightningEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Set opponents = game.getOpponents(controller.getId()); + if (controller != null && opponents != null) { + for (UUID opponent : opponents) { + List permanents = game.getBattlefield().getActivePermanents(opponent, game); + for (Permanent permanent : permanents) { + if (permanent.isCreature() && permanent.getControllerId() == opponent) { + permanent.tap(source, game); + DontUntapInControllersNextUntapStepTargetEffect effect = new DontUntapInControllersNextUntapStepTargetEffect(); + effect.setTargetPointer(new FixedTarget(permanent.getId(), game)); + game.addEffect(effect, source); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SithWayfinder.java b/Mage.Sets/src/mage/cards/s/SithWayfinder.java new file mode 100644 index 0000000000..f9a3094f10 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SithWayfinder.java @@ -0,0 +1,41 @@ +package mage.cards.s; + +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class SithWayfinder extends CardImpl { + public SithWayfinder(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + //{2}, {T}, Sacrifice Sith Wayfinder: Search your library for a land card, reveal it, and put it into your hand. + //Then shuffle your library. + SimpleActivatedAbility simpleActivatedAbility = new SimpleActivatedAbility(new SearchLibraryPutInHandEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_LAND), true, true), + new ManaCostsImpl<>("{2}")); + simpleActivatedAbility.addCost(new TapSourceCost()); + simpleActivatedAbility.addCost(new SacrificeSourceCost()); + this.addAbility(simpleActivatedAbility); + } + + public SithWayfinder(final SithWayfinder card) { + super(card); + } + + @Override + public SithWayfinder copy() { + return new SithWayfinder(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TrainingDroid.java b/Mage.Sets/src/mage/cards/t/TrainingDroid.java new file mode 100644 index 0000000000..8350e75de1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TrainingDroid.java @@ -0,0 +1,34 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.keyword.RepairAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class TrainingDroid extends CardImpl { + public TrainingDroid(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); + this.addSubType(SubType.DROID); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + //Repair 2 + this.addAbility(new RepairAbility(2)); + } + + public TrainingDroid(final TrainingDroid card) { + super(card); + } + + @Override + public TrainingDroid copy() { + return new TrainingDroid(this); + } +} diff --git a/Mage.Sets/src/mage/cards/u/UnpleasantDiscovery.java b/Mage.Sets/src/mage/cards/u/UnpleasantDiscovery.java new file mode 100644 index 0000000000..87e2089947 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnpleasantDiscovery.java @@ -0,0 +1,35 @@ +package mage.cards.u; + +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.common.MillCardsEachPlayerEffect; +import mage.abilities.effects.common.RevealHandEachPlayerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class UnpleasantDiscovery extends CardImpl { + public UnpleasantDiscovery(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); + + //Each opponent reveals their hand, loses 1 life, and mills two cards. + this.getSpellAbility().addEffect(new RevealHandEachPlayerEffect(TargetController.OPPONENT)); + this.getSpellAbility().addEffect(new LoseLifeOpponentsEffect(1).setText("and loses 1 life")); + this.getSpellAbility().addEffect(new MillCardsEachPlayerEffect(2, TargetController.OPPONENT) + .setText(" and mills two cards")); + } + + public UnpleasantDiscovery(final UnpleasantDiscovery card) { + super(card); + } + + @Override + public UnpleasantDiscovery copy() { + return new UnpleasantDiscovery(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/Vexis.java b/Mage.Sets/src/mage/cards/v/Vexis.java new file mode 100644 index 0000000000..1791d0ddfc --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/Vexis.java @@ -0,0 +1,52 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.common.OneOrMoreCountersAddedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ColoredManaCost; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.MonstrosityAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class Vexis extends CardImpl { + public Vexis(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + this.addSubType(SubType.WURM); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + //Trample + this.addAbility(TrampleAbility.getInstance()); + + //{W}: Monstrosity 2 + this.addAbility(new MonstrosityAbility("{W}", 2)); + + //Whenever a +1/+1 counter is put on Vexis, it gains vigilance until end of turn. + this.addAbility(new OneOrMoreCountersAddedTriggeredAbility(new GainAbilitySourceEffect( + VigilanceAbility.getInstance(), Duration.EndOfTurn), false, CounterType.P1P1)); + } + + public Vexis(final Vexis card) { + super(card); + } + + @Override + public Vexis copy() { + return new Vexis(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WarRoomStarWars.java b/Mage.Sets/src/mage/cards/w/WarRoomStarWars.java new file mode 100644 index 0000000000..603d6f12d1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WarRoomStarWars.java @@ -0,0 +1,82 @@ +package mage.cards.w; + +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.AttackedOrBlockedThisCombatWatcher; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class WarRoomStarWars extends CardImpl { + public WarRoomStarWars(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + + //At the beginning of each combat on your turn, target creature can't block this turn. + BeginningOfCombatTriggeredAbility beginningOfCombatTriggeredAbility = new BeginningOfCombatTriggeredAbility( + new GainAbilityTargetEffect(new CantBlockAbility(), Duration.EndOfTurn) + .setText("target creature can't block this turn"), TargetController.YOU, false); + beginningOfCombatTriggeredAbility.addTarget(new TargetCreaturePermanent()); + this.addAbility(beginningOfCombatTriggeredAbility); + + //{1}: War Room deals 1 damage to target player. Activate this ability only if a creature you control attacked + //this turn and only once per turn. + LimitedTimesPerTurnActivatedAbility limitedTimesPerTurnActivatedAbility = new LimitedTimesPerTurnActivatedAbility( + Zone.BATTLEFIELD, + new DamageTargetEffect(1), + new ManaCostsImpl<>("{1}"), + 1, + new WarRoomStarWarsCondition()); + limitedTimesPerTurnActivatedAbility.addTarget(new TargetPlayer()); + this.addAbility(limitedTimesPerTurnActivatedAbility, new AttackedOrBlockedThisCombatWatcher()); + } + + public WarRoomStarWars(final WarRoomStarWars card) { + super(card); + } + + @Override + public WarRoomStarWars copy() { + return new WarRoomStarWars(this); + } +} + +class WarRoomStarWarsCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + AttackedOrBlockedThisCombatWatcher watcher = game.getState().getWatcher(AttackedOrBlockedThisCombatWatcher.class); + if (game.getActivePlayerId() == source.getControllerId()) { + if (watcher != null) { + for (MageObjectReference mor : watcher.getAttackedThisTurnCreatures()) { + if (mor.getPermanent(game).getControllerId() == source.getControllerId()) { + return true; + } + } + } + } + return false; + } + + @Override + public String toString() { + return "if a creature you control attacked this turn"; + } +} diff --git a/Mage.Sets/src/mage/cards/x/XystonStarDestroyer.java b/Mage.Sets/src/mage/cards/x/XystonStarDestroyer.java new file mode 100644 index 0000000000..39c6ec290a --- /dev/null +++ b/Mage.Sets/src/mage/cards/x/XystonStarDestroyer.java @@ -0,0 +1,43 @@ +package mage.cards.x; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.SpaceflightAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class XystonStarDestroyer extends CardImpl { + public XystonStarDestroyer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}{B}{B}"); + this.subtype.add(SubType.STARSHIP); + this.power = new MageInt(9); + this.toughness = new MageInt(9); + + //Spaceflight + this.addAbility(SpaceflightAbility.getInstance()); + + //When Xyston Star Destroyer enters the battlefield, destroy target creature. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public XystonStarDestroyer(final XystonStarDestroyer card) { + super(card); + } + + @Override + public XystonStarDestroyer copy() { + return new XystonStarDestroyer(this); + } +} diff --git a/Mage.Sets/src/mage/cards/z/ZoriiBliss.java b/Mage.Sets/src/mage/cards/z/ZoriiBliss.java new file mode 100644 index 0000000000..66a5733517 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZoriiBliss.java @@ -0,0 +1,50 @@ +package mage.cards.z; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.target.TargetPlayer; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class ZoriiBliss extends CardImpl { + public ZoriiBliss(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.addSuperType(SuperType.LEGENDARY); + this.addSubType(SubType.REBEL); + this.addSubType(SubType.ROGUE); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + //Haste + this.addAbility(HasteAbility.getInstance()); + + //Whenever Zorii Bliss attacks, you may discard a card. If you do, any number of target players each draw a card. + AttacksTriggeredAbility attacksTriggeredAbility = new AttacksTriggeredAbility( + new DoIfCostPaid(new DrawCardTargetEffect(1), new DiscardCardCost(), + "Discard a card and target players draw a card?"), false, + "Whenever Zorii Bliss attacks, you may discard a card. If you do, any number of target players each draw a card."); + attacksTriggeredAbility.addTarget(new TargetPlayer(0, Integer.MAX_VALUE, false)); + this.addAbility(attacksTriggeredAbility); + } + + public ZoriiBliss(final ZoriiBliss card) { + super(card); + } + + @Override + public ZoriiBliss copy() { + return new ZoriiBliss(this); + } +} diff --git a/Mage.Sets/src/mage/sets/StarWars.java b/Mage.Sets/src/mage/sets/StarWars.java index df1d2f87b1..4ba3a8b63e 100644 --- a/Mage.Sets/src/mage/sets/StarWars.java +++ b/Mage.Sets/src/mage/sets/StarWars.java @@ -32,6 +32,7 @@ public final class StarWars extends ExpansionSet { this.ratioBoosterMythic = 8; this.maxCardNumberInBooster = 271; + cards.add(new SetCardInfo("A Jedi's Fervor", 704, Rarity.UNCOMMON, mage.cards.a.AJedisFervor.class)); cards.add(new SetCardInfo("A-Wing", 96, Rarity.UNCOMMON, mage.cards.a.AWing.class)); cards.add(new SetCardInfo("AAT-1", 160, Rarity.UNCOMMON, mage.cards.a.AAT1.class)); cards.add(new SetCardInfo("Acklay of the Arena", 161, Rarity.RARE, mage.cards.a.AcklayOfTheArena.class)); @@ -39,6 +40,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Admiral Ackbar", 35, Rarity.RARE, mage.cards.a.AdmiralAckbar.class)); cards.add(new SetCardInfo("Adroit Hateflayer", 162, Rarity.COMMON, mage.cards.a.AdroitHateflayer.class)); cards.add(new SetCardInfo("Afterburn", 600, Rarity.COMMON, mage.cards.a.Afterburn.class)); + cards.add(new SetCardInfo("Allegiant General Pryde", 712, Rarity.RARE, mage.cards.a.AllegiantGeneralPryde.class)); cards.add(new SetCardInfo("Anakin Skywalker", 163, Rarity.MYTHIC, mage.cards.a.AnakinSkywalker.class)); cards.add(new SetCardInfo("Ancient Holocron", 230, Rarity.UNCOMMON, mage.cards.a.AncientHolocron.class)); cards.add(new SetCardInfo("Aqualish Bounty Hunter", 66, Rarity.COMMON, mage.cards.a.AqualishBountyHunter.class)); @@ -48,13 +50,18 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("AT-ST", 128, Rarity.RARE, mage.cards.a.ATST.class)); cards.add(new SetCardInfo("Astromech Droid", 400, Rarity.COMMON, mage.cards.a.AstromechDroid.class)); cards.add(new SetCardInfo("Aurra Sing, Bane of Jedi", 165, Rarity.MYTHIC, mage.cards.a.AurraSingBaneOfJedi.class)); + cards.add(new SetCardInfo("Balance", 702, Rarity.MYTHIC, mage.cards.b.Balance.class)); + cards.add(new SetCardInfo("Band Together", 718, Rarity.COMMON, mage.cards.b.BandTogether.class)); cards.add(new SetCardInfo("Bantha Herd", 3, Rarity.RARE, mage.cards.b.BanthaHerd.class)); cards.add(new SetCardInfo("Bathe in Bacta", 129, Rarity.COMMON, mage.cards.b.BatheInBacta.class)); cards.add(new SetCardInfo("Battle Tactics", 5, Rarity.UNCOMMON, mage.cards.b.BattleTactics.class)); + cards.add(new SetCardInfo("Ben Solo", 725, Rarity.MYTHIC, mage.cards.b.BenSolo.class)); + cards.add(new SetCardInfo("Betray", 715, Rarity.COMMON, mage.cards.b.Betray.class)); cards.add(new SetCardInfo("Bib Fortuna", 68, Rarity.RARE, mage.cards.b.BibFortuna.class)); cards.add(new SetCardInfo("Black Market Dealer", 69, Rarity.UNCOMMON, mage.cards.b.BlackMarketDealer.class)); cards.add(new SetCardInfo("Blind Worship", 166, Rarity.RARE, mage.cards.b.BlindWorship.class)); cards.add(new SetCardInfo("Bludgeoning Pain", 300, Rarity.COMMON, mage.cards.b.BludgeoningPain.class)); + cards.add(new SetCardInfo("Brave the Elements", 703, Rarity.UNCOMMON, mage.cards.b.BraveTheElements.class)); cards.add(new SetCardInfo("Buried Ruin", 401, Rarity.COMMON, mage.cards.b.BuriedRuin.class)); cards.add(new SetCardInfo("Boba Fett", 167, Rarity.MYTHIC, mage.cards.b.BobaFett.class)); cards.add(new SetCardInfo("Bor Gullet", 301, Rarity.UNCOMMON, mage.cards.b.BorGullet.class)); @@ -83,6 +90,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Corellian Gunship", 603, Rarity.COMMON, mage.cards.c.CorellianGunship.class)); cards.add(new SetCardInfo("Crossfire", 100, Rarity.COMMON, mage.cards.c.Crossfire.class)); cards.add(new SetCardInfo("Cruelty of the Sith", 174, Rarity.UNCOMMON, mage.cards.c.CrueltyOfTheSith.class)); + cards.add(new SetCardInfo("Culling Dais", 727, Rarity.UNCOMMON, mage.cards.c.CullingDais.class)); cards.add(new SetCardInfo("Cunning Abduction", 175, Rarity.RARE, mage.cards.c.CunningAbduction.class)); cards.add(new SetCardInfo("Dagobah Maw Slug", 176, Rarity.COMMON, mage.cards.d.DagobahMawSlug.class)); cards.add(new SetCardInfo("Dark Apprenticeship", 101, Rarity.UNCOMMON, mage.cards.d.DarkApprenticeship.class)); @@ -102,9 +110,11 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Droid Factory", 239, Rarity.COMMON, mage.cards.d.DroidFactory.class)); cards.add(new SetCardInfo("Droid Foundry", 240, Rarity.UNCOMMON, mage.cards.d.DroidFoundry.class)); cards.add(new SetCardInfo("Droid Uprising", 605, Rarity.UNCOMMON, mage.cards.d.DroidUprising.class)); + cards.add(new SetCardInfo("Droidsmith", 720, Rarity.UNCOMMON, mage.cards.d.Droidsmith.class)); cards.add(new SetCardInfo("Droideka", 9, Rarity.UNCOMMON, mage.cards.d.Droideka.class)); cards.add(new SetCardInfo("Drone Holocron", 232, Rarity.COMMON, mage.cards.d.DroneHolocron.class)); cards.add(new SetCardInfo("Dryden Vos", 606, Rarity.RARE, mage.cards.d.DrydenVos.class)); + cards.add(new SetCardInfo("Dyad Force Transfer", 707, Rarity.COMMON, mage.cards.d.DyadForceTransfer.class)); cards.add(new SetCardInfo("Echo Base Commando", 181, Rarity.RARE, mage.cards.e.EchoBaseCommando.class)); cards.add(new SetCardInfo("EMP Blast", 10, Rarity.UNCOMMON, mage.cards.e.EMPBlast.class)); cards.add(new SetCardInfo("Enfys Nest", 607, Rarity.MYTHIC, mage.cards.e.EnfysNest.class)); @@ -115,14 +125,17 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Exogorth", 136, Rarity.RARE, mage.cards.e.Exogorth.class)); cards.add(new SetCardInfo("Fathier", 505, Rarity.COMMON, mage.cards.f.Fathier.class)); cards.add(new SetCardInfo("Ferocity of the Underworld", 182, Rarity.UNCOMMON, mage.cards.f.FerocityOfTheUnderworld.class)); + cards.add(new SetCardInfo("Festival of the Ancestors", 701, Rarity.COMMON, mage.cards.f.FestivalOfTheAncestors.class)); cards.add(new SetCardInfo("Finn", 402, Rarity.UNCOMMON, mage.cards.f.Finn.class)); cards.add(new SetCardInfo("First Order Dreadnought", 506, Rarity.MYTHIC, mage.cards.f.FirstOrderDreadnought.class)); + cards.add(new SetCardInfo("First Order Jet Trooper", 721, Rarity.UNCOMMON, mage.cards.f.FirstOrderJetTrooper.class)); cards.add(new SetCardInfo("Flame Trooper", 403, Rarity.COMMON, mage.cards.f.FlameTrooper.class)); cards.add(new SetCardInfo("Flames of Remembrance", 102, Rarity.RARE, mage.cards.f.FlamesOfRemembrance.class)); cards.add(new SetCardInfo("Force Choke", 183, Rarity.COMMON, mage.cards.f.ForceChoke.class)); cards.add(new SetCardInfo("Force Denial", 39, Rarity.COMMON, mage.cards.f.ForceDenial.class)); cards.add(new SetCardInfo("Force Drain", 74, Rarity.COMMON, mage.cards.f.ForceDrain.class)); cards.add(new SetCardInfo("Force Healing", 12, Rarity.COMMON, mage.cards.f.ForceHealing.class)); + cards.add(new SetCardInfo("Force Lift", 726, Rarity.COMMON, mage.cards.f.ForceLift.class)); cards.add(new SetCardInfo("Force Lightning", 103, Rarity.RARE, mage.cards.f.ForceLightning.class)); cards.add(new SetCardInfo("Force Mastery", 184, Rarity.RARE, mage.cards.f.ForceMastery.class)); cards.add(new SetCardInfo("Force Projection", 507, Rarity.RARE, mage.cards.f.ForceProjection.class)); @@ -143,6 +156,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Gamorrean Prison Guard", 106, Rarity.UNCOMMON, mage.cards.g.GamorreanPrisonGuard.class)); cards.add(new SetCardInfo("General Grievous", 185, Rarity.MYTHIC, mage.cards.g.GeneralGrievous.class)); cards.add(new SetCardInfo("General Hux", 405, Rarity.UNCOMMON, mage.cards.g.GeneralHux.class)); + cards.add(new SetCardInfo("General Organa", 722, Rarity.RARE, mage.cards.g.GeneralOrgana.class)); cards.add(new SetCardInfo("Gerrera's Revolutionary", 305, Rarity.COMMON, mage.cards.g.GerrerasRevolutionary.class)); cards.add(new SetCardInfo("Gifted Initiate", 14, Rarity.COMMON, mage.cards.g.GiftedInitiate.class)); cards.add(new SetCardInfo("Glorious Charge", 509, Rarity.COMMON, mage.cards.g.GloriousCharge.class)); @@ -157,6 +171,9 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Hazard Trooper", 76, Rarity.UNCOMMON, mage.cards.h.HazardTrooper.class)); cards.add(new SetCardInfo("Head Hunting", 77, Rarity.COMMON, mage.cards.h.HeadHunting.class)); cards.add(new SetCardInfo("Heavy Trooper", 78, Rarity.COMMON, mage.cards.h.HeavyTrooper.class)); + cards.add(new SetCardInfo("Hidden Base", 733, Rarity.UNCOMMON, mage.cards.h.HiddenBase.class)); + cards.add(new SetCardInfo("Hold Captive", 723, Rarity.COMMON, mage.cards.h.HoldCaptive.class)); + cards.add(new SetCardInfo("Holochess", 708, Rarity.UNCOMMON, mage.cards.h.Holochess.class)); cards.add(new SetCardInfo("Hot Pursuit", 188, Rarity.RARE, mage.cards.h.HotPursuit.class)); cards.add(new SetCardInfo("Hungry Dragonsnake", 138, Rarity.COMMON, mage.cards.h.HungryDragonsnake.class)); cards.add(new SetCardInfo("Hunt to Extinction", 189, Rarity.RARE, mage.cards.h.HuntToExtinction.class)); @@ -172,6 +189,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Interrogation", 81, Rarity.COMMON, mage.cards.i.Interrogation.class)); cards.add(new SetCardInfo("Ion Cannon", 15, Rarity.COMMON, mage.cards.i.IonCannon.class)); cards.add(new SetCardInfo("Iron Fist of the Empire", 191, Rarity.RARE, mage.cards.i.IronFistOfTheEmpire.class)); + cards.add(new SetCardInfo("Island", "520a", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Island", "256a", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Island", "256b", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Island", "256c", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); @@ -200,15 +218,18 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Kalevan Star Yacht", 610, Rarity.UNCOMMON, mage.cards.k.KalevanStarYacht.class)); cards.add(new SetCardInfo("Kamino Cloning Facility", 246, Rarity.RARE, mage.cards.k.KaminoCloningFacility.class)); cards.add(new SetCardInfo("Ki-Adi-Mundi", 142, Rarity.RARE, mage.cards.k.KiAdiMundi.class)); + cards.add(new SetCardInfo("Knights of Ren", 724, Rarity.RARE, mage.cards.k.KnightsOfRen.class)); cards.add(new SetCardInfo("Kylo Ren", 406, Rarity.MYTHIC, mage.cards.k.KyloRen.class)); cards.add(new SetCardInfo("LAAT Gunship", 20, Rarity.UNCOMMON, mage.cards.l.LAATGunship.class)); cards.add(new SetCardInfo("Lando Calrissian", 21, Rarity.RARE, mage.cards.l.LandoCalrissian.class)); cards.add(new SetCardInfo("Legacy of the Beloved", 143, Rarity.RARE, mage.cards.l.LegacyOfTheBeloved.class)); cards.add(new SetCardInfo("Lightning Bolt", 113, Rarity.UNCOMMON, mage.cards.l.LightningBolt.class)); cards.add(new SetCardInfo("Lightsaber", 234, Rarity.COMMON, mage.cards.l.Lightsaber.class)); + cards.add(new SetCardInfo("Lightspeed Skipping", 705, Rarity.COMMON, mage.cards.l.LightspeedSkipping.class)); cards.add(new SetCardInfo("Loyal Tauntaun", 22, Rarity.COMMON, mage.cards.l.LoyalTauntaun.class)); cards.add(new SetCardInfo("Luke Skywalker", 195, Rarity.MYTHIC, mage.cards.l.LukeSkywalker.class)); cards.add(new SetCardInfo("Luke Skywalker, the Last Jedi", 511, Rarity.MYTHIC, mage.cards.l.LukeSkywalkerTheLastJedi.class)); + cards.add(new SetCardInfo("Luke's Lightsaber", 728, Rarity.RARE, mage.cards.l.LukesLightsaber.class)); cards.add(new SetCardInfo("Mace Windu", 47, Rarity.RARE, mage.cards.m.MaceWindu.class)); cards.add(new SetCardInfo("Maelstrom Blockade", 611, Rarity.COMMON, mage.cards.m.MaelstromBlockade.class)); cards.add(new SetCardInfo("Maintenance Droid", 196, Rarity.COMMON, mage.cards.m.MaintenanceDroid.class)); @@ -218,6 +239,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Massiff Swarm", 145, Rarity.COMMON, mage.cards.m.MassiffSwarm.class)); cards.add(new SetCardInfo("Might of the Wild", 198, Rarity.UNCOMMON, mage.cards.m.MightOfTheWild.class)); cards.add(new SetCardInfo("Millennium Falcon", 146, Rarity.RARE, mage.cards.m.MillenniumFalcon.class)); + cards.add(new SetCardInfo("Mimic Vat", 729, Rarity.RARE, mage.cards.m.MimicVat.class)); cards.add(new SetCardInfo("Miraculous Recovery", 24, Rarity.UNCOMMON, mage.cards.m.MiraculousRecovery.class)); cards.add(new SetCardInfo("Moisture Farm", 247, Rarity.UNCOMMON, mage.cards.m.MoistureFarm.class)); cards.add(new SetCardInfo("Mon Calamari Cruiser", 48, Rarity.UNCOMMON, mage.cards.m.MonCalamariCruiser.class)); @@ -240,6 +262,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Obi-Wan Kenobi", 200, Rarity.MYTHIC, mage.cards.o.ObiWanKenobi.class)); cards.add(new SetCardInfo("Occupation", 309, Rarity.UNCOMMON, mage.cards.o.Occupation.class)); cards.add(new SetCardInfo("Open Season", 83, Rarity.UNCOMMON, mage.cards.o.OpenSeason.class)); + cards.add(new SetCardInfo("Orbak", 706, Rarity.COMMON, mage.cards.o.Orbak.class)); cards.add(new SetCardInfo("Orbital Bombardment", 26, Rarity.RARE, mage.cards.o.OrbitalBombardment.class)); cards.add(new SetCardInfo("Order 66", 84, Rarity.RARE, mage.cards.o.Order66.class)); cards.add(new SetCardInfo("Ortolan Keyboardist", 50, Rarity.COMMON, mage.cards.o.OrtolanKeyboardist.class)); @@ -247,6 +270,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Outer Rim Slaver", 201, Rarity.COMMON, mage.cards.o.OuterRimSlaver.class)); cards.add(new SetCardInfo("Outlaw Holocron", 235, Rarity.COMMON, mage.cards.o.OutlawHolocron.class)); cards.add(new SetCardInfo("Personal Energy Shield", 51, Rarity.COMMON, mage.cards.p.PersonalEnergyShield.class)); + cards.add(new SetCardInfo("Plains", "520b", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Plains", "252a", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Plains", "252b", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Plains", "252c", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); @@ -261,6 +285,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Primal Instinct", 203, Rarity.COMMON, mage.cards.p.PrimalInstinct.class)); cards.add(new SetCardInfo("Princess Leia", 204, Rarity.RARE, mage.cards.p.PrincessLeia.class)); cards.add(new SetCardInfo("Probe Droid", 52, Rarity.COMMON, mage.cards.p.ProbeDroid.class)); + cards.add(new SetCardInfo("Propaganda", 709, Rarity.UNCOMMON, mage.cards.p.Propaganda.class)); cards.add(new SetCardInfo("Qui-Gon Jinn", 205, Rarity.RARE, mage.cards.q.QuiGonJinn.class)); cards.add(new SetCardInfo("Raging Reek", 115, Rarity.COMMON, mage.cards.r.RagingReek.class)); cards.add(new SetCardInfo("Rallying Fire", 116, Rarity.COMMON, mage.cards.r.RallyingFire.class)); @@ -274,6 +299,8 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Resistance Bomber", 515, Rarity.UNCOMMON, mage.cards.r.ResistanceBomber.class)); cards.add(new SetCardInfo("Revenge (Star Wars)", 117, Rarity.COMMON, mage.cards.r.RevengeStarWars.class)); cards.add(new SetCardInfo("Rey", 410, Rarity.RARE, mage.cards.r.Rey.class)); + cards.add(new SetCardInfo("Rey Skywalker", 710, Rarity.MYTHIC, mage.cards.r.ReySkywalker.class)); + cards.add(new SetCardInfo("Rey's Lightsaber", 730, Rarity.RARE, mage.cards.r.ReysLightsaber.class)); cards.add(new SetCardInfo("Riding Ronto", 28, Rarity.UNCOMMON, mage.cards.r.RidingRonto.class)); cards.add(new SetCardInfo("Riot Trooper", 411, Rarity.COMMON, mage.cards.r.RiotTrooper.class)); cards.add(new SetCardInfo("Rocket Trooper", 118, Rarity.RARE, mage.cards.r.RocketTrooper.class)); @@ -302,6 +329,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Sins of the Father", 413, Rarity.COMMON, mage.cards.s.SinsOfTheFather.class)); cards.add(new SetCardInfo("Sith Assassin", 87, Rarity.UNCOMMON, mage.cards.s.SithAssassin.class)); cards.add(new SetCardInfo("Sith Citadel", 249, Rarity.UNCOMMON, mage.cards.s.SithCitadel.class)); + cards.add(new SetCardInfo("Sith Eternal Lightning", 711, Rarity.RARE, mage.cards.s.SithEternalLightning.class)); cards.add(new SetCardInfo("Sith Evoker", 88, Rarity.COMMON, mage.cards.s.SithEvoker.class)); cards.add(new SetCardInfo("Sith Holocron", 236, Rarity.COMMON, mage.cards.s.SithHolocron.class)); cards.add(new SetCardInfo("Sith Inquisitor", 89, Rarity.COMMON, mage.cards.s.SithInquisitor.class)); @@ -314,6 +342,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Sith Ruins", 250, Rarity.COMMON, mage.cards.s.SithRuins.class)); cards.add(new SetCardInfo("Sith Sorcerer", 58, Rarity.COMMON, mage.cards.s.SithSorcerer.class)); cards.add(new SetCardInfo("Sith Thoughtseeker", 91, Rarity.COMMON, mage.cards.s.SithThoughtseeker.class)); + cards.add(new SetCardInfo("Sith Wayfinder", 731, Rarity.COMMON, mage.cards.s.SithWayfinder.class)); cards.add(new SetCardInfo("Slave I", 216, Rarity.RARE, mage.cards.s.SlaveI.class)); cards.add(new SetCardInfo("Smash to Smithereens", 122, Rarity.UNCOMMON, mage.cards.s.SmashToSmithereens.class)); cards.add(new SetCardInfo("Snow Trooper", 31, Rarity.UNCOMMON, mage.cards.s.SnowTrooper.class)); @@ -327,6 +356,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Swamp", "260b", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Swamp", "260c", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Swamp", "260d", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); + cards.add(new SetCardInfo("Swamp", "734e", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); cards.add(new SetCardInfo("Swarm the Skies", 92, Rarity.COMMON, mage.cards.s.SwarmTheSkies.class)); cards.add(new SetCardInfo("Syndicate Enforcer", 124, Rarity.COMMON, mage.cards.s.SyndicateEnforcerSWS.class)); cards.add(new SetCardInfo("Tank Droid", 218, Rarity.RARE, mage.cards.t.TankDroid.class)); @@ -344,6 +374,7 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Thermal Detonator", 311, Rarity.COMMON, mage.cards.t.ThermalDetonator.class)); cards.add(new SetCardInfo("Tobias Beckett", 614, Rarity.RARE, mage.cards.t.TobiasBeckett.class)); cards.add(new SetCardInfo("Trade Federation Battleship", 219, Rarity.RARE, mage.cards.t.TradeFederationBattleship.class)); + cards.add(new SetCardInfo("Training Droid", 732, Rarity.COMMON, mage.cards.t.TrainingDroid.class)); cards.add(new SetCardInfo("Tri-Fighter", 228, Rarity.COMMON, mage.cards.t.TriFighter.class)); cards.add(new SetCardInfo("Trooper Armor", 237, Rarity.UNCOMMON, mage.cards.t.TrooperArmor.class)); cards.add(new SetCardInfo("Trooper Commando", 157, Rarity.UNCOMMON, mage.cards.t.TrooperCommando.class)); @@ -353,12 +384,15 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Underground Forum", 615, Rarity.UNCOMMON, mage.cards.u.UndergroundForum.class)); cards.add(new SetCardInfo("Underworld Slums", 251, Rarity.COMMON, mage.cards.u.UnderworldSlums.class)); cards.add(new SetCardInfo("Unity of the Droids", 220, Rarity.UNCOMMON, mage.cards.u.UnityOfTheDroids.class)); + cards.add(new SetCardInfo("Unpleasant Discovery", 713, Rarity.COMMON, mage.cards.u.UnpleasantDiscovery.class)); cards.add(new SetCardInfo("Unruly Sureshot", 95, Rarity.UNCOMMON, mage.cards.u.UnrulySureshot.class)); cards.add(new SetCardInfo("Upsilon-class Shuttle", 414, Rarity.COMMON, mage.cards.u.UpsilonClassShuttle.class)); cards.add(new SetCardInfo("V-Wing", 126, Rarity.COMMON, mage.cards.v.VWing.class)); cards.add(new SetCardInfo("Vader's Command", 314, Rarity.RARE, mage.cards.v.VadersCommand.class)); cards.add(new SetCardInfo("Vapor Snag", 62, Rarity.COMMON, mage.cards.v.VaporSnag.class)); + cards.add(new SetCardInfo("Vexis", 719, Rarity.UNCOMMON, mage.cards.v.Vexis.class)); cards.add(new SetCardInfo("Vulptex", 519, Rarity.COMMON, mage.cards.v.Vulptex.class)); + cards.add(new SetCardInfo("War Room (Star Wars)", 716, Rarity.RARE, mage.cards.w.WarRoomStarWars.class)); cards.add(new SetCardInfo("Weequay Beastmaster", 127, Rarity.UNCOMMON, mage.cards.w.WeequayBeastmaster.class)); cards.add(new SetCardInfo("Wild Holocron", 238, Rarity.COMMON, mage.cards.w.WildHolocron.class)); cards.add(new SetCardInfo("Wisdom of the Jedi", 221, Rarity.UNCOMMON, mage.cards.w.WisdomOfTheJedi.class)); @@ -367,10 +401,10 @@ public final class StarWars extends ExpansionSet { cards.add(new SetCardInfo("Wookiee Mystic", 222, Rarity.UNCOMMON, mage.cards.w.WookieeMystic.class)); cards.add(new SetCardInfo("Wookiee Raidleader", 229, Rarity.COMMON, mage.cards.w.WookieeRaidleader.class)); cards.add(new SetCardInfo("X-Wing", 33, Rarity.COMMON, mage.cards.x.XWing.class)); + cards.add(new SetCardInfo("Xyston Star Destroyer", 714, Rarity.RARE, mage.cards.x.XystonStarDestroyer.class)); cards.add(new SetCardInfo("Y-Wing", 63, Rarity.UNCOMMON, mage.cards.y.YWing.class)); cards.add(new SetCardInfo("Yoda, Jedi Master", 223, Rarity.MYTHIC, mage.cards.y.YodaJediMaster.class)); cards.add(new SetCardInfo("Zam Wesell", 64, Rarity.RARE, mage.cards.z.ZamWesell.class)); - cards.add(new SetCardInfo("Island", "520a", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); - cards.add(new SetCardInfo("Plains", "520b", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true))); + cards.add(new SetCardInfo("Zorii Bliss", 717, Rarity.RARE, mage.cards.z.ZoriiBliss.class)); } } diff --git a/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java b/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java index a6e2260740..d43797cdc2 100644 --- a/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java @@ -204,6 +204,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge || ruleLow.startsWith("attach") || ruleLow.startsWith("counter") || ruleLow.startsWith("destroy") + || ruleLow.startsWith("sacrifice") || ruleLow.startsWith("exchange") || ruleLow.startsWith("exile") || ruleLow.startsWith("gain") diff --git a/Mage/src/main/java/mage/abilities/effects/common/RevealHandEachPlayerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RevealHandEachPlayerEffect.java new file mode 100644 index 0000000000..49f8aca74e --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/RevealHandEachPlayerEffect.java @@ -0,0 +1,89 @@ +package mage.abilities.effects.common; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class RevealHandEachPlayerEffect extends OneShotEffect { + private final TargetController targetController; + + public RevealHandEachPlayerEffect() { + this(TargetController.ANY); + } + + public RevealHandEachPlayerEffect(TargetController targetController) { + super(Outcome.Benefit); + this.targetController = targetController; + } + + public RevealHandEachPlayerEffect(final RevealHandEachPlayerEffect effect) { + super(effect); + this.targetController = effect.targetController; + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source); + if (controller == null) { + return true; + } + for (UUID playerId : game.getPlayers().keySet()) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + switch (targetController) { + case NOT_YOU: + if (playerId.equals(source.getControllerId())) { + continue; + } + break; + case OPPONENT: + if (!game.getOpponents(source.getControllerId()).contains(playerId)) { + continue; + } + break; + } + player.revealCards(sourceObject.getIdName() + player.getName(), player.getHand(), game); + } + return true; + } + + @Override + public RevealHandEachPlayerEffect copy() { + return new RevealHandEachPlayerEffect(this); + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder(); + sb.append("each "); + switch (targetController) { + case NOT_YOU: + sb.append("other player"); + break; + case OPPONENT: + sb.append("opponent"); + break; + case ANY: + sb.append("player"); + break; + } + sb.append(" reveals their hand"); + return sb.toString(); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAndUntapTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAndUntapTargetEffect.java new file mode 100644 index 0000000000..68cea91cac --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAndUntapTargetEffect.java @@ -0,0 +1,159 @@ +package mage.abilities.effects.common.continuous; + +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.Mode; +import mage.abilities.condition.Condition; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author Merlingilb + */ +public class GainControlAndUntapTargetEffect extends ContinuousEffectImpl { + + protected UUID controllingPlayerId; + private boolean fixedControl; + private boolean firstControlChange = true; + private final Condition condition; + + public GainControlAndUntapTargetEffect(Duration duration) { + this(duration, false, null); + } + + /** + * @param duration + * @param fixedControl Controlling player is fixed even if the controller of + * the ability changes later + */ + public GainControlAndUntapTargetEffect(Duration duration, boolean fixedControl) { + this(duration, fixedControl, null); + } + + /** + * @param duration + * @param controllingPlayerId Player that controls the target creature + */ + public GainControlAndUntapTargetEffect(Duration duration, UUID controllingPlayerId) { + this(duration, true, controllingPlayerId); + + } + + public GainControlAndUntapTargetEffect(Duration duration, boolean fixedControl, UUID controllingPlayerId) { + this(duration, fixedControl, controllingPlayerId, null); + } + + public GainControlAndUntapTargetEffect(Duration duration, boolean fixedControl, UUID controllingPlayerId, Condition condition) { + super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); + this.controllingPlayerId = controllingPlayerId; + this.fixedControl = fixedControl; + this.condition = condition; + } + + public GainControlAndUntapTargetEffect(final GainControlAndUntapTargetEffect effect) { + super(effect); + this.controllingPlayerId = effect.controllingPlayerId; + this.fixedControl = effect.fixedControl; + this.condition = effect.condition; + } + + @Override + public GainControlAndUntapTargetEffect copy() { + return new GainControlAndUntapTargetEffect(this); + } + + @Override + public void init(Ability source, Game game) { + if (this.controllingPlayerId == null && fixedControl) { + this.controllingPlayerId = source.getControllerId(); + } + super.init(source, game); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + discard(); // controller no longer exists + return false; + } + boolean oneTargetStillExists = false; + for (UUID permanentId : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(permanentId); + if (permanent == null) { + continue; + } + oneTargetStillExists = true; + if (permanent.isControlledBy(controllingPlayerId)) { + permanent.untap(game); + continue; + } + boolean controlChanged = false; + if (controllingPlayerId != null) { + if (permanent.changeControllerId(controllingPlayerId, game, source)) { + permanent.untap(game); + controlChanged = true; + } + } else { + if (permanent.changeControllerId(source.getControllerId(), game, source)) { + permanent.untap(game); + controlChanged = true; + } + } + if (source instanceof ActivatedAbility + && firstControlChange && !controlChanged) { + // If it was not possible to get control of target permanent by the activated ability the first time it took place + // the effect failed (e.g. because of Guardian Beast) and must be discarded + // This does not handle correctly multiple targets at once + discard(); + } + if (condition != null && !condition.apply(game, source)) { + discard(); + } + } + // no valid target exists and the controller is no longer in the game, effect can be discarded + if (!oneTargetStillExists || !controller.isInGame()) { + discard(); + } + firstControlChange = false; + return true; + } + + @Override + public String getText(Mode mode) { + if (!staticText.isEmpty()) { + return staticText; + } + + if (mode.getTargets().isEmpty()) { + return "gain control of target permanent until end of turn. Untap it."; + } + + Target target = mode.getTargets().get(0); + StringBuilder sb = new StringBuilder("gain control of "); + if (target.getMaxNumberOfTargets() > 1) { + if (target.getNumberOfTargets() < target.getMaxNumberOfTargets()) { + sb.append("up to "); + } + sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets())).append(" target "); + } else if (!target.getTargetName().startsWith("another")) { + sb.append("target "); + } + sb.append(mode.getTargets().get(0).getTargetName()); + if (!duration.toString().isEmpty()) { + sb.append(' ').append(duration.toString()); + } + sb.append("and untap it"); + return sb.toString(); + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java b/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java index be3a2cdb14..760ba5fefa 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java @@ -1,6 +1,5 @@ package mage.abilities.keyword; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -8,11 +7,11 @@ import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.cards.Card; -import mage.constants.AsThoughEffectType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.TargetController; @@ -20,17 +19,20 @@ import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; /** * - * @author Styxo + * @author Styxo, Merlingilb */ public class RepairAbility extends DiesSourceTriggeredAbility { - private String ruleText; + private final String ruleText; public RepairAbility(int count) { - super(new AddCountersSourceEffect(CounterType.REPAIR.createInstance(), StaticValue.get(count), false, true)); + super(new AddCountersSourceEffect( + CounterType.REPAIR.createInstance(), StaticValue.get(count), false, true)); addSubAbility(new RepairBeginningOfUpkeepInterveningIfTriggeredAbility()); addSubAbility(new RepairCastFromGraveyardTriggeredAbility()); @@ -56,37 +58,41 @@ public class RepairAbility extends DiesSourceTriggeredAbility { } } -class RepairCastFromGraveyardEffect extends AsThoughEffectImpl { +class RepairedCastFromGraveyardEffect extends OneShotEffect { - public RepairCastFromGraveyardEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may cast it from graveyard until end of turn"; + public RepairedCastFromGraveyardEffect() { + super(Outcome.Benefit); } - public RepairCastFromGraveyardEffect(final RepairCastFromGraveyardEffect effect) { + private RepairedCastFromGraveyardEffect(final RepairedCastFromGraveyardEffect effect) { super(effect); } + @Override + public RepairedCastFromGraveyardEffect copy() { + return new RepairedCastFromGraveyardEffect(this); + } + @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Card card = game.getCard(source.getSourceId()); + if (card == null) { + return false; + } + game.addEffect(new PlayFromNotOwnHandZoneTargetEffect(Zone.GRAVEYARD, Duration.UntilYourNextEndStep) + .setTargetPointer(new FixedTarget(card, game)), source); return true; } - - @Override - public RepairCastFromGraveyardEffect copy() { - return new RepairCastFromGraveyardEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.isControlledBy(affectedControllerId); - } } class RepairCastFromGraveyardTriggeredAbility extends TriggeredAbilityImpl { public RepairCastFromGraveyardTriggeredAbility() { - super(Zone.GRAVEYARD, new RepairCastFromGraveyardEffect()); + super(Zone.GRAVEYARD, new RepairedCastFromGraveyardEffect()); setRuleVisible(false); } @@ -103,10 +109,8 @@ class RepairCastFromGraveyardTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (event.getTargetId().equals(getSourceId())) { Card card = game.getCard(getSourceId()); - if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD - && card.getCounters(game).getCount(CounterType.REPAIR) == 0) { - return true; - } + return card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD + && card.getCounters(game).getCount(CounterType.REPAIR) == 0; } return false; } @@ -125,11 +129,11 @@ class RepairCastFromGraveyardTriggeredAbility extends TriggeredAbilityImpl { class RepairBeginningOfUpkeepInterveningIfTriggeredAbility extends ConditionalInterveningIfTriggeredAbility { public RepairBeginningOfUpkeepInterveningIfTriggeredAbility() { - super(new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, new RemoveCounterSourceEffect(CounterType.REPAIR.createInstance()), TargetController.YOU, false), + super(new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, + new RemoveCounterSourceEffect(CounterType.REPAIR.createInstance()),TargetController.YOU, false), new SourceHasCounterCondition(CounterType.REPAIR), "At the beginning of your upkeep, remove a repair counter from {this}"); this.setRuleVisible(false); - } public RepairBeginningOfUpkeepInterveningIfTriggeredAbility(final RepairBeginningOfUpkeepInterveningIfTriggeredAbility effect) { diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index d7a33bd3fd..b5ca37b937 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -58,6 +58,7 @@ public enum SubType { ALLY("Ally", SubTypeSet.CreatureType), ANGEL("Angel", SubTypeSet.CreatureType), ANTELOPE("Antelope", SubTypeSet.CreatureType), + ANZELLAN("Anzellan", SubTypeSet.CreatureType, true), // Star Wars AQUALISH("Aqualish", SubTypeSet.CreatureType, true), // Star Wars APE("Ape", SubTypeSet.CreatureType), ARCONA("Arcona", SubTypeSet.CreatureType, true), @@ -465,6 +466,7 @@ public enum SubType { OBI_WAN("Obi-Wan", SubTypeSet.PlaneswalkerType, true), // Star Wars OKO("Oko", SubTypeSet.PlaneswalkerType), RAL("Ral", SubTypeSet.PlaneswalkerType), + REY("Rey", SubTypeSet.PlaneswalkerType, true), // Star Wars, ROWAN("Rowan", SubTypeSet.PlaneswalkerType), SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType), SAMUT("Samut", SubTypeSet.PlaneswalkerType), diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 8dbbac5b15..34e6420f11 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -450,6 +450,12 @@ public final class StaticFilters { FILTER_CONTROLLED_PERMANENT_LANDS.setLockedFilter(true); } + public static final FilterPermanent FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER = new FilterControlledCreatureOrPlaneswalkerPermanent("creature or planeswalker you control"); + + static { + FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER.setLockedFilter(true); + } + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_PLANESWALKER = new FilterControlledPlaneswalkerPermanent("planeswalker you control"); static { @@ -470,6 +476,12 @@ public final class StaticFilters { FILTER_OPPONENTS_PERMANENT_NON_LAND.setLockedFilter(true); } + public static final FilterNoncreaturePermanent FILTER_PERMANENT_NON_CREATURE = new FilterNoncreaturePermanent(); + + static { + FILTER_PERMANENT_NON_CREATURE.setLockedFilter(true); + } + public static final FilterCreaturePermanent FILTER_OPPONENTS_PERMANENT_CREATURE = new FilterOpponentsCreaturePermanent(); static { @@ -782,21 +794,21 @@ public final class StaticFilters { FILTER_SPELL_CREATURE.setLockedFilter(true); } - public static final FilterSpell FILTER_SPELL_NON_CREATURE = (FilterSpell) new FilterSpell("noncreature spell"); + public static final FilterSpell FILTER_SPELL_NON_CREATURE = new FilterSpell("noncreature spell"); static { FILTER_SPELL_NON_CREATURE.add(Predicates.not(CardType.CREATURE.getPredicate())); FILTER_SPELL_NON_CREATURE.setLockedFilter(true); } - public static final FilterSpell FILTER_SPELLS_NON_CREATURE = (FilterSpell) new FilterSpell("noncreature spells"); + public static final FilterSpell FILTER_SPELLS_NON_CREATURE = new FilterSpell("noncreature spells"); static { FILTER_SPELLS_NON_CREATURE.add(Predicates.not(CardType.CREATURE.getPredicate())); FILTER_SPELLS_NON_CREATURE.setLockedFilter(true); } - public static final FilterSpell FILTER_SPELL_A_NON_CREATURE = (FilterSpell) new FilterSpell("a noncreature spell"); + public static final FilterSpell FILTER_SPELL_A_NON_CREATURE = new FilterSpell("a noncreature spell"); static { FILTER_SPELL_A_NON_CREATURE.add(Predicates.not(CardType.CREATURE.getPredicate())); diff --git a/Mage/src/main/java/mage/filter/common/FilterControlledCreatureOrPlaneswalkerPermanent.java b/Mage/src/main/java/mage/filter/common/FilterControlledCreatureOrPlaneswalkerPermanent.java new file mode 100644 index 0000000000..e82d6b4491 --- /dev/null +++ b/Mage/src/main/java/mage/filter/common/FilterControlledCreatureOrPlaneswalkerPermanent.java @@ -0,0 +1,46 @@ +package mage.filter.common; + +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.predicate.Predicates; + +/** + * @author LevelX2 + */ +public class FilterControlledCreatureOrPlaneswalkerPermanent extends FilterControlledPermanent { + + public FilterControlledCreatureOrPlaneswalkerPermanent() { + this("creature or planeswalker you control"); + } + + public FilterControlledCreatureOrPlaneswalkerPermanent(SubType subType) { + this(subType, "a " + subType + " creature or a " + subType + " planeswalker"); + } + + public FilterControlledCreatureOrPlaneswalkerPermanent(SubType subType, String name) { + super(name); + this.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.PLANESWALKER.getPredicate() + )); + this.add(subType.getPredicate()); + } + + public FilterControlledCreatureOrPlaneswalkerPermanent(String name) { + super(name); + this.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.PLANESWALKER.getPredicate() + )); + } + + public FilterControlledCreatureOrPlaneswalkerPermanent(final FilterControlledCreatureOrPlaneswalkerPermanent filter) { + super(filter); + } + + @Override + public FilterControlledCreatureOrPlaneswalkerPermanent copy() { + return new FilterControlledCreatureOrPlaneswalkerPermanent(this); + } + +} diff --git a/Mage/src/main/java/mage/filter/common/FilterNoncreaturePermanent.java b/Mage/src/main/java/mage/filter/common/FilterNoncreaturePermanent.java new file mode 100644 index 0000000000..c13fae6727 --- /dev/null +++ b/Mage/src/main/java/mage/filter/common/FilterNoncreaturePermanent.java @@ -0,0 +1,33 @@ + + +package mage.filter.common; + +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; + + +/** + * @author Merlingilb + */ +public class FilterNoncreaturePermanent extends FilterPermanent { + + public FilterNoncreaturePermanent() { + this("noncreature permanent"); + } + + public FilterNoncreaturePermanent(String name) { + super(name); + this.add(Predicates.not(CardType.CREATURE.getPredicate())); + } + + public FilterNoncreaturePermanent(final FilterNoncreaturePermanent filter) { + super(filter); + } + + @Override + public FilterNoncreaturePermanent copy() { + return new FilterNoncreaturePermanent(this); + } + +}